CSSの疑似要素:beforeと:afterでUI要素を実装するテクニックのまとめ
Post on:2019年12月3日
CSSの疑似要素は非常に便利です。疑似要素:beforeと:afterを使用したUI要素を実装する便利なテクニックを紹介します。
Webページやスマホアプリで使えるUI要素をはじめ、クリック・タップ可能領域を広げたり、:afterと:beforeのどちらを使うべきかなど、知っておくと役立つ疑似要素のテクニックです。
Uncommon Use Cases For Pseudo Elements
by Ahmad Shadeed
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
- 疑似要素で、親子のホバーエフェクト
- 一覧のリスト
- 疑似要素で、クリック可能領域のサイズを広くする
- 疑似要素を使用したオーバーレイ
- 疑似要素で、シャドウエフェクト
- :afterと:beforeのどちらを使うべきか
- ファイル拡張子を元にリンクのスタイル設定
- 疑似要素で、区切り線
- 終わりに
疑似要素で、親子のホバーエフェクト
疑似要素はその親要素に属しているため、それを利用したテクニックがいくつかあります。分かりやすい例を使用して説明します。
子をホバーすると、親にエフェクトが適用される
見出し(Section Title)があり、その左に小さな円があります。見出しにカーソルを合わせると、この小さな円は大きくなります。
これは、下記のCSSで実現できます。
1 2 3 4 5 6 7 8 9 10 11 |
.section-title:before { content: ""; width: 20px; height: 20px; background: blue; /* Other styles */ } .section-title:hover:before { transform: scale(1.2); } |
CSSは簡単で分かりやすいと思います。
では、このコンセプトをより有用な使用例に拡張してみます。
一覧のリスト
私のWebサイトには、プロジェクトの一覧があります。プロジェクトごとにサムネイルを追加したかったのですが、最優先事項ではありませんでした。より重要だったのは、リンク自体です。このエフェクトはEthan Marcotteで、初めて見ました。
デフォルト時
上記のモックアップ画像は、私が適用したかったアイデアを示しています。本文のリンクには、それに対応する要素があります。
子要素のリンクをホバーすると、親要素にエフェクトを適用
HTMLは、下記の通りです。
1 2 3 |
<section class="hero"> <p>Hello, my name is Ahmad. I’m a UX Designer and Front End Developer that enjoys the intersection between design and code. I write on <a href="www.ishadeed.com" class="link-1">ishadeed.com</a> and <a href="www.a11ymatters.com" class="link-2">a11ymatters.com</a> on CSS, UX Design and Web Accessibility.</p> </section> |
ヒーローにpaddingを追加
疑似要素のためにスペースを確保したいので、paddingを追加します。
paddingを追加して、スペースを確保
疑似要素を絶対配置にする
絶対配置にするには、どの親が相対的な親であるかを定義する必要があります。この場合は、ヒーローセクションに追加する必要があります。
下記のアニメーションGIFで、.heroからposition: relativeを削除すると疑似要素にどのような影響を与えるかに確認してください。
position: relativeを削除すると疑似要素にどのような影響を与えるか
擬似要素を追加
最後にホバーエフェクトとともに、擬似要素を追加します。
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 |
.link-1 { color: #854FBB; } @media (min-width: 700px) { .link-1:after { content: ""; position: absolute; right: 0; top: 20px; width: 150px; height: 100px; background: currentColor; opacity: 0.85; transition: 0.3s ease-out; } .link-1:hover { text-decoration: underline; } .link-1:hover:after { transform: scale(1.2); opacity: 1; } } |
これで、子要素のリンクをホバーすると、それに対応した要素にエフェクトが適用されます。
完成したデモ
実装のポイント
疑似要素のbackgroundプロパティにcurrentColorを定義していることに注目してください。このキーワードは常に、親のカラーを継承します。そのため、リンクのカラーを変更しても問題ありません。
リンクと同じカラーを常に継承する
実際のデモは、下記ページでご覧ください。
See the Pen
Pseudo-elements: Example 1 by Ahmad Shadeed (@shadeed)
on CodePen.
もし興味があれば、私のWebサイトにも実際に使用しているので、チェックしてください。ここで紹介したテクニックを使用しています。
疑似要素で、クリック可能領域のサイズを広くする
疑似要素をリンクに追加することで、クリック可能な領域が広くなります。これは非常に便利なテクニックで、ユーザーエクスペリエンスを向上します。
クリック可能領域のサイズを広くする
さらに、カードコンポーネントのクリック可能領域を広くするためにも使用できます。記事のタイトルや画像などのコンテンツは疑似要素の上にあるため、テキストの選択や画像の保存には影響しません。
カードのクリック可能領域のサイズを広くする
この実装方法については、以前詳しく解説した記事をご覧ください。
Enhancing The Clickable Area Size
日本語訳: クリック・タップ可能な領域のサイズを広くする実装方法のまとめ
疑似要素を使用したオーバーレイ
背景画像を持つ要素があり、そのデザインに描画モードがカラーに設定されたグラデーションのオーバーレイがあるとします。その場合、疑似要素で実装できます!
疑似要素を使用したオーバーレイ
CSSは、下記の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
.hero { position: relative; height: 300px; background: url("image.jpg") center/cover; } .hero:after { content: ""; position: absolute; left: 0; top: 0; width: 100%; height: 100%; background-image: linear-gradient(180deg, #851717 0%, #30328C 100%); mix-blend-mode: color; } |
実際のデモは、下記ページでご覧ください。
See the Pen
Pseudo-elements: Example 2 by Ahmad Shadeed (@shadeed)
on CodePen.
疑似要素で、シャドウエフェクト
「Wrapped Shadows」の名称が正しいかどうか分かりませんが、私はそう認識しています。このエフェクトを実現するために、少し歪んだシャドウを作成していました、繊細なエフェクトです。
聞いてください! 疑似要素を使用するとこれも簡単に実装できます。
少し歪んだシャドウ「Wrapped Shadows」
このエフェクトの実装方法を解説します。
Step 1: 要素を作成
まずは、div要素で矩形のスタイルを定義します。
1 2 3 4 5 6 7 8 9 10 11 12 |
.elem { position: relative; display: flex; align-items: center; max-width: 400px; background: #fff; padding: 2rem 1rem; font-size: 1.5rem; margin: 2rem auto; text-align: center; box-sizing: border-box; } |
中央に配置された矩形が実装されました。
中央に配置された矩形
Step 2: 疑似要素を加える
次に、widthが50%の:beforeと:afterを加えます。
※説明のために、それぞれ異なる背景色をつけました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
.elem:before, .elem:after { content: ""; position: absolute; top: 2px; width: 50%; height: 100%; } .elem:before { left: 0; background: grey; } .elem:after { right: 0; background: #000; } |
:beforeがグレー、:afterがブラック
疑似要素にtransform: skew(x)を加え、xは2度です。1つをマイナスにすることで、目的のエフェクトが得られます。
1 2 3 4 5 6 7 |
.elem:before { transform: skew(-2deg); } .elem:after { transform: skew(2deg); } |
角度をつける
擬似要素にz-index: -1を加え、親の背後に移動します。
疑似要素を背後に移動
最後に仕上げです。
- filter: blurを加える。
- opacityを下げる。
- 透明から黒へのグラデーションを加える(親の上部中央にある擬似要素のエッジを非表示にするため)。
最終のコード
最終のコードは、下記の通りです。
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 |
.elem { position: relative; display: flex; align-items: center; max-width: 400px; background: #fff; padding: 2rem 1rem; font-size: 1.5rem; margin: 2rem auto; text-align: center; box-sizing: border-box; } .elem:before, .elem:after { content: ""; position: absolute; top: 3px; width: 50%; height: 100%; z-index: -1; background: linear-gradient(to bottom, transparent, #000); filter: blur(3px); opacity: 0.3; } .elem:before { left: 0; transform: skewY(-2deg); } .elem:after { right: 0; transform: skewY(2deg); } |
疑似要素の:beforeと:afterにskewYに入れ替えると、また違ったシャドウを実装できます。
skewYに入れ替えたエフェクト
実際のデモは、下記ページでご覧ください。
See the Pen
Pseudo-elements: Example 3 by Ahmad Shadeed (@shadeed)
on CodePen.
:afterと:beforeのどちらを使うべきか
私は最近Twitterの議論で、:afterではなく:beforeを使用する方が良いということを学びました。どうしてでしょう?
なぜなら、:afterを使用した場合は疑似要素が他のネストされた要素と重ならないようにz-indexを他のネストされた要素に追加する必要があるかもしれないからです。
実際の例を見てましょう。
サムネイルとタイトルで構成されたシンプルなカードです。テキストの下にはグラデーションオーバーレイがあり、サムネイルの画像が明るすぎる場合でもテキストが見やすくなります。
サムネイルとタイトルで構成されたシンプルなカード
HTMLは非常にシンプルです。
1 2 3 4 |
<article class="card"> <img src="article.jpg" alt=""> <h2>Title here</h2> </article> |
タイトルの下にオーバーレイを追加するには、疑似要素を使用する必要があります。:afterと:beforeのどちらを使用しますか? 両方の例を見てましょう。
:afterを使用した場合
:afterを使用した場合は、タイトルは下記のように擬似要素オーバーレイの下に表示されます。
タイトルがオーバーレイの下に表示されてしまう
これを解決するには、タイトルにz-indexを加えます。簡単で迅速な解決策ですが、それは正しい方法ではありません。
1 2 3 4 |
.card-title { /*Other styles*/ z-index: 1; } |
:beforeを使用した場合
:beforeを使用した場合は、デフォルトで機能します。タイトルにz-indexを加える必要はありません。これが機能する理由は、:beforeを使用すると他の兄弟要素の上には表示されませんが、:afterだと表示されてしまうからです。
実際のデモは、下記ページでご覧ください。
See the Pen
Pseudo-elements: Example 4 by Ahmad Shadeed (@shadeed)
on CodePen.
ファイル拡張子を元にリンクのスタイル設定
このテクニックは例えば、PDFファイルへのリンクがある場合はPDFアイコンを表示して、ユーザーに分かりやすくすることができます。
さっそく、その実装方法を見てましょう。
1 2 |
<p><a href="example.pdf">Download PDF</a></p> <p><a href="example.doc">Download Doc</a></p> |
1 2 3 4 5 6 7 8 9 10 |
a[href$=".pdf"]:before { content: ""; display: inline-block; vertical-align: middle; margin-right: 8px; width: 18px; height: 18px; background: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/182774/np_pdf_377198_000000.svg) center/20px no-repeat; padding: 3px; } |
これで、.pdfへのリンクにはPDFアイコンを、.docへのリンクにはDOCアイコンを表示します。
ファイル拡張子を元にリンクのスタイル設定
実際のデモは、下記ページでご覧ください。
See the Pen
Pseudo-elements: Example 5 by Ahmad Shadeed (@shadeed)
on CodePen.
疑似要素で、区切り線
「or」の両側にラインを引いた区切り線です、これは疑似要素とFlexboxを使用して簡単に実装できます。
疑似要素で、区切り線
実装は非常にシンプルです。
1 |
<p>Or</p> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
p { display: flex; align-items: center; } p:before, p:after { content: ""; height: 2px; background: #c5c5c5; flex-grow: 1; } p:before { margin-right: 10px; } p:after { margin-left: 10px; } |
実際のデモは、下記ページでご覧ください。
See the Pen
Pseudo-elements: Example 6 by Ahmad Shadeed (@shadeed)
on CodePen.
アップデート
この実装方法より、よい方法があります。Scott ZirkelのTwitterで指摘され、<hr>を使用する方がよいことが分かりました。実際のコードは、下記のデモをご覧ください。
See the Pen
HR with centered text by Scott Zirkel (@scottzirkel)
on CodePen.
終わりに
これで終了です。コメントや提案があれば、@shadeed9に送ってください。
sponsors