07. CSSセレクタ

レッスン6では、idclassを使って特定の要素にスタイルを適用しました。このレッスンでは、より詳細な要素の指定方法を学びます。

モンスターを3体に増やす

まず、モンスターを3体に増やしましょう。それぞれの画像にclassを付けて、種類を区別できるようにします。

<!-- battle.html highlight:17-19 preview:{min-width:1220px;} -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>バトル</title>
    <link rel="stylesheet" href="css/battle.css">
</head>
<body>
    <table id="status">
        <tr class="name-row">
            <th>ゆうしゃ</th><th>せんし</th><th>そうりょ</th><th>まほうつかい</th>
        </tr>
        <tr><td>HP 153</td><td>HP 198</td><td>HP 101</td><td>HP 77</td></tr>
        <tr><td>MP 25</td><td>MP 0</td><td>MP 35</td><td>MP 58</td></tr>
    </table>
    <div id="monster">
        <img class="dark-knight" src="img/dark-knight.png">
        <img class="dark-lord" src="img/dark-lord.png">
        <img class="demon-priest" src="img/demon-priest.png">
    </div>
    <div id="message">
        まおうがあらわれた。
    </div>
</body>
</html>
/* battle.css hidden */
body {
    background-color: rgb(34, 34, 34);
    color: white;
    font-family: sans-serif;
}
table {
    border: solid 2px white;
    border-collapse: collapse;
    margin: 10px auto 0 auto;
    width: 640px;
}
.name-row {
    border-bottom: solid 1px white;
}
td {
    text-align: center;
}
#monster {
    text-align: center;
    margin-top: 40px;
}
img {
    width: 400px;
}
#message {
    border: solid 2px white;
    border-radius: 4px;
    padding: 10px;
    width: 720px;
    margin: 30px auto;
}

ブラウザで確認すると、3体のモンスターが横に並んで表示されます。これは、<img>要素はインライン要素なので、横に並ぶ性質を持っているためです。

現状では、「まおう」以外の2体の表示が大きすぎます。「まおう」を大きく、他の2体を小さく表示したいところです。

画像ごとにサイズを指定する

レッスン6ではimgセレクタで全ての画像に同じ幅を指定していました。

img {
    width: 400px;
}

これを削除して、モンスターごとに個別のサイズを指定しましょう。.dark-lord.dark-knightなどにサイズを指定することもできますが、それらのclassは他のタグにも使用することがあるかもしれません(たとえば、「まおう」のHPを表示するときなど)。#monster .dark-lordのように書くと、「id="monster"の中にあるclass="dark-lord"の要素」を指定できます。

<!-- battle.html hidden -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>バトル</title>
    <link rel="stylesheet" href="css/battle.css">
</head>
<body>
    <table id="status">
        <tr class="name-row">
            <th>ゆうしゃ</th><th>せんし</th><th>そうりょ</th><th>まほうつかい</th>
        </tr>
        <tr><td>HP 153</td><td>HP 198</td><td>HP 101</td><td>HP 77</td></tr>
        <tr><td>MP 25</td><td>MP 0</td><td>MP 35</td><td>MP 58</td></tr>
    </table>
    <div id="monster">
        <img class="dark-knight" src="img/dark-knight.png">
        <img class="dark-lord" src="img/dark-lord.png">
        <img class="demon-priest" src="img/demon-priest.png">
    </div>
    <div id="message">
        まおうがあらわれた。
    </div>
</body>
</html>
/* battle.css selection:18-37 highlight:22-30 */
body {
    background-color: rgb(34, 34, 34);
    color: white;
    font-family: sans-serif;
}
table {
    border: solid 2px white;
    border-collapse: collapse;
    margin: 10px auto 0 auto;
    width: 640px;
}
.name-row {
    border-bottom: solid 1px white;
}
td {
    text-align: center;
}
#monster {
    text-align: center;
    margin-top: 40px;
}
#monster .dark-lord {
    width: 400px;
}
#monster .dark-knight {
    width: 150px;
}
#monster .demon-priest {
    width: 150px;
}
#message {
    border: solid 2px white;
    border-radius: 4px;
    padding: 10px;
    width: 720px;
    margin: 30px auto;
}

これで、「まおう」が大きく、「あんこくきし」と「デモンプリースト」が小さく表示されます。

子孫セレクタ

次のように<div>要素の中に<img>要素が入っている場合、外側にある<div>親要素、内側にある<img>子要素と呼びます。

<div id="monster">
    <img class="dark-knight" src="img/dark-knight.png">
    <img class="dark-lord" src="img/dark-lord.png">
    <img class="demon-priest" src="img/demon-priest.png">
