CSSで1番最後の要素以外にスタイルを適用したい時の方法について。
margin, padding, colorなど使い所は様々。要素の数が一定でない場合も使える方法になる。
考え方としては、全体にスタイルを適用しておいて、1番最後だけlast-of-typeやlast-childでデフォルトのスタイルを適用する。
ただし、ast-of-typeとlast-childは特性が大きく異なるので注意が必要。
:last-of-type|指定した要素の1番最後のスタイルを指定
複数の異なるタグがある中で、指定したタグの最後のみ変更する場合は、 :last-of-typeを使う。
例えば、以下のように、pタグとdivタグがあり、1番最後のpタグのみ変更を解除する場合は以下のようになる。
<div>
<p class="text">pタグ1</p>
<p class="text">pタグ2</p>
<p class="text">pタグ3</p>
<p class="text">pタグ4</p>
<div>divタグ1</div>
<div>divタグ2</div>
</div>
body{
color: blue;
}
p:last-of-type{
color :initial;
}
last-childが効かない!? last-childとlast-of-typeの違い
last-childを使っていると、「last-childが効かない!」「思った通りにスタイルが適用されない」「css動いてないの?」という状況が発生するが、これは、last-childの名前の紛らわしさが原因であることがほとんど。
last-childは「もし~なら」という条件付きでスタイルを適用するプロパティになる。
プロパティ | 内容 |
last-of-type | 指定したセレクタの中の1番最後の要素 |
last-child | もし1番最後に指定したセレクタがあるなら |
翻訳としては、last-of-type が タイプの中の1番最後、last-childが1番最後の子要素。となっており、last-childには同じタイプであるといった制限がかかっていない。(last-if-childとかにしてくれれば混乱しないのに、、)
last-child の機能を見るには実例で確認するのがわかりやすいです。
:last-child | もし1番最後に指定した要素があれば
似たようなプロパティで last-child があるが、これは last-of-type とは異なり、指定した要素が1番最後にある場合はスタイルを適用するという機能になる。
つまり、if文のような機能をもつプロパティといえる。
例えば、先程のように、pタグとdivタグがあり、pタグに last-child でカラーをデフォルトに戻す指定をした場合、pタグの階層の1番最後には divタグ2 が来てしまい、pタグがないので何も変化しないという仕様になる。
<div>
<p class="text">pタグ1</p>
<p class="text">pタグ2</p>
<p class="text">pタグ3</p>
<p class="text">pタグ4</p>
<div>divタグ1</div>
<div>divタグ2</div>
</div>
body{
color: blue;
}
p:last-child{
color :initial;
}
このように、一番最後にくるpタグは存在しないため、指定したスタイルは適用されない。
pタグが1番後ろに来る場合
先程のhtmlコードでdivタグを上に移動し、1番最後にpタグが来るようにした場合、「もし1番最後に~があれば」の条件にマッチするので、1番最後のpタグの色が変化する。
<div>
<div>divタグ1</div>
<div>divタグ2</div>
<p class="text">pタグ1</p>
<p class="text">pタグ2</p>
<p class="text">pタグ3</p>
<p class="text">pタグ4</p>
</div>
body{
color: blue;
}
p:last-child{
color :initial;
}
もちろん、divタグが間に挟まっていたとしても、1番最後に指定したセレクタがあるなら、スタイルが適用される。
▼divタグをpタグの間に挿入した場合
指定した要素が1つしかない場合
もし指定した要素が1つしかない場合に、「last-of-type」「last-child」で指定したスタイルが適用されるのか?というと、答えはYESです。
一つしかない = 1番最後
とみなされます。注意点としては、1番最初の要素としてもみなされるため、first-of-typeやfirst-childも適用されます。
同じ要素に対して、last~やfirst~がある場合、下に記述したスタイルが適用されます。
<div>
<p>pタグ</p>
</div>
body{
color: blue;
}
p:last-child{
color :initial;
}
bodyにかかっている青色のスタイルが、p:last-child で打ち消されていることがわかります。
これは、p:last-of-type としても同じになります。
body{
color: blue;
}
p:last-of-type{
color :initial;
}
要素が一つしかない場合は除外のスタイルを適用しない
たまに出くわす状況が、1番最後の要素のスタイルは除外したいけど、要素が1つしかない場合は除外を適用したくないという場合です。
この状況は、 only-of-type というプロパティを使えば実現できます。
only-of-type
兄弟要素が存在しない場合にスタイルを適用する。
記述としては、last-of-type の下に、only-of-typeを記述します。
<div>
<p class="text">pタグ1</p>
<p class="text">pタグ2</p>
<p class="text">pタグ3</p>
<div>divタグ1</div>
<div>divタグ2</div>
</div>
<hr>
<div class="div-wrapper">
<p class="text">pタグ</p>
</div>
<hr>
<div class="div-wrapper">
<div>divタグ1</div>
<p class="text">pタグ</p>
<div>divタグ2</div>
</div>
body{
color: blue;
}
p:last-of-type{
color : initial;
}
p:only-of-type{
color: blue;
}
こうすると、指定したセレクタが同じ階層に複数ある場合は1番最後の要素に指定したスタイルを適用しますが、一つしかない場合は適用しません。
ブロックが3つあり
- 1番上には、pタグが3つあるので、last-of-typeが適用される。
- 2番目は、pタグが1つしかないので、only-of-typeが適用される。
- 3番目も、pタグが1つしかないので、only-of-typeが適用される。
となります。
まとめ
last-childとlast-of-typeは名前も似ているのでわかりにくいですよね。でも、仕様の違いを理解しさえすれば恐いものなしです。
last-of-typeはtypeがあるので絞り込みされる、last-childは「もし~なら」というif条件と覚えておくとわかりやすいです。
first-of-typeとfirst-childも同じ考え方が使えます。
ちなにみ、last-type-ofとタイプミスしてしまう場合は、「~のタイプ」=「of-type」でタイプを絞り込みしていると覚えておくと、ミスが減るかもしれません。