In 'n' Out

知識を取り込み、そして発信する

疑似要素と属性セレクタ

HTMLを増やさずに指定するCSS

CSSには、HTMLの構造を変更せずに見た目や指定範囲を補足できる仕組みがあります。
疑似要素は、実際には存在しない要素をCSSによって生成し、装飾や表現を追加するために使われます。
また、属性セレクタは、HTMLに記述された属性を条件としてスタイルを適用する方法です。
ここでは、HTMLを増やさずにスタイルを制御する代表的な指定方法として、疑似要素と属性セレクタを解説します。

疑似要素

まずは疑似要素にはどのようなものがあるのか一覧表でまとめました。

疑似要素一覧
疑似要素主な対象説明
::before任意の要素要素内容の前に生成される
::after任意の要素要素内容の後に生成される
::placeholderinput・textareaプレースホルダ文字
::file-selector-buttoninput[type="file"]ファイル選択ボタン部分
::markerliリストマーカー
::first-letterブロック要素最初の1文字
::first-lineブロック要素最初の1行
::selectionテキスト選択中の文字列
::backdropdialogなどモーダル背後
::cuevideo・audio字幕キュー
::cue-regionvideo字幕リージョン
::grammar-errorテキスト文法エラー
::spelling-errorテキストスペルエラー
::target-textinputURL指定テキストアンカー遷移文字
::part()Shadow DOM公開パーツ
::slotted()Shadow DOMslot内要素

様々な種類があり説明文だけではわからないことが多いですが、使用する際に詳細を改めて説明します。
このページでは使用頻度の高い疑似要素である::beforeと::afterを取り扱います。
その前に両疑似要素で重要であるcontentプロパティを解説します。

contentプロパティ

contentプロパティは疑似要素専用のプロパティです。

構文

セレクタ::疑似要素{
    content:"値";
}

contentプロパティは、疑似要素として生成される内容そのものを指定するためのプロパティです。
::before や ::after では、content を指定しない限り疑似要素は表示されません。
主に::beforeや::afterで使用したり、装飾目的の場合は、表示する文字がなくても疑似要素を生成するために、空文字("")を指定することがよくあります。。

::before・::after

::beforeと::afterは、要素の内容の前後に疑似的な要素を生成します。
装飾目的で最も使用される疑似要素であり、HTMLを汚さずにアイコンや飾り線を追加できます。

::before

構文

セレクタ::before{
    content:"文字";
    プロパティ:値;
}

::beforeは、要素の内容の前に疑似的な要素を生成します。
また、contentプロパティを指定する必要があり、contentプロパティで指定した値に対してスタイルを適用します。

コード例

<p>テキストの前に四角を表示</p>
p::before{
    content:"■";
    color: red;
}

出力例

テキストの前に四角を表示

このようにHTMLにはない文字が表示されます。
しかも文字色もcontentで指定した文字列に対してのみ適用されます。

::after

構文

セレクタ::after{
    content:"文字";
    プロパティ:値;
}

::afterは、要素の内容の後ろに疑似的な要素を生成します。
また、::before同様、contentプロパティを指定する必要があり、contentプロパティで指定した値に対してスタイルを適用します。

コード例

<p>テキストの後ろに青い文字で日付を表示</p>
p::after{
    content:"12/24";
    color: blue;
}

出力例

テキストの後ろに青い文字で日付を表示

::before同様、HTMLにはない文字が表示されます。
文字色もcontentで指定した文字列に対してのみ適用されます。

このように::before・::after疑似要素はHTMLの構造にかかわらず、文字を追加することができます。
この特性により、装飾目的の文字や記号をHTMLに直接書く必要がなくなります。
ただし、追加できる文字はcontentプロパティで指定した文字列のみで、contentプロパティを複数指定することはできませんが、::beforeと::afterを同時に指定することはできます。

疑似要素で追加した内容はスクリーンリーダーに読み上げられない場合があります。
重要な情報はHTMLに記述するようにしましょう。

属性セレクタ

属性セレクタは、HTML要素が持つ属性や属性値を条件としてスタイルを指定する方法です。
classやidを追加せずに指定できるため、HTMLを変更できない場合や、フォーム要素などで補助的に使われます。
指定方法にはいくつかの種類があり、用途に応じて使い分けることが重要です。

属性セレクタ一覧
書き方主な対象条件・説明
[属性名]全HTML要素指定した属性を持つ要素すべてに一致
[属性名="属性値"]属性値が完全に一致する要素
[属性名~="属性値"]classを持つ要素空白切りの属性値リストに属性値を含む
[属性名|="属性値"]lang属性を持つ要素属性値または属性値-で始まる属性値
[属性名^="属性値"]href・srcを持つ要素属性値が指定文字列で始まる状態
[属性名$="属性値"]属性値が指定文字列で終わる状態
[属性名*="属性値"]全HTML要素属性値に指定文字列を含む状態
[属性名="属性値" i]大文字・小文字を区別せず一致
[属性名="属性値" s]大文字・小文字を区別して一致