</div>

子要素がさらに子要素を持っている場合は孫要素と呼びます。孫要素がさらに子要素を持っている場合もあります。それらも含めて子孫要素と呼びます。

#monster .dark-lordのように、スペースで区切って複数のセレクタを書くと、「親要素の中にある子孫要素」を指定できます。これを子孫セレクタと呼びます。

#monster .dark-lord {
    /* id="monster"の中にあるclass="dark-lord"の要素 */
}

子孫セレクタを使うと、ページの特定の場所にある要素だけにスタイルを適用できます。

ステータス表に限定してスタイルを適用する

ステータス表について、今は次のようにスタイルを適用しています。

/* battle.css selection:6-11 */
body {
    background-color: rgb(34, 34, 34);
    color: white;
    font-family: sans-serif;
}
table {
    border: solid 2px white;
    border-collapse: collapse;
    margin: 10px auto 0 auto;
    width: 640px;
}
.name-row {
    border-bottom: solid 1px white;
}
td {
    text-align: center;
}
#monster {
    text-align: center;
    margin-top: 40px;
}
#monster .dark-lord {
    width: 400px;
}
#monster .dark-knight {
    width: 150px;
}
#monster .demon-priest {
    width: 150px;
}
#message {
    border: solid 2px white;
    border-radius: 4px;
    padding: 10px;
    width: 720px;
    margin: 30px auto;
}

しかし、tableにスタイルを適用していると、同じHTML中のすべての表にこのスタイルが適用されてしまいます。table#statusと書くことで、id="status"が指定されたtableに限定してスタイルを指定することができます。

/* battle.css selection:6-11 highlight:6 */
body {
    background-color: rgb(34, 34, 34);
    color: white;
    font-family: sans-serif;
}
table#status {
    border: solid 2px white;
    border-collapse: collapse;
    margin: 10px auto 0 auto;
    width: 640px;
}
.name-row {
    border-bottom: solid 1px white;
}
td {
    text-align: center;
}
#monster {
    text-align: center;
    margin-top: 40px;
}
#monster .dark-lord {
    width: 400px;
}
#monster .dark-knight {
    width: 150px;
}
#monster .demon-priest {
    width: 150px;
}
#message {
    border: solid 2px white;
    border-radius: 4px;
    padding: 10px;
    width: 720px;
    margin: 30px auto;
}

これと子孫セレクタを組み合わせると、<table id="status">の中の<td>だけを指定することもできます。

/* battle.css selection:15-17 highlight:15 */
body {
    background-color: rgb(34, 34, 34);
    color: white;
    font-family: sans-serif;
}
table#status {
    border: solid 2px white;
    border-collapse: collapse;
    margin: 10px auto 0 auto;
    width: 640px;
}
.name-row {
    border-bottom: solid 1px white;
}
table#status td {
    text-align: center;
}
#monster {
    text-align: center;
    margin-top: 40px;
}
#monster .dark-lord {
    width: 400px;
}
#monster .dark-knight {
    width: 150px;
}
#monster .demon-priest {
    width: 150px;
}
#message {
    border: solid 2px white;
    border-radius: 4px;
    padding: 10px;
    width: 720px;
    margin: 30px auto;
}

さらに、<table id="status">の中の<tr class="name-row">を指定するには次のように書けます。

/* battle.css selection:12-14 highlight:12 */
body {
    background-color: rgb(34, 34, 34);
    color: white;
    font-family: sans-serif;
}
table#status {
    border: solid 2px white;
    border-collapse: collapse;
    margin: 10px auto 0 auto;
    width: 640px;
}
table#status tr.name-row {
    border-bottom: solid 1px white;
}
table#status td {
    text-align: center;
}
#monster {
    text-align: center;
    margin-top: 40px;
}
#monster .dark-lord {
    width: 400px;
}
#monster .dark-knight {
    width: 150px;
}
#monster .demon-priest {
    width: 150px;
}
#message {
    border: solid 2px white;
    border-radius: 4px;
    padding: 10px;
    width: 720px;
    margin: 30px auto;
}

N番目の要素を指定する

class="name-row"を使わなくても、CSSセレクタを使えば1行目の<tr>だけを指定することができます。

nth-child

:nth-child(n)を使うと、「n番目の要素」を指定できます。これを使って、1行目の<tr>を指定しましょう。

class="name-row"は不要になるので削除します。

<!-- battle.html selection:9-15 highlight:10 -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>バトル</title>
    <link rel="stylesheet" href="css/battle.css">
