イマドキの擬似要素 2024年版 前編 UIを伴った要素のための擬似要素

この記事では、2018年に書かれたシリーズから2024年現在までの間に登場した、比較的新しい擬似要素について解説します。前編ではdetails要素や、typeがfileのinput要素などUIを伴った要素のスタイリングをとりあげます。

発行

著者 坂巻 翔大郎 フロントエンド・エンジニア
イマドキの擬似要素 2024年版 シリーズの記事一覧

はじめに

CodeGridでは以前、2018年に「CSSセレクター総ざらい」というシリーズの中で、擬似要素について解説しました。

擬似要素は、特定のHTML要素の一部分や、実際にはHTML構造に存在しない仮想的な部分に対してスタイルを適用するためのものです。コロン2つ(::)を使って指定します。

実務でもよく使われるものでいえば::before::afterがあります。これらは、指定した要素の最初や最後に要素を追加するためのものです。

元のHTML

<p>これはテキストです。</p>

::before擬似要素

p::before {
  content: "★";
  color: red;
}

CSSセレクターについてのシリーズのなかでは、「さまざまな擬似要素」の部分でいくつかの擬似要素について解説しています。

  • ::before擬似要素::after擬似要素
  • ::first-line擬似要素::first-letter擬似要素
  • ::selection擬似要素
  • ::placeholder擬似要素

また::marker擬似要素については「::marker擬似要素 | contentプロパティ再入門 後編」で解説されています。

補足:::marker擬似要素のブラウザ対応状況

2024年12月現在は、Chrome、Edge、Firefox、Safariでサポートされています。しかしSafariについては、colorfont-sizeプロパティのみのサポートで、contentプロパティによるコンテンツ生成に対応しておらず、ブラウザが表示するマーカーに対してのプロパティ指定となります。

本記事では、上記のシリーズでは触れなかった、比較的新しい擬似要素について解説します。

擬似要素についての仕様は以下を参照してください。

ほかにも::backdrop擬似要素についてはCSS Positioned Layout Module Level 4の中で登場するため、今回は取り上げていませんが、CodeGridの「dialog要素でつくるモーダルダイアログ | 第1回 | 基本実装と見た目のカスタマイズ」で利用方法を解説しています。

本記事で解説する擬似要素

本シリーズでは、前後編に分けて、以下の擬似要素について解説します。

  • ::details-content
  • ::file-selector-button
  • ::spelling-error
  • ::grammar-error
  • ::highlight()
  • ::target-text
  • ::search-text

なお、記事中のデモのソースコードは以下のリポジトリにまとまっています。

イマドキの擬似要素 2024年版

details要素のコンテンツをスタイリング:::details-content

::details-content擬似要素を使うことで、details要素内のsummary要素を除くコンテンツ部分に対してスタイルを当てられるようになりました。仕様に追加されたのが2024年になってからということもあり、2024年12月現在、実装しているブラウザーはChrome、Edgeのみです。details要素については詳細を折りたたむdetails要素で解説されています。

::details-content擬似要素を利用して、コンテンツが展開されたときにスタイルを当てるには次のようにします。

details要素を使ったHTML

<details>
  <summary>ここをクリックして開閉</summary>
  <p>テキストが入ります</p>
  <ul>
    <li>リストです</li>
    <li>リストです</li>
    <li>リストです</li>
  </ul>
</details>

<details open>
  <summary>ここをクリックして開閉</summary>
  <p>テキストが入ります</p>
  <ul>
    <li>リストです</li>
    <li>リストです</li>
    <li>リストです</li>
  </ul>
</details>

::details-content擬似要素

details[open]::details-content {
  border: 5px dotted tomato;
}

デモでは、内容が展開されたときだけ、details要素のsummary要素を除いた子要素を囲む赤い点線の枠が表示されます。

さらに、他のプロパティと組み合わせることで、展開されるときのアニメーションも簡単にできるようになっています。開閉の際にスライドするアニメーションを追加します。

::details-content擬似要素とアニメーション

:root {
  interpolate-size: allow-keywords;
}

