Upgrade to Pro — share decks privately, control downloads, hide ads and more …

「え?!それ今ではCSSだけでできるの!?」驚きの進化を遂げたモダンCSS

 「え?!それ今ではCSSだけでできるの!?」驚きの進化を遂げたモダンCSS

このスライドはSlidevで作られており、以下のレポジトリで公開しています
https://github.com/riya-amemiya/amemiya_riya_slide_data/tree/main/frontend_conf_hokkaido_2025

Avatar for Riya Amemiya

Riya Amemiya

August 14, 2025
Tweet

More Decks by Riya Amemiya

Other Decks in Technology

Transcript

  1. 従来の解決方法:JavaScript ResizeObserver で親要素のサイズを監視して クラスを付け替える… でもこれって: パフォーマンスへの影響 複雑なイベント管理 CSS とJS の依存関係

    もっとシンプルにできないの? const resizeObserver = new ResizeObserver(entries => { entries.forEach(entry => { const width = entry.contentRect.width; entry.target.classList.toggle('small', width < 400); }); });
  2. 今はCSS だけで解決 :has() セレクタ:子要素の状態で親を選択 入力が無効になった瞬間に自動的に反映! JavaScript のイベント管理が不要に /* 無効な入力を含むフォームグループ */

    .form-group:has(input:invalid) { border-left: 3px solid red; background: #ffebee; } /* チェックされたチェックボックスを含むラベル */ label:has(input:checked) { font-weight: bold; color: blue; }
  3. 今はHTML とCSS だけで解決 Popover API :ネイティブなポップオーバー機能 <button popovertarget="menu"> 開く</button> <div

    id="menu" popover> <h3> メニュー</h3> <ul> <li> 項目1</li> <li> 項目2</li> </ul> </div>
  4. CSS あるある:詳細度の戦い 外部ライブラリのスタイルを上書きしたい時… !important 地獄の始まり… /* ライブラリ */ .btn-primary {

    background: blue; } /* 上書きしたい... */ .my-component .btn-primary { } /* 詳細度を上げる */ body .my-component .btn-primary { } /* もっと上げる */ .btn-primary { background: red !important; } /* 最終手段 */
  5. 今はCSS だけで解決 @layer :優先順位を明示的に制御 レイヤーの順番で優先度が決まる 詳細度の計算から解放される! /* レイヤーの定義(左から右に優先度が上がる) */ @layer

    library, components, utilities; @layer library { .btn { background: blue; } } @layer components { .btn { background: red; } /* 詳細度が低くても勝つ! */ }
  6. 今はCSS だけで解決 @scope :スタイルの適用範囲を限定 シンプルなクラス名でOK 範囲が明確で安心! /* .article 内だけに適用 */

    @scope (.article) { h2 { font-size: 2rem; } p { line-height: 1.8; } } /* .sidebar 内は完全に独立 */ @scope (.sidebar) { h2 { font-size: 1.2rem; } /* .article のh2 と競合しない! */ }
  7. @scope のインラインスタイル構文 HTML 内にインラインで@scope を書くことで、そのHTML 要素のみにスタイルを適用できます <section class="article-body"> <style> @scope

    { /* ここに書いたスタイルは、自動的にこの<style> タグの親要素 (この場合はsection.article-body )だけに適用されます */ img { border: 5px solid black; background-color: goldenrod; } } </style> <!-- セクションの内容 --> </section>
  8. 今はCSS だけで解決 animation-timeline: scroll() たったこれだけで、スクロールに連動したアニメーションが実現 /* スクロール進捗バー */ .progress-bar {

    animation: grow auto linear; animation-timeline: scroll(root); /* ページ全体のスクロール */ } @keyframes grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
  9. 今はCSS だけで解決 @starting-style :初期状態を定義 表示時に自動的にフェードイン! dialog { opacity: 1; transition:

    opacity 0.3s; } /* 表示開始時の初期状態 */ @starting-style { dialog[open] { opacity: 0; } }
  10. 今はCSS だけで解決 light-dark() :自動色切り替え OS の設定に自動追従! :root { color-scheme: light

    dark; } /* light-dark( ライトモード, ダークモード) */ body { background: light-dark(white, #1a1a1a); color: light-dark(black, #e5e5e5); }
  11. まとめ 最後に今回紹介した機能をまとめます レイアウト・レスポンシブ Container Queries - 親要素ベースのレスポンシブ :has() - 子要素の状態で親を選択

    UI ・インタラクション Popover API - ネイティブなポップオーバー Scroll-driven Animations - スクロール連動アニメーション @starting-style - display:none からのアニメーション
  12. スタイル管理 @layer - 詳細度の制御 @scope - スタイルの適用範囲 CSS Nesting -

    ネイティブなネスト記法 その他の便利機能 text-wrap: balance - 自動改行調整 light-dark() - 自動テーマ切り替え field-sizing - フォームの自動リサイズ この他にも様々な機能があり、CSS は進化し続けています。 ぜひ気になったら調べてみてください。
  13. ご清聴ありがとうございました 本日のスライドは下記のリポジトリで公開しています。 内容の修正・改善など、お気軽にPull Request をお送りください。 9/21 の東京、11/30 の関西のフロントエンドカンファレンスでも登壇するので、そこでもお会いしましょう! https://github.com/riya-amemiya/amemiya_riya_slide_data/tree/main/frontend_conf_hokkaido_2025 X

    やGitHub など: https://riya-amemiya-links.tokidux.com/ このスライドは CC BY-SA 4.0 でライセンスされています。 より自由な翻訳を可能にするため、翻訳は例外的に CC BY 4.0 での配布が許可されています。 Required Attribution: Riya Amemiya (https://github.com/riya-amemiya)