CSS Reference
より効率的な CSS の記述
ブラウザの CSS サポートが広がったことで可能になった効率的な CSS の記述について簡単に解説します。
CSS だけでできる範囲の広がり
CSS の基礎知識で開設したように、CSS は「モジュール」という概念に基づいてその仕様の拡張が行われており、ブラウザのリリースサイクルが高速化したことで、新たな CSS 機能の実装についても積極的、かつ短期間で行われるようになりました。
実際のウェブサイト制作においては、動作検証対象となるブラウザ間での互換性、つまり、新たな CSS 機能の実装について各ブラウザ間で足並みが揃うことが、その機能を広く使用するひとつの条件になりますが、このブラウザ実装の部分で唯一足並みが揃わず、長年足かせとなっていた Internet Explorer 11 (IE11)に関して、開発元のマイクロソフト社は、2022 年 6 月 15 日をもってコンシューマー向けバージョンのサポートを終了すると発表したことで、状況は大きく好転しています。
その結果、ひと昔前は一部ブラウザのためだけに所謂「Hack(ハック)」的な記述をしたり、Polyfill(ポリフィル)と呼ばれる JavaScript コードを追加したり、あるいは CSS のみでの実装をあきらめ、JavaScript を使用して実装するといったことを行ってきましたが、このようなテクニックの利用も徐々に不要になることが想定されます。
スムーズスクロール
ページ内リンクによってウェブページ内の特定の箇所に移動する際、スルスルとスムーズにスクロールして移動するような実装は、旧来において JavaScript の出番でした。しかし、現在では下記のように
scroll-behavior
プロパティの指定を 1 行書くだけで実現可能です。
html {
scroll-behavior: smooth;
}
ヘッダの高さ分ずらしてスクロール
例えばウェブサイトの共通ヘッダがスクロールに対して画面上部に固定されるような実装において、ページ内リンクによってウェブページ内の特定の箇所に移動する場合、そのままだと固定されたヘッダがリンク先となる箇所に重なってしまうため、ヘッダの高さ分をずらして(オフセットさせて)スクロールさせるということを、スムーズスクロール同様、JavaScript を用いて実装していました。
しかし、これも現在では CSS の記述のみで解決できます。例えばヘッダ部分の高さが 80px
で、その分ページ内リンクをオフセットさせたいのであれば、下記のように指定するだけで実装できます。
:target {
scroll-margin-top: 80px;
}
ヘッダの高さを CSS カスタムプロパティで定義しておけば、変更も容易になるでしょう。
:root {
--header-height: 80px;
}
.header {
height: var(--header-height);
}
:target {
scroll-margin-top: var(--header-height);
}
要素内における中央揃え
例えば下記のような構造の HTML があった場合、子要素となる div 要素を親要素内で上下中央に配置したい場合を考えてみましょう。
<div class="parent">
<div class="child"></div>
</div>
.parent {
width: 600px;
height: 600px;
border: 1px solid red;
}
.child {
width: 200px;
height: 200px;
border: 1px solid green;
}
ひと昔前であれば、position
プロパティを使用して、下記のように記述するテクニックがよく用いられました。これは絶対配置された要素と margin
プロパティの仕様に基づいた記述方法です (参考記事)。
/* 前述したサイズなどの指定は省略しています */
.parent {
position: relative;
}
.child {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
}
しかし、現在ではもっと簡単な方法で同じ事が実現できます。例えば CSS フレックスボックスを利用した記述であれば、下記のように親要素に対してスタイルを記述するだけで同じ効果が得られます。
/* 前述したサイズなどの指定は省略しています */
.parent {
display: flex;
justify-content: center;
align-items: center;
}
CSS グリッドを使用しても同様の事ができますので、用途に応じて使い分けるとよいでしょう。
/* 前述したサイズなどの指定は省略しています */
.parent {
display: grid;
place-items: center;
}
セレクタの簡略化
複数のセレクタを 1 つの宣言ブロックに対して使用する場合、カンマ(,)で記述することができますが、場合によっては冗長になる場合もあるでしょう。例えば下記のように、複数の場所にある a 要素にスタイルを適用したい場合、旧来であればそれらセレクタをカンマ区切りで羅列していくことが一般的でした。
div.sample a:hover,
section a:hover,
article a:hover,
aside a:hover {
color: red;
}
しかし、例えば :is()
疑似クラスを使用することでよりシンプルに記述するようなことも可能です。
:is(div.sample, section, article, aside) a:hover {
color: red;
}
これは、「section、article、adide、nav 要素のいずれかの子要素となる section、article、adide、nav 要素の子要素として存在する h1 要素」のようにより複雑な条件で要素をマッチさせたい場合などは非常に便利です。
section section h1,
section article h1,
section aside h1,
section nav h1,
article section h1,
article article h1,
article aside h1,
article nav h1,
aside section h1,
aside article h1,
aside aside h1,
aside nav h1,
nav section h1,
nav article h1,
nav aside h1,
nav nav h1 {
font-size: 1.5rem;
}
上記のように長々と各組み合わせを羅列していかないといけないのは苦痛ですしメンテナンス性も低下しますが、下記のように記述すれば簡素化され、ソースコードの見通しもよくなります。
:is(section, article, aside, nav) :is(section, article, aside, nav) h1 {
font-size: 1.5rem;
}
補足解説
用語解説など、補足記事を下記にまとめています。