Post on:2025年12月16日
sponsorsr
今年もCSSの進化が早かった1年でした。一昔前にはJavaScriptや複雑なCSSを使用しないとできなかったことがたった一行、もしくは数行のCSSで簡単に実装できるようになりました。
2025年、Web制作者がチェックしておきたいCSSの新機能: カスタマイズ可能な新しいコンポーネント編を紹介します。

CSS Wrapped 2025 -Google Blog
CSS Wrapped 2025
下記は各ポイントを意訳したものです。
※元サイト様のライセンスとApache 2.0に基づいて翻訳しています。基づいてというのは、貢献部分に関して同ライセンスも含みます。
これまでJavaScriptを使用しないと実装・カスタマイズできなかったコンポーネントが、CSSだけでできるようになったものがたくさんあります。
ドロップダウンは長年の課題をクリアしてスタイルを設定できるようになり、CSSだけでカルーセルを実装できるようになったり、ネイティブのアンカーポジショニング、モーダルやポップオーバーの表示・非表示など、機能的で、CSSでカスタマイズ可能な新しいコンポーネントが登場しました。
ボタンをクリックして<dialog>のモーダルを表示するには、通常はJavaScriptを使用して、その<dialog>にshowModalメソッドを呼び出すonclickハンドラが必要でした。
1 2 | <buttononclick="document.querySelector('#my-dialog').showModal();">ShowDialog</button> <dialogid="my-dialog">…</dialog> |
しかし、Chrome 135+ではJavaScriptは必要なく、ボタンにcommandforとcommandを設定するだけでモーダルを表示する操作ができるようになりました。
1 2 | <buttoncommandfor="my-dialog"command="show-modal">ShowDialog</button> <dialogid="my-dialog">…</dialog> |
commandfor属性はfor属性と同様にidを受け取り、command属性は組み込み値を受け入れるため、より移植性が高く、直感的なアプローチが可能になります。
実際の動作は、下記のデモページをご覧ください。
ダイアログとポップオーバーを表示・非表示にするデモで、非対応ブラウザはポリフィルで機能します。
See the Pen
CSS Wrapped 2025: ダイアログ 1 by coliss (@coliss)
onCodePen.
現在、ダイアログとポップオーバーに対してコマンドを送信することができますが、将来的にはさらに多くの種類の要素に対応する予定です。要素に対するコマンドは、対応するJavaScriptコマンドと同じです。
show-popover:el.showPopover()hide-popover:el.hidePopover()toggle-popover:el.togglePopover()show-modal:dialogEl.showModal()close:dialogEl.close()要素に送信するカスタムコマンドを設定することも可能です。カスタムコマンドの記述は--で始まり、トグルイベントによって処理されます。
1 | <buttoncommandfor="some-element"command="--show-confetti">🎉</button> |
1 2 3 4 5 | document.querySelector('#some-element').addEventListener('command',(e)=>{ if(e.command==="--show-confetti"){ // … } }); |
<dialog>にPopover APIの便利な機能が導入されました。ポップオーバーを閉じる動作です。これによりユーザーはポップオーバーの外側(::backdrop)をクリックするか、ESCキーを押すことでポップオーバーを閉じることができます。
Chrome 134+ではこの閉じる動作が<dialog>でも利用可能になり、closedby属性が追加されました。
<dialog closeby="none">: ユーザーによる閉じる動作を一切許可しません。これがデフォルトです。<dialog closeby="closerequest">: ESCキー(または閉じるトリガー)を押すと、閉じます。<dialog closeby="any">: 外側をクリック、またはESCキーを押すと閉じます。実際の動作は、デモページでご覧ください。
See the Pen
CSS Wrapped 2025: ダイアログ 2 by coliss (@coliss)
onCodePen.
ヒントポップオーバー(popover=hint)は、ツールチップやリンクプレビューのような一時的な階層化UIパターン向けに設計された新しいタイプのHTMLポップオーバーです。ヒントポップオーバーを開いても、他の自動または手動ポップオーバーは閉じられず、階層化UI要素として共存できます。また、ボタン要素から起動が必要な自動・手動ポップオーバーとは異なり、リンク要素(a)にも配置可能です。
実装は簡単で、他のポップオーバーと同じように記述します。
1 2 3 4 | <buttoninterestfor="callout-1"></button> <divid="callout-1"popover=hint> Productcalloutinformationhere. </div> |
popover=hintと興味関心喚起([interestfor]属性)を組み合わせることで、複雑なJavaScriptなしで、HTMLとCSSでツールチップ・ホバーカード・プレビューなどの階層化されたUI要素を実装することが簡単にできます。この組み合わせにより、2つの目的をもつインタラクションパターン(ホバーでプレビュー、クリックでナビゲーションなど)が可能になり、スクリーン上の複数のレイヤーをより適切に管理できるようになります。
実際の動作は、デモページでご覧ください。
See the Pen
CSS Wrapped 2025: popover=hint by coliss (@coliss)
onCodePen.
ついに、CSSでselect要素のスタイルを設定できるようになりました。
select要素をカスタマイズするには最初にappearance: base-select;を設定します。これにより、カスタマイズに最適化された最小限の状態になります。
1 2 3 4 5 | select{ &::picker(select){ appearance:base-select; } } |
appearance: base-select;を設定すると、CSSによるカスタマイズを含め、いくつかの強力な機能が利用可能になります。ボタン、ドロップダウンリスト、オプションを含めselect要素のあらゆるパーツをCSSでスタイル設定できます。カラー、フォント、スペースを変更したり、アニメーションを追加したりすることで、サイトのデザインに合った独自の外観と操作感を実現できます。
オプションのドロップダウンリスト(::picker(select)))は、ページの最上位レイヤーにレンダリングされます。つまりこれは親コンテナによるクリッピングを受けずに、他のすべてのコンテンツの上に表示されることを意味します。ブラウザはビューポート内の利用可能なスペースに基づいて、ドロップダウンの位置と反転を自動的に処理します。
この新しいselect要素のカスタマイズでは、option要素内に直接imgやspanなどのHTML要素を含めることができ、適切にレンダリングできるようになりました。たとえば、国の選択リストで国名の横に国旗アイコンを配置するといった単純な操作から、アイコン・名前・メールアドレス・IDを表示するプロフィール選択リストの作成といった複雑な動作まで可能になります。カスタマイズ可能なselect要素内では許可されていないリンクなどのインタラクティブ要素を含まない限り、視覚的に豊かなドロップダウンメニューを自由に実装できます。
カスタマイズができるようになったselect要素でもう一つ便利な機能は、<selectedcontent>という新しい要素です。この要素は選択されたアイテムのHTMLコンテンツを反映します。複雑なドロップダウンリストの場合、<selectedcontent>内の特定要素にdisplay: none;を設定することで、アイテムの一部を表示したり、選択状態を示すアイコンを表示させることができます。
1 2 3 | selectedcontent.description{ display:none; } |
たとえば、下記のデモページのように選択された状態のときには、モンスターのスキルを非表示にするということもできます。
See the Pen
CSS Wrapped 2025: select by coliss (@coliss)
onCodePen.
CSSの新しい疑似要素::scroll-button()と::scroll-marker()を使用すると、CSSだけでカルーセルを簡単に実装できるようになります。JavaScriptは必要ありません、ネイティブでアクセシブル、かつ高性能なカルーセルを実装できます。
カルーセルとは、スクロール可能な領域にナビゲーション用のUI要素で操作できるものです。具体的には、前後にスクロールするボタン、現在の位置を示す特定のアイテムがあり、直接移動するマーカーが備わっています。
::scroll-button()疑似要素は、ブラウザが提供する状態管理が可能なインタラクティブなスクロールボタンを作成します。このボタンはスクロール可能なコンテナ上に配置され、CSSでスタイル設定が可能です。通常のbutton要素と同様に動作し、フォーカス可能で、特定方向へのスクロールが不可能になると自動的に無効になります。
このボタンは左・右・上・下といった任意のスクロール方向やblock-startやinline-endなどの論理方向にスクロールできます。スクロールボタンがアクティブになると、コンテナの可視領域の約85%分スクロールします。
1 2 3 4 5 6 7 | .carousel::scroll-button(left){ content:"⬅"/"Scroll Left"; } .carousel::scroll-button(right){ content:"⮕"/"Scroll Right"; } |
::scroll-marker疑似要素は、スクロール可能なコンテナ内の要素を示すマーカーを表します。このマーカーは::scroll-marker-groupでグループ化され、アンカーリンクのように動作します。これによりユーザーはスクロール領域内の特定のアイテムに直接ジャンプできます。これはカルーセルのドットナビゲーションや長いページの目次を作成するのに便利です。
::scroll-markerは::scroll-button()と同様に、CSSでスタイル設定が可能です。画像やテキスト、さらにはカウンターを使用して、さまざまなマーカースタイルを実装できます。さらに、:target-current疑似クラスを使用すると、現在スクロールされているアイテムに一致するアクティブなマーカー(現在位置)のスタイルを設定できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | .carousel{ scroll-marker-group:after; } .carousel>li::scroll-marker{ content:' '; width:1em; height:1em; border:1pxsolidblack; border-radius:50%; } .carousel>li::scroll-marker:target-current{ background:black; } |
下記にデモは、::scroll-button()と::scroll-marker()を組み合わせたシンプルなカルーセルです。
See the Pen
CSS Wrapped 2025: ::scroll-marker by coliss (@coliss)
onCodePen.
さらにアンカーポジショニングとスクロール状態のクエリを使用すると、より複雑なカルーセルも実装できます。
See the Pen
CSS Wrapped 2025: ::scroll-marker 2 by coliss (@coliss)
onCodePen.
CSSだけで実装するカルーセルについてさらに詳しくは、下記をご覧ください。

カルーセルはもうCSSだけで実装できる! 疑似要素::scroll-button()と::scroll-marker()の使い方を解説
CSSのカルーセルには::scroll-button()と::scroll-marker()の疑似要素に加えて、もう一つ便利な機能があります。それはscroll-target-groupです。scroll-target-groupは要素を目次のようなナビゲーションアイテムのグループを格納するコンテナとして機能します。これにより、手動で作成したアンカーリンクのリストをページ内で移動するためのスクロールマーカーに変換できます。
さらにscroll-target-groupと:target-current疑似クラスを組み合わせることで、現在表示されいてうターゲットを持つアンカー要素をスタイル設定できます。これにより、CSS Carousel APIの::scroll-markerの機能に加え、マーカーに独自のHTML要素を使用できる柔軟性が得られ、スタイルやコンテンツをより細かく制御できるようになります。
たとえば、スクロールスパイナビゲーションを作成するには、次の2つの要素が必要です。
scroll-target-group: auto;プロパティ下記のHTMLは、ページの目次で現在位置をハイライトするスクロールスパイを実装します。
1 2 3 4 5 6 7 8 9 10 11 12 13 | <navclass="toc"> <ul> <li><ahref="#section-1">Section1</a></li> <li><ahref="#section-2">Section2</a></li> <li><ahref="#section-3">Section3</a></li> </ul> </nav> <main> <sectionid="section-1">...</section> <sectionid="section-2">...</section> <sectionid="section-3">...</section> </main> |
CSSではscroll-target-groupで目次のスタイルを設定します。現在表示されているセクションに対応するリンクはredのboldで表示されます。
1 2 3 4 5 6 7 8 | .toc{ scroll-target-group:auto; } .toca:target-current{ color:red; font-weight:bold; } |
実際の動作はデモページでご覧ください。
See the Pen
CSS Wrapped 2025: scroll-target-group by coliss (@coliss)
onCodePen.
アンカー付きコンテナクエリは、アンカーの位置に基づいて要素のスタイルを設定できます。
2024年のCSSのまとめでは、CSSのアンカーポジショニングについて解説しました。これは要素同士の相対的な配置方法を変える画期的なアップデートでした。その後、Interop 2025にも取りあげられ、ブラウザのサポートも拡大しました。
しかし、CSSでは要素を代替位置に移動することはできても、どの代替要素が選択されたかを判別手段がありませんでした。つまり、ツールチップがスクリーン下部から上部に反転しても、矢印の方向は間違った方向を示していました。現在、この問題はアンカー付きコンテナクエリで解決できます。
アンカークエリは、以下の2つの手順で作成できます。
container-type: anchored;を設定します。これにより要素はアンカーの代替位置を認識できるようになります。@containerブロック内でanchored(fallback: ...)関数を使用して、配置要素の子要素に有効なフォールバック値に基づいてスタイルを設定します。フォールバック値を指定する際は、名前を付けて指定するカスタムフォールバック値、またはブラウザのデフォルト値(code>flip-block,flip-inlineなど)のいずれかになります。
アンカー付きコンテナクエリを使用して、ツールチップの位置が変化した際に自動的に矢印を反転させるのは簡単です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /* The element our tooltip is anchored to */ .anchor{ anchor-name:--my-anchor; } /* The positioned element (tooltip) */ .tooltip{ position:fixed; position-anchor:--my-anchor; position-area:bottom; /* Reposition in the block direction */ position-try-fallbacks:flip-block; /* Make it an anchored query container */ container-type:anchored; /* Add a default "up" arrow */ &::before{ content:'▲'; position:absolute; /* Sits on top of the tooltip, pointing up */ bottom:100%; } } /* Use the anchored query to check the fallback */ @containeranchored(fallback:flip-block){ .tooltip::before{ /* The 'top' fallback was used, so flip the arrow */ content:'▼'; bottom:auto; /* Move the arrow below the tooltip */ top:100%; } } |
実際の動作はデモページでご覧ください。
See the Pen
CSS Wrapped 2025: @container anchored by coliss (@coliss)
onCodePen.
ホバーやフォーカスをトリガーにしたUIは、ツールチップ、ホバーカード、ページプレビューなど、Web上のあらゆる場所で使用されています。このパターンはマウスのユーザーには効果的ですが、タッチスクリーンなど他の操作モードでは利用できない場合があります。さらに制作者は入力タイプごとにロジックを手動で実装する必要があり、一貫性のないエクスペリエンスにも繋がります。
interestforという新しい属性を使用すると、ユーザーが要素に「興味を示した」際に、ネイティブで宣言的な方法で要素をスタイル設定する手段を提供することでこの問題を解決します。interestfor属性の呼び出し方法はcommandfor属性と似ており、クリックではなく、ユーザーがマウスでホバーしたりキーボードでフォーカスしたりするなど、ユーザーが要素に「興味を示した」動作によって発動します。popover="hint"と組み合わせることで、JavaScriptを一切使用せずに、ツールチップやホーバーカードのような階層型UI要素を非常に簡単に実装できます。
1 2 3 4 5 | <buttoninterestfor="callout-1"></button> <divid="callout-1"popover="hint"> Productcalloutinformationhere. </div> |
注意: ボタン要素でのみ機能するコマンド起動子とは異なり、関心起動子はリンク(aタグ)とボタンの両方に設定できます。
下記のデモは商品の情報を表示するもので、interestforを使用して、画像上のボタンにカーソルを合わせると、詳細情報が表示されます。
See the Pen
CSS Wrapped 2025: popover="hint" by coliss (@coliss)
onCodePen.
interestforと共に追加された新機能として、関心遅延の設定も可能です。これにより関心喚起要素が早すぎるタイミングでトリガーされるのを防ぎます。遅延を設定するには、interest-delayに遅延時間を設定します。デフォルトは0.5秒ですが、下記のように短縮することもできます。
1 2 3 4 | /* applies an updated delay timing value on the interest-invoking button */ [interestfor]{ interest-delay:0.2s; } |
sponsors