1 月末にリニューアルした本サイトについて、今回は CSS を取り上げます。
本サイトでの CSS 設計や、実用的だと感じた CSS 指定、そして今後使用していきたい CSS について書いていきます。

CSS 設計
見出し「CSS 設計」これまでのプロジェクトであれば、Sass をベースとして、出力した CSS に対して Autoprefixer をかけていたのですが、今回はこれらは使用せずに純粋に CSS だけで実装しました。
理由としては、フレームワークとして使用している Astro でコンポーネント化できているのと、ブラウザのサポート状況(相互運用性の向上)から -webkit-
のようなプレフィックスを付ける機会も減ってきているためです。
今のところ Sass を使用しないことで不便に感じるのは、メディアクエリには CSS 変数を指定できないので、毎回値を記入しなければならないことぐらいです。
(Sass を使用する場合には @mixin
で一元管理します)
:root {
--breakpoint: 768px;
}
/* ❌ メディアクエリには CSS 変数を指定できない */
@media (min-width: var(--breakpoint)) {
/* ... */
}
Custom Media Queries
見出し「Custom Media Queries」将来的に @custom-media
が使用できるようになれば、メディアクエリに CSS 変数を指定できない問題は解消します。
@custom-media --breakpoint (width >= 768px);
@media (--breakpoint) {
/* ... */
}
現状は、PostCSS のプラグインによって同様の機能を試すことができます。
グローバルスタイル
見出し「グローバルスタイル」Astro 側ではサイト全体に適用したい CSS を src/styles
以下に格納し、ベースレイアウトに import
で読み込み、それ以外はコンポーネントごとに個別に指定しています。
src/
└── styles/
├── fonts.css // `@font-face` (独自フォント指定)
├── variables.css // CSS 変数(カスタムプロパティ)
├── reset.css // リセット
└── global.css // それ以外のグローバルな指定
---
import '@styles/fonts.css';
import '@styles/variables.css';
import '@styles/reset.css';
import '@styles/global.css';
---
CSS スコープ
見出し「CSS スコープ」「Astro 編」でも書きましたが、コンポーネントで記述した CSS のスコープは擬似的に閉じられるので、BEM のような命名規則を用いた、CSS セレクタの管理からは解放されます。
ただ、ブログ記事は Markdown 記法を使用しているため、出力されるコードは <h2>
や <p>
など、class
属性の付かない HTML 要素です。
Astro でこれらの要素にスタイルを適用するには、<style is:global>
でスコープを無効にするか、部分的に :global()
セレクタを使用することになりますが、このとき、他の要素に影響しないように注意しなければなりません。
<!-- `<style>` 全体でスコープを無効にする例 -->
<style is:global>
.markdown h2 {
margin-bottom: 24px;
}
</style>
<!-- 部分的にスコープを無効にする例 -->
<style>
.markdown :global(h2) {
margin-bottom: 24px;
}
</style>
もしくは、MDX を使用すれば、カスタムコンポーネントを HTML 要素に割り当てることができるので、コンポーネントでのスコープを徹底したい場合には、この方法を採用するとよいでしょう。
実用的な CSS 指定
見出し「実用的な CSS 指定」リニューアル作業をとおして実用的だと感じた、以下の 5 つの CSS 指定について取り上げます。
fit-content
inset
revert
currentColor
scroll-behavior
なお、CSS 変数(カスタムプロパティ)や CSS Grid Layout についても積極的に使用しており、十分にその恩恵を受けていますが、この記事では扱いきれないので割愛します。
fit-content
見出し「fit-content」width: fit-content
と指定することで、コンテンツ幅を横幅としてレイアウトしてくれます。
例えば display: block
を指定した要素は、通常は幅いっぱいまで広がりますが、width: fit-content
の指定ではコンテンツ幅にとどまるので、背景スタイルやリンク範囲といった領域の制御が容易になります。
また、margin: auto
を使用した左右のセンタリングでは、従来は 600px
のように値を明示する必要がありましたが、fit-content
を使用することで、コンテンツ幅のままセンタリングすることができます。
.elem {
margin-right: auto;
margin-left: auto;
width: fit-content;
display: block;
background-color: lightblue;
}
inset
見出し「inset」inset
は top
right
bottom
left
を一括指定できます。
特に、擬似要素を position: absolute
で配置する際によく使います。
.elem::after {
content: '';
position: absolute;
inset: 0;
/* `top: 0; right: 0; bottom: 0; left: 0;` を指定したのと同じ効果 */
}
revert
見出し「revert」revert
はプロパティの値を、親から継承された値や、User-Agent のスタイルシートまでロールバックするキーワードです。
メディアクエリを使ってモバイル用とデスクトップ用の指定を切り替えるときに、前の指定を取り消したいときがありますが、display: block
や margin: 0
のような明示的に値を指定するのではなく、revert
を使用することで、自然なカスケーティングを保つことができます。
例えば以下は、ビューポート幅が狭いときにのみ表示するユーティリティクラスの例ですが、display: none
で非表示にしておいて、ビューポート幅 767px
以下の場合に、display: revert
で本来持っていた値にロールバックさせています。
.is-narrow {
display: none;
}
@media (max-width: 767px) {
.is-narrow {
display: revert;
}
}
このとき、通常は div
要素であれば display: block
になり、span
要素であれば display: inline
になります。
currentColor
見出し「currentColor」以前より広くサポートされていますが、currentColor
キーワードを使用することで、color
プロパティで指定した値を適用できます。
特に SVG の単色のアイコンのカラーを指定するときや、ホバーやダークモードでそのカラーを変更するときに重宝します。
---
// Astro コンポーネントの例
---
<button type="button" class="btn">
ボタン
<svg width="27" height="27" viewbox="0 0 27 27" class="btn-icon">
<path d="M20.035 13.5 13.5 19.802l-1.307-1.26 4.37-4.214H6.965v-1.782h9.466l-4.238-4.087 1.307-1.26 6.535 6.301Z"/>
</svg>
</button>
<style>
.btn {
/* 親要素にカラーを指定 */
color: #cfdddd;
}
.btn-icon {
/* このとき SVG の `fill` が `#cfdddd` になる */
fill: currentColor;
}
.btn:hover {
background-color: #cfdddd;
/* ホバーで変更したカラーは `currentColor` にも反映される */
color: #042020;
}
</style>
scroll-behavior
見出し「scroll-behavior」scroll-behavior: smooth
を指定することで、簡単にスムーススクロールが実現できます。
あわせて、スクロール先の要素に scroll-margin-top
を指定することで、アンカーリンクで遷移したときのスクロール位置の余白を調整できます。
html {
scroll-behavior: smooth;
}
:where(h2, h3, h4) {
scroll-margin-top: 24px;
}
スクロール時の細かい速度調整はできませんが、CSS のみでアクセシブルなスムーススクロールが実装できるのは喜ばしい限りです。
今後使用していきたい CSS
見出し「今後使用していきたい CSS」ここ最近の CSS の進化は目覚ましく、フォローするだけでも大変ですが、その反面、新しい機能や表現を使えるのも楽しみでもあります。
今後、本サイトを実験場として以下で紹介されている CSS も試していきたいです。
- State of CSS 2022 | web.dev(外部リンクを開く)
- @layer | MDN(外部リンクを開く)
- :has() | MDN(外部リンクを開く)
- Subgrid | MDN(外部リンクを開く)
- CSS Container Queries | MDN(外部リンクを開く)
- CSS Color Spaces and Relative Color Syntax | 12 Days of Web(外部リンクを開く)
JS との併用になりますが、画面遷移のアニメーションを制御する View Transitions API も気になるところです。
(まだ Google Chrome の試験運用版の段階なので、実用化は先になりそうですが Chrome 111 でサポートされました)