CSSの「魔法」を正しく扱う:`::before/::after` で実現する洗練されたインライン装飾の作法
フロントエンド開発の現場で、デザインカンプから「この要素の横に小さなアイコンをつけたい」「テキストの強調を少しリッチにしたい」と指示を受けたとき、あなたならどうしますか?
HTMLを汚さず、CSSだけで完結させる魔法、それが `::before` と `::after` です。しかし、この疑似要素、ただ便利というだけで使い倒していると、後々アクセシビリティの落とし穴にはまることになります。
今日は、中級エンジニアの皆さんが、自信を持って「なぜこの手法を選んだのか」を言語化し、実装できるようになるためのベストプラクティスを共有します。
—
1. ブラウザは疑似要素をどう見ているのか?
まず、技術的な解像度を上げておきましょう。`::before` や `::after` は、HTML上に実在するノードではありません。ブラウザのレンダリングエンジンは、指定された要素の「最初の子要素」または「最後の子要素」として、仮想的なノードをメモリ上に生成します。
重要なのは、「疑似要素の内容はDOMツリーには存在しない」という点です。
これは何を意味するか?
- `textContent` や `innerText` で取得できない。
- スクリーンリーダーによっては、読み上げられたり、無視されたりする。
つまり、「コンテンツとして重要な情報」を疑似要素に入れてはいけない、というのが鉄則です。あくまで「装飾(Decorative)」であるべき、という原則を忘れないでください。
—
2. 実践:インライン装飾の「綺麗な」書き方
よくあるのが、`a` タグや `span` タグの中にアイコンを直接記述し、CSSで配置する方法です。しかし、これだとHTMLの階層が深くなり、メンテナンス性が下がります。
以下は、`a` タグの後に「外部リンクアイコン」を添え、かつスクリーンリーダーに無駄な読み上げをさせないための、現場で使えるモダンな実装例です。
/ 外部リンクの装飾用スタイル /
.external-link {
position: relative;
padding-right: 1.5em; / アイコン用のスペースを確保 /
text-decoration: underline;
}
.external-link::after {
content: ‘↗’; / 装飾用の文字を挿入 /
position: absolute;
right: 0;
top: 0;
/ 重要なポイント:アクセシビリティ対応 /
/ スクリーンリーダーが二重読みしないようにする /
speak: none;
aria-hidden: true;
/ 視覚的な微調整 /
font-size: 0.8em;
color: #666;
pointer-events: none; / クリックイベントを阻害しない /
}
—
3. 注意すべきアクセシビリティの罠
前述のコードで、なぜ `aria-hidden=”true”` に相当する処理が重要なのか。それは、CSSで挿入した文字が、意図しないタイミングで読み上げられることで、ユーザーのコンテキストを破壊してしまうからです。
- 装飾的なアイコンや記号: 必ず `aria-hidden=”true”`(CSSで制御する場合は `speak: none`)を意識してください。
- 意味のある情報: もし「新規ウィンドウで開く」ということが重要なら、それはCSSの疑似要素ではなく、`(新規ウィンドウで開きます)` のようにHTML側に記述し、スクリーンリーダー向けにのみ公開するのがプロの仕事です。
—
4. 現場で重宝する `code` や `time` との組み合わせ
例えば、ブログのコードスニペットや、日付の装飾にもこの疑似要素は非常に強力です。`time` 要素の前後にアイコンを添えるだけで、UIの信頼感はぐっと増します。
.post-date::before {
content: ‘📅’; / 日付であることを直感的に伝える /
margin-right: 0.5em;
display: inline-block;
/ 疑似要素はデフォルトでインラインなので、必要に応じて調整 /
}
—
まとめ:プロとして「使い分け」の基準を持つ
`::before` / `::after` を使いこなすことは、HTMLを「セマンティクス(意味論)」に集中させ、CSSで「プレゼンテーション(表現)」を制御するという、フロントエンドの基本原則を守ることに他なりません。
1. HTMLが汚れていないか?(不要な `` タグを乱用していないか)
2. 情報の重要度は?(装飾ならCSS、情報ならHTML)
3. アクセシビリティは担保されているか?(スクリーンリーダーの読み上げを考慮しているか)
この3点さえクリアできていれば、あなたの実装は単なる「見た目の調整」から、堅牢な「UIエンジニアリング」へと昇華します。
明日からのコーディングで、ぜひこの視点を取り入れてみてください。コードの美しさは、細部へのこだわりから生まれます。もし実装で迷ったら、いつでもこの記事を見返して、基本に立ち返ってみてください。応援しています。

コメント