::details-content {
  transition:
    opacity 0.5s ease,
    height 0.5s ease,
    content-visibility 0.5s ease allow-discrete;
  height: 0;
  opacity: 0;
  overflow: clip;
}

details[open]::details-content {
  border: 5px dotted tomato;
  opacity: 1;
  height: auto;
}

従来、CSSのみでコンテンツの高さが不明なものに対して開閉アニメーションをつけるには、JavaScriptを使用する必要がありました。いくつかのテクニックを組み合わせることで、details要素の開閉時にCSSのみでアニメーションを実装できるようになりました。

::details-content擬似要素の開閉アニメーション

::details-content擬似要素のdisplayプロパティ値は、閉じているときも開いているときもblockです。それでもコンテンツが隠れたり出たりしているのは、content-visibilityプロパティの値がhiddenからvisibleへと変化しているためです。

開閉アニメーションをするためには、content-visibilityプロパティの変化をアニメーションさせることと、要素の高さを0pxからコンテンツに合った高さ(auto)にアニメーションさせる工夫が必要になります。

前節のアニメーションのデモで、まず1つ目の工夫があるのは、content-visibility 0.5s ease allow-discreteの部分です。

アニメーションを実現している部分

::details-content {
  transition:
    opacity 0.5s ease,
    height 0.5s ease,
    content-visibility 0.5s ease allow-discrete;
  height: 0;
  opacity: 0;
  overflow: clip;
}

details要素の開閉時に、::details-content擬似要素のcontent-visibilityプロパティ値を0.5sかけて変化させるというものです。

content-visibilityvisiblehiddenといった値を指定することで、コンテンツの描画を制御するプロパティです。そしてそのプロパティをアニメーションさせるためにはallow-discreteを指定する必要があります。

2つ目の工夫は、デモコード冒頭の部分です。

アニメーションを実現している部分

:root { interpolate-size: allow-keywords; }

interpolate-sizeプロパティは、automin-contentといったキーワード値のアニメーションの可否を制御するもので、allow-keywordsを指定することで、キーワード値のアニメーションを許可します。端的にいえば、height: 0;からheight: auto;へのアニメーションが可能になります。

:rootに対して指定することで、ドキュメント全体でキーワード値のアニメーションを許可します。

この2つの工夫をすることで、JavaScriptを使わずに::details-content擬似要素の開閉アニメーションを可能にしています。

typeがfileのinput要素の選択ボタンをスタイリング:::file-selector-button

<input type="file">の選択ボタン部分にスタイルを適用するための擬似要素です。

ボタン用の見出し

<h2>通常のもの</h2>
<input type="file">

<h2>スタイルをかえたもの</h2>
<input type="file" class="-custom">

::file-selector-button擬似要素

.-custom {
  border: 3px solid black;
  border-radius: 10px;
}

.-custom::file-selector-button {
  padding: 10px;
  border: 0;
  background-color: black;
  color: #fff;
  padding: 5px 10px;
  margin-right: 10px;
}

.-custom:hover::file-selector-button {
  color: yellow;
  font-weight: bold;
}

CodeGridでは以前、「ファイル選択UIのカスタマイズ 前編」の中でこの擬似要素について解説しています。当時はブラウザの対応がまちまちだったため、接頭辞付きの::-webkit-file-selector-buttonや、::-ms-browseといった擬似要素を使っていました。2024年現在は足並みが揃っているので、::file-selector-buttonでかまいません。

ちょっとしたスタイルを当てる程度で良ければ、この擬似要素を使うのが良いでしょう。さらにカスタマイズした見た目にしたい場合は、「ファイル選択UIのカスタマイズ」シリーズの記事を参考にしてください。

ここまでのまとめ

本記事で解説した擬似要素は次のとおりです。

  • ::details-content<details>要素内の<summary>以外の部分をスタイル付け可能。開閉アニメーションするには工夫が必要。
  • ::file-selectors-button<input type="file">の選択ボタンをスタイル変更可能。

擬似要素によるスタイリングで、標準のCSSだけでさまざまな見た目を作り出すことができます。また、そのほかのテクニックを組み合わせることで、アニメーションも可能になりました。

次回は、テキストに関連した擬似要素を中心に解説をします。