鹿野 壮

CSSと猫が大好きです

@tonkotsuboy_com

本日の構成

  1. 2024年最新CSS実践テクニック 50分
  2. 事前質問への回答 5分

新しいCSSが日々生まれている

新しいCSSを学ぶメリットとは?

新しいCSSを学ぶメリット

  • 長いJavaScriptで実現していたものが、
    短いCSSで済む
  • 読みやすいコードになり、
    開発者体験(DX)が向上する
  • バグが減り、制作物の品質が向上する
01

2024年最新CSS実践テクニック

01

:nth-child()が便利になった

of S構文

クイズ

2番目の.item 要素「🍇ぶどう」にスタイルをあてるには?

HTML
<ul>
  <li>🍎りんご</li>
  <li class="item">🍑</li>
  <!-- ぶどうにスタイルをあてたい -->
  <li class="item">🍇ぶどう</li>
</ul>

https://codepen.io/tonkotsuboy/pen/yLWpmBm

:nth-child(2) や :nth-of-type(2) は不正解

  • .item:nth-child(2)
    • 2番目の要素かつ .item がついているもの
HTML
<ul>
  <li>🍎りんご</li>
  <!-- 桃にスタイルがあたってしまう -->
  <li class="item">🍑</li>
  <li class="item">🍇ぶどう</li>
</ul>
※ `:nth-of-type(2)` は同じタグの中で2番目の要素

もっと直感的に指定できるようになった

【モダン】 of S 構文を使う

  • :nth-child(2 of .item)
    • .item 要素のうち、2番目
<ul>
  <li>🍎りんご</li>
  <li class="item">🍑</li>
  <!-- ぶどうにスタイルがあたる -->
  <li class="item">🍇ぶどう</li>
</ul>

https://codepen.io/tonkotsuboy/pen/yLWpmBm

【実例】テーブルの偶数行に背景色(ゼブラ表示)

非表示の行には、JavaScriptで hidden 属性が付与される

Demo

https://codepen.io/tonkotsuboy/pen/YzbeERN

:nth-child(even of :not(:hidden))

HTML
<tbody>
  <tr data-type="女の子" hidden></tr>
  <tr data-type="男の子"></tr>
  <tr data-type="女の子" hidden></tr>
  <tr data-type="女の子" hidden></tr>
  <tr data-type="男の子"></tr>
CSS
tr:nth-child(even of :not([hidden])) {
  background: #efeeee;
}
表示されているtrの偶数番目に色をつける

of S構文は全ブラウザ対応済み

  • 2023年5月にFirefox 113が対応
  • 全ブラウザ対応完了

https://caniuse.com/css-nth-child-of より。
緑色が対応済みバージョン

02

inputの入力が終わったときにだけ
エラー表示をしたい

input のエラー表示

input のエラー表示

  • 必須(required)なinputに値が入力されていないとき
  • メールアドレスが正しい形式ではないとき

Demo

https://codepen.io/tonkotsuboy/pen/jOoZaQe

【従来】 input:invalid はページを開いた瞬間に判定

ページを開いた瞬間に背景が赤色になる

HTML
<input required />
CSS
input:invalid {
  background-color: red;
}

【モダン】 input:user-invalid を使う

1回目の入力が終わったら背景が赤色になる

HTML
<input required />
CSS
input:user-invalid {
  background-color: red;
}

input:user-invalid の挙動

  • 1回目の入力が終わった後に2回目の入力を試みると、
    入力途中のエラー扱いになる
  • 「フォーカスが外れたときにだけ」エラー表示ができない

2回目以降も入力が終わったときに
エラー表示したい場合がある

:not(:focus) を組み合わせる

  • :user-invalid:not(:focus)
    • 「フォーカスがあたっていない状態の不正な要素」
    • :focus フォーカスがあたっているとき
    • :not() セレクターに一致しない要素
CSS
input:user-invalid:not(:focus) {
  background-color: red;
}

:user-invalidは全ブラウザ対応済み

  • 2023年11月にEdge 119が対応
  • Safariは16.5(2023年5月)から
  • 全ブラウザ対応完了

https://caniuse.com/mdn-css_selectors_user-invalid より。
緑色が対応済みバージョン

03

子要素の状態に応じて、
親要素のスタイルを変えたい

:has()

input が不正なとき、親要素の背景の色を変える

HTML
<div class="item"> <!-- 背景を変えたい -->
  <label>氏名</label>
  <input required /> <!-- 不正になりうる -->
</div>

Demo

https://codepen.io/tonkotsuboy/pen/jOoZaQe

【従来】JavaScriptを使っていた

  • input の状態が変更されるイベントをチェック
  • .item および labelのスタイルをJavaScriptで更新

【モダン】 :has() を使う

子孫要素に input:user-invalidがある.item要素の
背景の色を変える

CSS
.item:has(input:user-invalid) {
  background: #ffe5e5;
}
.form:has(input:user-invalid:not(:focus)) が better

:has()は全ブラウザ対応済み

  • 2023年12月にFirefox 121が対応
  • Safariは15.4(2022年5月)から
  • 全ブラウザ対応完了

https://caniuse.com/css-has より。
緑色が対応済みバージョン

04

Sass ではなく、
CSS でネスト(入れ子)にする

【従来】ネストには Sass が必要だった

SCSS
.container {
  .child {
    color: red;
  }
}

【モダン】「CSS」でネストする

