最近のWebサイトで見かける! フロントエンドのデベロッパーにもデザイナーにも役立つCSSの実装テクニックのまとめ
Post on:2022年3月31日
最近のWebサイトやアプリで見かけるUIコンポーネントやエフェクトを実装するCSSのテクニックを紹介します。
一昔前まではJavaScriptが必要だったりしましたが、現在ではCSSのみで実装できるようになり、覚えておくと非常に便利です。
10 Useful CSS Tricks for Front-end Developers
by Alex Ivanovs
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
- はじめに
- 1. タイプライターのようなエフェクト
- 2. 透過画像用シャドウ
- 3. カーソルのカスタマイズ
- 4. attr()でシンプルなツールチップ
- 5. ピュアCSSによるチェックリスト
- 6. is()と:where()による要素のスタイル
- 7. キーフレームを使用したアコーディオン
- 8. ホバーエフェクトのサイドバー
- 9. ::first-letterを使用した文字ドロップキャップ
- 10. ::beforeを使用してボタンの前にアイコンを追加
- 終わりに
はじめに
CSSのプロパティは、全部で200種類以上あります。そして、これらのプロパティの多くは相互に影響し合っています。すべてを把握することは、現実的には不可能かもしれません。この記事では、デベロッパーにもデザイナーにも役立つCSSの実装テクニックをいくつか紹介します。
CSSは現在、かなり良好な状態です。新機能は、CSSを真のスクリプト言語として確固たるものにするのに役立っています。
@when
や@else
を導入するためのドラフトが作成されたことはご存じですか? 今すぐには利用できませんが、将来的にはCSSで条件付きロジックを書く可能性があることを知っておいたほうがよいでしょう。
これから登場するCSSの新機能については、下記をご覧ください。
私の経験では、CSSの新機能を常にチェックしていないと、見落とすことがよくあります。is()
やwhere()
などのプロパティだけでなく、attr()
も以前から存在していましたが、モダンフレームワークの登場によって影が薄くなってしまいました。
CSSでWordPressをハックする
この記事を書くきっかけになったのは、日常的にWordPressを使用している経験から得たものです。私は10年以上WordPressを使い続けています。その間、さまざまなテーマのデザインをカスタマイズするために、1万行以上のCSSを書いてきました。
具体的に言えば、プラグインの必要性をなくすためにCSSを使用しています。WordPressの仕組みは、ほとんどすべてにおいてプラグインを使用する必要があります。もちろん、CSSを少し知っていれば別ですが。ツールチップを表示させたい? プラグインを使用しましょう。ボタンにアイコンを付けたい? プラグインが必要です。という感じです。
この記事のCSSの使用手順
CSSとHTMLを少し知っていることが唯一の条件です。サンプルテンプレートを用意しましたので、コピペしてプロジェクトに使用してください。
HTMLファイルを用意し、下記のようにコピペするだけです。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<!DOCTYPE HTML> <html> <head> <title>CSS Tricks & Tips</title> <meta charset="UTF-8" /> <style> <!-- CSSをここにコピペ --> </style> </head> <body> <!-- HTMLをここにコピペ --> </body> </html> |
1. タイプライターのようなエフェクト
Webデザインは、分単位でよりクリエイティブになってきています。そして、CSSのアニメーション機能を使用すれば、Webページを生き生きとしたものにすることができます。ここでは、animation
と@keyframes
プロパティを使用して、タイプライターのようなエフェクトを実現しています。
簡単に解説すると、steps()
プロパティでテキストアニメーションを分割しています。まず、steps()
にアニメーション化させたいテキストの文字数を指定します。空白スペースも1文字分としてください。
次に、@keyframes
にアニメーションをいつ開始するかを宣言します。例えば、「Typing effect for text」の後に別の単語を書くと、step()
の数を変更しない限り、アニメーションは機能しません。
とはいえ、このエフェクト自体は特に新しいものではありません。しかし、CSSだけで同じことができるにもかかわらず、多くのデベロッパーはJavaScriptのライブラリに群がります。
1 2 3 4 5 |
<div class="typing"> <div class="typing-effect"> Typing effect for text </div> </div> |
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 |
.typing { height: 80vh; display: flex; align-items: center; justify-content: center; } .typing-effect { width: 22ch; animation: typing 2s steps(22), effect .5s step-end infinite alternate; white-space: nowrap; overflow: hidden; border-right: 3px solid; font-family: monospace; font-size: 2em; } @keyframes typing { from { width: 0 } } @keyframes effect { 50% { border-color: transparent } } |
2. 透過画像用シャドウ
透過画像にbox-shadow
を与えたら、まるで枠を与えたようになったことはありませんか? 透過画像にシャドウを与えるには、drop-shadow
を使用します。
この方法が機能する理由は、drop-shadow
プロパティは与えられた画像のアルファチャンネルに従うからです。そのため、シャドウは画像の外側にではなく、画像の内側の形状にもとづいて表示されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<div class="transparent-shadow"> <div class="margin-right"> <div class="margin-bottom align-center"> box-shadow </div> <img class="box-shadow" src="https://stackdiary.com/wp-content/uploads/2022/02/logo.png" alt="box-shadow example (transparent)"> </div> <div> <div class="margin-bottom align-center"> drop-shadow </div> <img class="drop-shadow" src="https://stackdiary.com/wp-content/uploads/2022/02/logo.png" alt="drop-shadow example (transparent)"> </div> </div> |
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 |
.transparent-shadow { height: 80vh; display: flex; align-items: center; justify-content: center; } .margin-right { margin-right: 2em; } .margin-bottom { margin-bottom: 1em; } .align-center { text-align: center; } .box-shadow { box-shadow: 2px 4px 8px #3723a1; } .drop-shadow { filter: drop-shadow(2px 4px 8px #3723a1); } |
3. カーソルのカスタマイズ
ビジターを固有のカーソルに強制的に誘導する必要はまずないでしょう。少なくとも、一般的なUXではありません。ただし、cursor
プロパティで注目すべき点は、画像を表示できることです。これはツールチップで写真を表示するのと同じことができます。
たとえば、ビューポートで写真をレンダリングすることなく、2つの異なる写真を比較できるようにするなどの用途があります。cursor
プロパティは、デザインのスペースを節約するために使用できます。カスタムカーソルは特定の要素だけに表示することができるため、それ以外の要素に干渉することはありません。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<div class="custom-cursor"> <div class="card"> Default </div> <div class="card card-image-cursor"> Image </div> <div class="card card-emoji-cursor"> Emoji </div> </div> |
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 |
.custom-cursor { display: flex; height: 80vh; align-items: center; justify-content: center; background: #f3f3f3; padding: 0 10px; } .card { width: 200px; height: 200px;display: flex; align-items: center; justify-content: center; background-color: #D29A5A; margin-right: 10px;color: #fff; font-size: 1.4em; text-align: center; } .card-image-cursor { background-color: #D11A5A; cursor: url(https://stackdiary.com/tools/assets/img/tools/html-beautifier.svg), auto; } .card-emoji-cursor { background-color: #D29B22; cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewport='0 0 100 100' style='fill:black;font-size:24px;'><text y='50%'>🚀</text></svg>"), auto; } |
4. attr()でシンプルなツールチップ
attr()
プロパティは、私のお気に入りの最近の発見の一つです。WordPressのブログにツールチップ機能を追加したかったのですが、そのためには不要な肥大化をもたらすプラグインを使用する必要がありました。ありがたいことに、attr()
を使用すれば、それを回避できます。
仕組みは非常に簡単です、コードについて説明します。
.tooltip
を使用して、ツールチップになる要素を指定します。これは好きなようにスタイルができ、このデモではdotted border-bottom
にしています。- 次に、
content: attr();
とそれを含む:before
擬似要素を作成します。ここでは、content: attr(tooltip-data);
としました。 - 最後に、
:hover
疑似クラスを作成し、ツールチップの上にカーソルを合わせたときにopacity
が1
になるように設定します。
スタイルはカスタマイズもできます。ツールチップに表示するテキストの量によっては、幅だけでなく、マージンも調整する必要があるかもしれません。すべてを設定しておけば、ページ内のどの要素にもtooltip-data
とattr()
を再利用できます。
1 2 3 4 5 6 7 8 9 |
<h1> HTML/CSS tooltip </h1> <p> Hover <span class="tooltip" tooltip-data="Tooltip Content">Here</span> to see the tooltip. </p> <p> You can also hover <span class="tooltip" tooltip-data="This is another Tooltip Content">here</span> to see another example. </p> |
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 36 37 38 39 40 41 42 43 44 |
.tooltip { position: relative; border-bottom: 1px dotted black; } .tooltip:before { content: attr(tooltip-data); position: absolute; width: 250px; background-color: #efba93; color: #fff; text-align: center; padding: 15px; line-height: 1.1; border-radius: 5px; z-index: 1; opacity: 0; transition: opacity .5s; bottom: 125%; left: 50%; margin-left: -60px; font-size: 0.70em; visibility: hidden; } .tooltip:after { content: ""; position: absolute; bottom: 75%; left: 50%; margin-left: -5px; border-width: 5px; border-style: solid; opacity: 0; transition: opacity .5s; border-color: #000 transparent transparent transparent; visibility: hidden; } .tooltip:hover:before, .tooltip:hover:after { opacity: 1; visibility: visible; } |
5. ピュアCSSによるチェックリスト
冒頭で述べたように、CSSは着実に成熟しています。そして、この動的なチェックリストはその典型です。
仕組みは、input
要素のcheckbox
タイプを:checked
疑似クラスと一緒に使用するというものです。また、transform
プロパティを使用して、:checked
指定がtrueを返すたびに状態を変更します。
このテクニックは応用もできます。たとえば、チェックボックスをクリックしたときに非表示のコンテンツを表示します。radio
やcheckbox
などのinput
要素で使用されるのが一般的ですが、option
要素やselect
要素でも使用できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<div class="checklist"> <h2>Item Checklist with CSS</h2> <label> <input type="checkbox" name="" id="" /> <i></i> <span>Item #1</span> </label> <label> <input type="checkbox" name="" id="" /> <i></i> <span>Item #2</span> </label> <label> <input type="checkbox" name="" id="" /> <i></i> <span>Item #3</span> </label> </div> |
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
.checklist { padding: 50px; position: relative; background: #043b3e; border-top: 50px solid #03a2f4; } .checklist h2 { color: #f3f3f3; font-size: 25px; padding: 10px 0; margin-left: 10px; display: inline-block; border-bottom: 4px solid #f3f3f3; } .checklist label { position: relative; display: block; margin: 40px 0; color: #fff; font-size: 24px; cursor: pointer; } .checklist input[type="checkbox"] { -webkit-appearance: none; } .checklist i { position: absolute; top: 2px; display: inline-block; width: 25px; height: 25px; border: 2px solid #fff; } .checklist input[type="checkbox"]:checked ~ i { top: 1px; height: 15px; width: 25px; border-top: none; border-right: none; transform: rotate(-45deg); } .checklist span { position: relative; left: 40px; transition: 0.5s; } .checklist span:before { content: ''; position: absolute; top: 50%; left: 0; width: 100%; height: 1px; background: #fff; transform: translateY(-50%) scaleX(0); transform-origin: left; transition: transform 0.5s; } .checklist input[type="checkbox"]:checked ~ span:before { transform: translateY(-50%) scaleX(1); transform-origin: right; transition: transform 0.5s; } .checklist input[type="checkbox"]:checked ~ span { color: #154e6b; } |
6. is()と:where()による要素のスタイル
最近のCSSのモダンフレームワークの仕組みの一つに、条件付き論理セレクタがあります。つまり、:is()
プロパティや:where()
プロパティを使用して、さまざまな要素のスタイルを一度に設定できます。そしてより重要なことは、これらのプロパティを使用して、通常なら個別に指定しなければならない要素をクエリできることです。
下記のCSSには、さまざまな例が含まれています。各クエリが何をするのか、コメントを追加しました。:is()
プロパティや:where()
プロパティについて詳しく知りたいときは、下記をご覧ください。
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 |
/* 見出し要素内のb要素を選択し、カラーを変更します。 */ :where(h2,h3,h4) > b { color: yellow; } /* article要素内にネストされたfooterのp要素を選択します。デザインの特定の要素を選択し、スタイルを設定できます。 */ article :is(footer) > p { color: black; } /* さまざまなスタイルを同時に作成します。:whereプロパティで、動的にテーマスタイル内の特定要素を選択できます。 たとえば(button、a)にすると、さらにネストできます。 */ .dark-button-style :where(button) { background-color: red; } /* 複数のセレクタを一度に選択する場合にも有効です。 */ :is(.dark-button-style, .red-button-style) :where(button) { color: red; } /* div要素内にあるh2要素を選択します。 */ :is(h2):where(.content-title) { text-transform: uppercase; } /* 特定のサブセットに変更を適用することで、クエリをさらに改善できます。 */ .title-area:is(h2:is(.content-title)) { font-weight: 900; } |
7. キーフレームを使用したアコーディオン
JavaScriptのライブラリ(jQueryなど)の問題点は、必要なのが小規模な機能であってもライブラリ全体を読み込まなければならないことです。このアコーディオンの例もそうです。
現在のWebデザインのトレンドをよく見てみると、ランディングページにアコーディオンがあるのを見つけるのに時間はかからないでしょう。スペースを占有するコンテンツを凝縮するとてもシンプルな方法です。よくある質問、製品の特徴、使い方のヒントなど、さまざまな情報をアコーディオンに入れることができます。そのアコーディオンをピュアCSSで実装できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<main> <details open> <summary>Accordion Tab #1</summary> <div class="tab-content"> <p>your text goes here</p> </div> </details> <details> <summary>Accordion Tab #2</summary> <div class="tab-content"> <p>your text goes here</p> </div> </details> <details> <summary>Accordion Tab #3</summary> <div class="tab-content"> <p>your text goes here</p> </div> </details> </main> |
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 36 37 38 39 40 41 42 |
/* .tab-contentは好きなようにスタイルできます */ main { max-width: 400px; margin: 0 auto; } p { text-align: justify; font-family: monospace; font-size: 13px; } summary { font-size: 1rem; font-weight: 600; background-color: #f3f3f3; color: #000; padding: 1rem; margin-bottom: 1rem; outline: none; border-radius: 0.25rem; cursor: pointer; position: relative; } details[open] summary ~ * { animation: sweep .5s ease-in-out; } @keyframes sweep { 0% {opacity: 0; margin-top: -10px} 100% {opacity: 1; margin-top: 0px} } details > summary::after { position: absolute; content: "+"; right: 20px; } details[open] > summary::after { position: absolute; content: "-"; right: 20px; } details > summary::-webkit-details-marker { display: none; } |
8. ホバーエフェクトのサイドバー
CSSで動的なホバーエフェクトのサイドバーを実装することは可能でしょうか? もちろん可能です、transform
や:hover
プロパティを利用します。
互換性については、さまざまなスマホ環境で試してみましたが、問題なく動作しました。ただし、スマホのスクリーンは窮屈に感じることがあるので、デスクトップの方がうまく機能します。
さらに、このテクニックはposition: sticky;
で、スティッキーに対応したサイドバーにすることもできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<div class="css-dynamic-sidebar"> <nav> <a class="" href="#">Menu #1</a> <a class="" href="#">Menu #2</a> <a class="" href="#">Menu #3</a> </nav> <div class="site-content"> <p>Hover over the sidebar</p> <p>Also work with Tab selector (for accessibility)</p> </div> </div> |
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 36 37 38 |
.css-dynamic-sidebar { overflow: hidden; position: relative; height: 15em; max-width: 15em; margin: auto; } .site-content { margin: auto; } nav { display: flex; flex-direction: column; position: absolute; right: 100%; padding: 1em; background-color: #f3f3f3; transform: translateX(1em); transition: 0.2s transform; } nav:hover, nav:focus-within { transform: translateX(100%); } a { white-space: pre; color: black; } p { font-size: 2em; font-family: monospace; text-align: center; } |
9. ::first-letterを使用した文字ドロップキャップ
CSSでは、先頭の要素を選択することが可能です。ここでは::first-letter
疑似クラスでドロップキャップのエフェクトを作成します。この疑似クラスのよいところは、文字を自由にスタイルできることです。そのため、デザインに合わせてドロップキャップの外観を調整できます。
このプロパティは、いろいろなことが実現できます。ある要素がページ上に初めて現れたときに限り、first-of-type
で個別にスタイルを設定できます。ただし、以前に表示されたにもかかわらず、複数の要素をターゲットにすることもできます。
1 2 3 4 5 6 7 8 9 10 11 |
/* ラッパーの.content-sectionをターゲットにして、p要素を選択します。次に、first-of-typeを追加して、first-letterをターゲットにします。ラッパー変数を変更することにより、デザインの他の部分で再利用できます。 */ .content-section p:first-of-type::first-letter { color: #f3f3f3; float: left; font-size: 4rem; line-height: 4vw; padding-right: 8px; /* border: 0.25em double; */ } /* borderなどのプロパティを追加して、本のプレゼンなどに適したクリエイティブなドロップキャップを作成することもできます */ |
10. ::beforeを使用してボタンの前にアイコンを追加
ブログを始めた目的の一つは、コンテンツの表示方法をよりクリエイティブにすることでした。また、私はリスト記事やさまざまなラウンドアップを書いているので、それらに個人的なタッチがあることを確認したかったのです。このようなブログを始めたのは、私が最初でも最後でもありませんが、カスタムデザインの要素は大いに役立つと思います。
通常、外部のリソースにリンクするときは、ボタンにカスタムスタイルを追加しています。具体的には、アイコンを追加したボタンです。Googleで検索すれば「ボタンジェネレーター」はたくさん見つかりますが、私は好きなときに再利用できる普遍的なテクニックに最も関心がありました。
そこで私の目標を達成するために、ボタンのためのカスタム:before
クラスを作成しました。このスニペットのcontent:"\0000a0";
は、 をエスケープしたものです。
アイコンのサイズは、スタイルを適用するボタンのサイズに合わせてwidth
とheight
プロパティで調整できます。
1 2 3 4 5 6 7 |
<div class="card"> <div class="card-body"> <a href="" target="_blank" class="wp-block-button btn btn-web btn-primary" rel="noopener">Website</a> <a href="" target="_blank" class="wp-block-button btn btn-docu btn-primary" rel="noopener">Documentation</a> <a href="" target="_blank" class="wp-block-button btn btn-gh btn-primary" rel="noopener">GitHub</a> </div> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/* グローバルボタンのスタイルを定義した後で、アイコンや画像を使用するカスタムのボタンクラスを定義します。 */ .btn-primary .btn-docu:before { content:"\0000a0"; display:inline-flex; height:24px; width:24px; line-height:24px; margin:0px 10px 0px 0px; position:relative; top:0px; left:0px; background:url(https://stackdiary.com/docu.svg) no-repeat left center transparent; background-size:100% 100%; } |
終わりに
JavaScriptではなくCSSを選択する。
ここで紹介したCSSのテクニックは、特定のデザイン機能においてJavaScriptが不要になる可能性を浮き彫りにしています。そして素晴らしいことは、実質的にどのようなデザインにも実装できることです。実際、これらの多くを組み合わせることで、よりクリエイティブなデザインの自由を実現できます。
もちろん、まだ改善の余地はあるでしょう。このようなスニペットによって、フレームワークやライブラリが不要になるとは思っていません。
しかし、JavaScriptを長々と書かなくても、CSSが複雑なデザイン効果を実現できる方向に向かっているのは、とてもよいことだと思います。
CSSによるアニメーションに興味がある人は、CSS Animation Examplesもご覧ください。現在作業中ですが、CSSアニメーションのデモを増やしていきます。
sponsors