様々な種類があり説明文だけではわからないことが多いですが、使用する際に詳細を改めて説明します。
このページでは使用頻度の高い[attr]、[attr="value"]、[attr*="value"を取り扱います。

属性を持つ要素の選択

指定した属性を持つ要素すべてに一致した場合にCSSを適用する属性セレクタです。

構文

要素名[属性名]{
    プロパティ:値;
}

属性名のみを指定すると、その属性を持つすべての要素が対象になります。
属性値の内容は問わず、属性が存在するかどうかで判定されます。

コード例

<a href="#" target="_blank">リンク1</a>
<a href="#" target="_self">リンク2</a>
<a href="#">リンク3</a>
a{
    display: block;
    width: 100px;
}

a[target]{
    color: red;
    font-weight: bold;
    border: 1px solid #ff0000;
}

出力例

このようにaタグの属性値にtargetがあるもののみを対象としてCSSが適用されます。
targetの値が_selfだとしても対象になるため、意図しない要素に影響する可能性があります。
限定したい場合は属性値まで指定する方が安全です。

属性値を完全一致で指定

属性値が完全に一致する要素にCSSを適用する属性セレクタです。

構文

要素名[属性名="値"]{
    プロパティ:値;
}

属性名と属性値を指定することで、特定の条件に一致する要素だけを対象にできます。
属性セレクタの中で、最もよく使われる指定方法です。

コード例

<form>
    <label>お名前
        <input type="text">
    </label>
    <label>メールアドレス
        <input type="text">
    </label>
    <label>電話番号
        <input type="text">
    </label>
    <label>メッセージ
        <textarea></textarea>
    </label>
</form>
label{
    display: block;
}

input{
    margin-bottom: 0.5rem;
}

input[type="text"] {
    width: 150px;
    color: blue;
}

textarea {
    vertical-align: top;
}

出力例

お名前・メールアドレス・電話番号に文字をなんでもいいので入力してみてください。
type="text"を持つinput要素のみにスタイルが適用されます。
他のinput要素には影響しません。
指定が明確で安全なのですが、属性値が変わるとスタイルが効かなくなるため、安定したHTML構造が前提となります。

属性値を部分一致で指定

属性値に指定文字列を含む状態にCSSを適用する属性セレクタです。

構文

要素名[属性名*="値"]{
    プロパティ:値;
}

属性値の中に指定した文字列を含む要素が対象になります。
前方・後方を問わず一致するため、柔軟な指定が可能です。

コード例

<div>
    <img src="../img/car1.jpg" alt="新車" width=150px>
    <img src="../img/car2.jpg" alt="中古車" width=150px>
    <img src="../img/car3.jpg" alt="新古車" width=150px>
</div>
img[alt*="新"]{
    border: 5px solid #ff0000;
}

img[alt*="古"] {
    box-shadow: 2px 2px 5px #0000ff99;
}

出力例

新車 中古車 新古車

alt属性の属性値に「新」を含むなら赤い枠を追加、「古」を含むなら影を追加するようにしました。
新車・新古車・中古車とあるので、1枚目の画像は赤い枠、2枚目は影のみ、3枚目は2つの条件を満たしているので赤い枠と影が追加されます。
他のimg要素には影響しません。
柔軟ですが場合によっては影響範囲が広く、意図しない一致が起きやすくなります。
ただ、命名規則が決まっていると有効なので、管理に気を付ければ活用できるシーンが多くなります。
基本はclass指定とし、属性セレクタは「HTMLを変更できない」「種類や状態で分けたい」場合に限定して使うのが安全です。

CSSは使いどころを理解する

CSSには多くのセレクタや疑似要素がありますが、すべてを覚える必要はありません。
実務で使用する機会が多いものと、知識として知っておけば十分なものには明確な差があります。

疑似要素の中でも、::before や ::after は装飾目的で頻繁に使用され、CSSを書く上で欠かせない存在です。
一方で、使用条件が限定される疑似要素については、無理に使おうとする必要はありません。
必要になったときに調べて使える状態であれば十分です。

属性セレクタも同様に、使用する機会はそれほど多くありません。
class指定が基本であり、属性セレクタはHTMLを変更できない場合や、補助的な指定として使われるのが一般的です。

重要なのは、すべての記述方法を暗記することではなく、「どの指定方法が適しているか」を判断できることです。
使用頻度の高いものから理解し、必要に応じて知識を広げていきましょう。