CSS
.container {
  .child {
    color: red;
  }
}

https://codepen.io/tonkotsuboy/pen/ExRbPgV

CSS ネストは、Sass のネストと「ほぼ」同じ

CSS
.container {
  .child1,
  .child2 {
    color: red;
  }
}
CSS
.link {
  &:hover,
  &:active {
    color: red;
  }
}

https://codepen.io/tonkotsuboy/pen/ExRbPgV

とくに @media や @container のネストが便利

CSS
.box {
  color: blue;

  @media (width <= 800px) {
    color: red;
  }
}

Demo

https://codepen.io/tonkotsuboy/pen/jOoZaQe

2023年12月から要素セレクターの前の & が不要に

Before

CSS
section {
  & h1 {
    color: red;
  }
}

After

CSS
section {
  h1 {
    color: red;
  }
}

ネストの緩和された構文の更新 https://developer.chrome.com/blog/css-nesting-relaxed-syntax-update?hl=ja

セレクター名の一部を & で表現するのは不可能

次のコードは動作しない。
筆者は歓迎だが、皆さんはどうですか?

CSS
/* 動きません */
.foo {
  &__bar {
    color: red;
  }
}
ジャンプできない・リファクタリングできない・コード検索が手間

ネストは全ブラウザ対応済み

  • 2023年12月にChrome・Edge 120が対応
  • 2023年12月にSafari 17.2が対応
  • 全ブラウザ対応完了

https://caniuse.com/css-nesting より。
緑色が対応済みバージョン
黄色は要素セレクターの前に & が必要なバージョン

05

行列を入れ子にしたい

テーブルレイアウトみたいなフォームをつくる

HTML

<main>
  <div class="item">
    <label>氏名</label>
    <input />
  </div>
  <div class="item">
    <label>会社</label>
    <input />
  </div>
  <!-- 中略 -->
  <button>送信する</button>
</main>

Demo

https://codepen.io/tonkotsuboy/pen/jOoZaQe

Flexだと見出しの幅が揃わない

CSS
.item {
  display: flex;
}

alt text

最大文字数にあわせて固定値にすれば解決できるが、文字数が変わるたびにCSSを更新する必要がある

【モダン】 行列を入れ子にする

  • 2列の親行列を作る
  • 子行列を配置する
  • 子行列は、親の列に一致させる

2列の行列を作り、子を配置

CSS
main {
  display: grid;
  grid-template-columns: 
    max-content 1fr;
}

main .item {
  display: grid;
  grid-template-columns: 
    subgrid;
  grid-column: span 2;
}

alt text

最大文字数にあわせて見出し幅が自動で変わる

Demo

https://codepen.io/tonkotsuboy/pen/jOoZaQe

Subgridの活用例

レスポンシブ対応しつつ各行の高さを統一

https://codepen.io/tonkotsuboy/pen/VwqmzeJ

12分割グリッドシステムを作る

https://codepen.io/brianhaferkamp/pen/XWXEbPp

Subgridは全ブラウザ対応済み

  • 2023年9月にChrome・Edge 117が対応
  • Safariは16.0(2022年9月)から
  • 全ブラウザ対応完了

https://caniuse.com/css-subgrid より。
緑色が対応済みバージョン

02

事前質問への回答

事前質問①

【質問】
最新CSSで最も注目しているものは?
【回答】
Subgrid、:has()、コンテナクエリがアツい。どれもこれまでのCSS開発を大きく変えてくれる、ゲームチェンジャーな新機能。

コンテナクエリ @container が全ブラウザ対応。新時代のレスポンシブ対応を完全理解する by @tonkotsuboy_com - Zenn

事前質問②

【質問】
Sassを使わなくなるのはいつ頃だと思う?
【回答】
私はもう使っていない。

事前質問③

【質問】
tailwind cssなど、何のCSSライブラリを使っている?
【回答】
CSS Modulesを使うことが多い。
今はvanilla-extractが一番気に入っている。

CSS・TypeScriptの相性が抜群。vanilla-extractが最高のCSS開発体験をくれた by @tonkotsuboy_com - Zenn

事前質問④

【質問】
新しい機能をプロダクトに導入する場合に、OSやデバイスがどれくらい対応していたら導入する?
【回答】
基本的には2バージョン以下。
Safariはバージョンアップの浸透が遅いので、3バージョン以下を対象に。 必要に応じて `@support` や ポリフィルを使う。

事前質問⑤

【質問】
どうやって新しい技術にキャッチアップしている?
【回答】
ブラウザの公式アップデート情報、ブラウザ開発者のSNS、Can I use...など。「もっと便利なやり方はないか?」と常にアンテナを張っておく。
知識の定着には、SNS・技術ブログ・登壇。

アウトプットこそ最高のインプット。鹿野壮が語る「自分が一番トクする」アウトプットの力 -レバテックLAB

03

まとめ

本日紹介したモダンCSS①

  • :nth-child()of S構文
    • .itemの2番目、といった指定が直感的にできる
  • :user-invalid:user-valid
    • ユーザー入力が終わっときの有効・無効判定
  • :has()
    • 子孫要素の状態に応じてスタイルを変更できる

本日紹介したモダンCSS②

  • CSSのネスト
    • @media の入れ子がとくに便利
  • subgrid
    • 行列の入れ子が可能
  • :not()
    • 一致しないセレクターの指定

参考資料

新しい知識を取り入れて
楽しくラクにウェブ制作をしましょう