「CSSはなんとなく書けるけど、もっとうまく使いたい」と感じていませんか? この記事では、Webコーダーとして6年間の実務で何度も助けられたCSS小技を厳選して10個紹介します。コピペしてすぐ使えるコードつきなので、ぜひ手元のプロジェクトで試してみてください。
- aspect-ratio / clamp() / gap / :is() / CSS変数
- scroll-behavior / object-fit / position: sticky / writing-mode / prefers-color-scheme
aspect-ratio でサイズ比率を固定する
画像や動画を16:9や4:3で表示したいとき、昔は padding-top: 56.25% というハックを使っていました。でも今は aspect-ratio 一行で完結します。特に画像の縦横比をレイアウト崩れなく保ちたいときに重宝します。
/* 16:9 の比率で固定 */
.video-wrap {
width: 100%;
aspect-ratio: 16 / 9;
overflow: hidden;
}
/* カード画像を正方形に */
.card-img {
aspect-ratio: 1 / 1;
object-fit: cover;
width: 100%;
}
aspect-ratio は現在ほぼすべてのブラウザで使えます。古い書き方(padding ハック)をしている箇所があれば、順次置き換えていくとコードがすっきりします。
clamp() でフォントサイズをレスポンシブに
レスポンシブ対応でフォントサイズを変えるとき、メディアクエリを何行も書いていませんか? clamp() を使えば「最小値・推奨値・最大値」を一行で指定できます。
h1 {
/* 最小16px、画面幅に応じて変化、最大32px */
font-size: clamp(16px, 4vw, 32px);
}
p {
font-size: clamp(14px, 2vw, 18px);
}
vw(ビューポート幅)を推奨値に使うのがポイント。画面サイズに合わせて自然にスケールします。
gap で Flexbox の余白を簡潔に
Flexboxで要素間の余白を margin で調整していたころ、「最後の要素だけ margin をなくしたい」問題に悩まされた方は多いと思います。gap ならその悩みがなくなります。
/* 縦横まとめて指定 */
.flex-wrap {
display: flex;
flex-wrap: wrap;
gap: 24px;
}
/* 縦と横で分けたいとき(行間 16px / 列間 24px) */
.flex-wrap-2 {
display: flex;
flex-wrap: wrap;
gap: 16px 24px;
}
gap はGridだけのものと思われがちですが、Flexboxでも問題なく使えます。flex-wrap: wrap で折り返したときの行間もまとめて面倒を見てくれるので、margin で調整していた頃の「最後の要素だけ打ち消す」記述が不要になります。
:is() でセレクタをまとめる
h1, h2, h3, h4 { ... } のような単純な並列なら、そのまま書けば済みます。:is() が効いてくるのは、同じ子孫セレクタを何度も繰り返すときです。
/* Before:親が増えるたびに組み合わせが倍々に増えていく */
article h2,
article h3,
section h2,
section h3 {
color: #2d7a4f;
}
/* After:親と子をそれぞれまとめられる */
:is(article, section) :is(h2, h3) {
color: #2d7a4f;
}
:is() の詳細度は、括弧の中でもっとも強いセレクタに合わせられます。:is(h1, #title) と書くと、h1 に当たる場合でもID相当の強さになってしまう点に注意してください。詳細度を上げたくない場合は、同じ書き方で詳細度が0になる :where() が使えます。
CSS変数(カスタムプロパティ)でテーマ管理
サイトのカラーやフォントサイズをCSS変数でまとめておくと、デザイン変更があったときに修正箇所が一か所で済みます。特に複数ページにわたるサイトでは必須のテクニックです。
:root {
--color-primary: #2d7a4f;
--color-text: #333;
--color-bg: #fff;
--font-size-base: 16px;
--spacing-lg: 48px;
}
a {
color: var(--color-primary);
}
.section {
padding: var(--spacing-lg) 0;
}
ダークモードの切り替えにもCSS変数が大活躍します。後述の prefers-color-scheme と組み合わせると強力です。
scroll-behavior: smooth でなめらかスクロール
ページ内リンクをクリックしたとき、ガクっと飛ぶのではなくなめらかにスクロールさせたい場合、JavaScriptなしでできます。
html {
scroll-behavior: smooth;
}
ただし、動きに酔いやすい方や、OSでアニメーションを減らす設定にしているユーザーもいます。その場合はスクロールの動きを止めてあげてください。
@media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
}
prefers-reduced-motion への対応は、アニメーションを使うとき全般に必要になります。scroll-behavior に限らず、transition や animation を書いたときも同じように無効化する経路を用意しておくと安全です。
object-fit で画像トリミングをCSSだけで
カード型レイアウトで、画像サイズがバラバラでもきれいに揃えたい場合は object-fit: cover が便利です。画像の縦横比を保ちながら、指定した枠に収めてくれます。
.card-img {
width: 100%;
height: 200px;
object-fit: cover; /* 比率を保ちながら枠を埋める */
object-position: center top; /* 基準点を指定 */
}
position: sticky で追従ヘッダー
ヘッダーやナビゲーションをスクロールに追従させたいとき、position: fixed だと「ページ上部に被る」問題が起きがちです。sticky を使うと自然に追従します。
header {
position: sticky;
top: 0; /* 画面上端からの距離 */
z-index: 100;
background: #fff;
}
sticky は親要素の高さの範囲内でのみ追従します。また、親要素のどこかに overflow: hidden(や auto)があると効かなくなります。動かないときは、まず祖先要素をさかのぼって overflow の指定を探してみてください。top の指定漏れも定番の原因です。
writing-mode で縦書きテキスト
和風デザインや雑誌レイアウトで縦書きテキストを使いたいとき、writing-mode 一発で実現できます。サイドのラベルや見出し装飾にも使えます。
.vertical-text {
writing-mode: vertical-rl; /* 右から左へ縦書き */
text-orientation: mixed;
}
/* 左から右なら */
.vertical-ltr {
writing-mode: vertical-lr;
}
@media (prefers-color-scheme) でダークモード対応
ユーザーのOS設定に合わせてダークモードを自動で切り替えることができます。CSS変数と組み合わせると最小限の記述で対応できます。
/* ライトモード(デフォルト) */
:root {
--color-bg: #ffffff;
--color-text: #333333;
}
/* ダークモード(OS設定に連動) */
@media (prefers-color-scheme: dark) {
:root {
--color-bg: #1a1a1a;
--color-text: #e8e8e8;
}
}
body {
background: var(--color-bg);
color: var(--color-text);
}
CSS変数との組み合わせが鍵。変数を切り替えるだけで、サイト全体の配色が一気に変わります。
よくある質問
これらのCSSは古いブラウザでも使えますか?
ここで紹介したものは、いずれも主要なモダンブラウザ(Chrome / Edge / Safari / Firefox)で問題なく使えます。サポート対象に古いブラウザが含まれる案件では、Can I use で個別に確認してください。心配な場合は、崩れても致命的にならない書き方(フォールバックを先に書く)にしておくと安全です。
aspect-ratioとpaddingハックはどちらを使うべきですか?
新しく書くなら aspect-ratio で問題ありません。padding-top: 56.25% のハックは、記述の意図がコードから読み取りにくく、後から比率を変えるときに計算し直す必要があります。既存コードを一斉に置き換える必要はありませんが、触る機会があれば順次移行していくのがおすすめです。
clamp()の推奨値には何を入れればいいですか?
画面幅に応じて変化させたいので、vw を使うのが基本です。clamp(16px, 4vw, 32px) であれば、画面幅の4%を基準にしつつ、16pxを下回らず32pxを超えない、という指定になります。数値は実際にブラウザ幅を変えながら調整するのが早いです。
gapはFlexboxでも使えますか?
使えます。以前はGrid専用という認識が広まっていましたが、現在は主要ブラウザすべてがFlexboxの gap に対応しています。margin で余白を作って最後の要素だけ打ち消す、という書き方はもう不要です。
まとめ
今回紹介した10のCSS小技をまとめます。
| プロパティ / テクニック | 用途 |
|---|---|
aspect-ratio |
サイズ比率の固定 |
clamp() |
レスポンシブなフォントサイズ |
gap |
Flexbox / Grid の余白管理 |
:is() |
セレクタのまとめ書き |
| CSS変数 | テーマカラーの一元管理 |
scroll-behavior |
なめらかスクロール |
object-fit |
画像トリミング |
position: sticky |
追従ヘッダー |
writing-mode |
縦書きテキスト |
prefers-color-scheme |
ダークモード対応 |
どれも今日から使えるものばかりです。1つずつ試していくうちに、コーディングのスピードと品質が確実に上がっていきます。ぜひ手元のプロジェクトで使ってみてください!