</head>
<body>
    <table id="status">
        <tr>
            <th>ゆうしゃ</th><th>せんし</th><th>そうりょ</th><th>まほうつかい</th>
        </tr>
        <tr><td>HP 153</td><td>HP 198</td><td>HP 101</td><td>HP 77</td></tr>
        <tr><td>MP 25</td><td>MP 0</td><td>MP 35</td><td>MP 58</td></tr>
    </table>
    <div id="monster">
        <img class="dark-knight" src="img/dark-knight.png">
        <img class="dark-lord" src="img/dark-lord.png">
        <img class="demon-priest" src="img/demon-priest.png">
    </div>
    <div id="message">
        まおうがあらわれた。
    </div>
</body>
</html>

次に、CSSで.name-rowの代わりに:nth-child(1)を使います。

/* battle.css selection:12-14 highlight:12 */
body {
    background-color: rgb(34, 34, 34);
    color: white;
    font-family: sans-serif;
}
table#status {
    border: solid 2px white;
    border-collapse: collapse;
    margin: 10px auto 0 auto;
    width: 640px;
}
table#status tr:nth-child(1) {
    border-bottom: solid 1px white;
}
table#status td {
    text-align: center;
}
#monster {
    text-align: center;
    margin-top: 40px;
}
#monster .dark-lord {
    width: 400px;
}
#monster .dark-knight {
    width: 150px;
}
#monster .demon-priest {
    width: 150px;
}
#message {
    border: solid 2px white;
    border-radius: 4px;
    padding: 10px;
    width: 720px;
    margin: 30px auto;
}

table#status tr:nth-child(1)は「<table id="status">の中にある<tr>のうち1番目の要素」という意味です。

first-child と last-child

「1番目」を指定する場合は:first-childを使うこともできます。より意図が明確になります。

/* battle.css selection:12-14 highlight:12 */
body {
    background-color: rgb(34, 34, 34);
    color: white;
    font-family: sans-serif;
}
table#status {
    border: solid 2px white;
    border-collapse: collapse;
    margin: 10px auto 0 auto;
    width: 640px;
}
table#status tr:first-child {
    border-bottom: solid 1px white;
}
table#status td {
    text-align: center;
}
#monster {
    text-align: center;
    margin-top: 40px;
}
#monster .dark-lord {
    width: 400px;
}
#monster .dark-knight {
    width: 150px;
}
#monster .demon-priest {
    width: 150px;
}
#message {
    border: solid 2px white;
    border-radius: 4px;
    padding: 10px;
    width: 720px;
    margin: 30px auto;
}

同様に、「最後の要素」を指定するには:last-childを使います。

table#status tr:last-child {
    /* 最後のtr要素に適用 */
}

nth-childの使い方

:nth-childには数字以外にも指定できます。

指定 意味
:nth-child(1) 1番目の要素
:nth-child(3) 3番目の要素
:nth-child(odd) 奇数番目の要素(1, 3, 5, …)
:nth-child(even) 偶数番目の要素(2, 4, 6, …)
:first-child 最初の要素(nth-child(1)と同じ)
:last-child 最後の要素

試してみよう

これまでの成果

<!-- battle.html -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>バトル</title>
    <link rel="stylesheet" href="css/battle.css">
</head>
<body>
    <table id="status">
        <tr>
            <th>ゆうしゃ</th><th>せんし</th><th>そうりょ</th><th>まほうつかい</th>
        </tr>
        <tr><td>HP 153</td><td>HP 198</td><td>HP 101</td><td>HP 77</td></tr>
        <tr><td>MP 25</td><td>MP 0</td><td>MP 35</td><td>MP 58</td></tr>
    </table>
    <div id="monster">
        <img class="dark-knight" src="img/dark-knight.png">
        <img class="dark-lord" src="img/dark-lord.png">
        <img class="demon-priest" src="img/demon-priest.png">
    </div>
    <div id="message">
        まおうがあらわれた。
    </div>
</body>
</html>
/* battle.css */
body {
    background-color: rgb(34, 34, 34);
    color: white;
    font-family: sans-serif;
}
table#status {
    border: solid 2px white;
    border-collapse: collapse;
    margin: 10px auto 0 auto;
    width: 640px;
}
table#status tr:first-child {
    border-bottom: solid 1px white;
}
table#status td {
    text-align: center;
}
#monster {
    text-align: center;
    margin-top: 40px;
}
#monster .dark-lord {
    width: 400px;
}
#monster .dark-knight {
    width: 150px;
}
#monster .demon-priest {
    width: 150px;
}
#message {
    border: solid 2px white;
    border-radius: 4px;
    padding: 10px;
    width: 720px;
    margin: 30px auto;
}