最近見かけた、CSSの一工夫加えたスゴ技テクニックのまとめ
Post on:2022年7月26日
Apple, Nike, Tesla, AirbnbなどのWebサイトやスマホアプリで使用されている、CSSの一工夫加えたスゴ技テクニックを紹介します。
美しい磨りガラスのヘッダ、コンテンツがズームするエフェクト、タッチフレンドリーなカルーセル、超クールなスワイプオーバーセクション、新感覚のスワイプアップするドロワーなど、すぐに使えるCSSのテクニックです。
my favorite clever CSS tricks
by @Steve8708
下記は各ポイントを意訳したものです。
※著者様の許諾のもと、翻訳・掲載しています。
Apple: ヘッダに使用されている美しい磨りガラスのエフェクト
Appleのヘッダに使用されている、美しい磨りガラスのエフェクトはCSSで実装されています。
How does Apple make that awesome frosted glass effect on their site header in CSS?
tl;dr backdrop-filter: blur(20px) saturate(180%)
Better explanation 👇 pic.twitter.com/vbmMaanbIA
— Steve (Builder.io) (@Steve8708) May 30, 2022
背景色を設定し、backdrop-filter: blur(20px);
でぼかし、磨りガラスの効果を与えます。Appleではさらに工夫がされており、saturate(180%)
で背景の彩度も調整しています。
1 2 3 4 |
#ac-globalnav { background: rgba(0,0,0,0.8); backdrop-filter: saturate(180%) blur(20px); } |
上記の背景色background: rgba(0,0,0,0.8);
はブラックですが、明るいホワイトでもこのエフェクトは使用できます。
1 2 3 4 |
#ac-globalnav { background: rgba(255,255,255,0.5); backdrop-filter: saturate(180%) blur(20px); } |
2022年7月現在、backdrop-filter
プロパティはFirefoxを除くすべてのブラウザにサポートされています。ただし、Firefoxの次期バージョン103でサポートされる予定です。
参考: backdrop-filterのサポート状況
backdrop-filter
プロパティの使い方については下記をご覧ください。
Apple: 超クールなスワイプオーバーセクション
iPhone 13やMacBookなど、Appleのプロダクトページでよく使用されているセクションをスワイプオーバーさせる超クールなエフェクトもCSSのみで実装できます。
Make super cool swipe-over sections like Apple in pure CSS!
Try it in code: https://t.co/OUvhtQK5IP
Try it in @builderio: https://t.co/5RMA37TdIr pic.twitter.com/lOiUdFeHx1— Steve (Builder.io) (@Steve8708) June 25, 2022
スワイプオーバーとは、高さいっぱいのセクションをカーテンを上げるように表示するエフェクトです。昔は背景をposition:fixed;
にして実装されていましたが、position: sticky;
を使用するとセクション単位で実装できます。
まずは、HTMLの基本構造。
1 2 3 4 |
<div class="wrapper"> <section class="under"></section> </div> <section class="over"></section> |
.under
が最初に表示され、.over
がスワイプオーバーで表示されます。
1 2 3 4 5 6 7 8 9 10 11 |
.under{ position: sticky; top: 0; } .wrapper{ height: 200vh; } .over{ margin-top: -100vh; position: relative; } |
.under
をposition: sticky;
にし、top: 0;
にすることでスクロールしたときに上にくっつきます。.wrapper
の下部が最終的に下部に上がるまでそのセクションを一番下までスクロールし続けないため、height: 200vh;
で非常に高くする必要があります。ラッパーの高さがあるため、空きスペースがたくさんできます。そして次のセクションの.over
にはそのスペースを埋めるために非常に大きな負のマージンを与えます。これで、下のセクションが上にくっついているとき、その下のセクションはその上に上がります。
position: sticky;
は、すべてのブラウザにサポートされています。
参考: position: sticky;のサポート状況
position: sticky;
の使い方については下記をご覧ください。
Apple: スクロールするとコンテンツがズームするエフェクト
これもAppleのプロダクトページでよく使用されている、特にヒーローなどの目立たせたい画像で使用されているエフェクトです。ページを表示すると大きな画像が表示され、スクロールするとズームアウトしたり、またその逆に全体を表示し、注目されたい箇所をズームインするエフェクトです。
How Apple makes those awesome zooming page transitions as you scroll
Code example: https://t.co/DrOlZ8QLoS
Low-code example: https://t.co/tpZglprSZV pic.twitter.com/nBy0XIleVS— Steve (Builder.io) (@Steve8708) June 28, 2022
このエフェクトには、2つのテクニックが使用されています。
1つ目は、position: sticky;
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<section class="top"></section> <section class="wrap"> <img class="zoom" src="image.jpg"> </section> <section class="bottom"></section> <style> .zoom{ position: sticky; top: 20vh; will-change: transform; tranform: scale(2.2); } </style> |
.zoom
にはposition: sticky;
があるので、スクロールすると上にくっついて継続されます。くっついた要素はtranform: scale(2.2);
で拡大されます。
2つ目は、スクロールリスナーとJavaScriptを少し追加し、スクロールに応じてscale
の値を変化させてズームさせています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
const zoom = document.querySelector('.zoom'); const minZoom = 1; const maxZoom = 2; addEventListener('scroll', e => { const vh = window.innerHeight / 100; const scrollTop = document.documentElement.scrollTop; const start = 100 * vh; const stop = 200 * vh; if (scrollTop > start && scrollTop < stop) { const scale = Math.max(2.2 - (scrollTop - start) / 500, 1); zoom.style.transform = `scale(${scale})` } }) |
これで下方向にスクロールにするとズームアウト、上方向にスクロールにするとズームインされます。
Apple: ピュアCSSで実装する美しいハンバーガーメニュー
Appleで使用されているハンバーガーメニューは、ピュアCSSで実装されています。JavaScriptをオフにして試してみてください。
How Apple makes their beautiful hamburger menu in *pure CSS* (no JS!)
<!-- tl;dr -->
<input type="checkbox" ... />
<style>
.checkbox:checked + .menu {
/* animate */
}
</style>More detail 👇 pic.twitter.com/0XldiLPuND
— Steve (Builder.io) (@Steve8708) June 2, 2022
ポイントは、ハンバーガーメニューはチェックボックスで実装されていることです。
1 2 3 4 5 6 |
<input type="checkbox"> <style> .checkbox:checked + .menu { /* animate */ } </style> |
:checked
でチェックした状態のスタイルを設定できます。また+
を使用することで、別の要素に対してスタイルを設定できます。
二本線から×にアニメーションさせるには、下記のように記述します。
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 |
.container.top { transform: translateY(-3px) scaleX(.88235); } .container.bottom { transform: translateY(3px) scaleX(.88235); } input:checked + label .container .line.bottom { transform: rotateZ(45deg); } input:checked + label .container .line.top { transform: rotateZ(-45deg); } input:checked + label .container.bottom { transform: none; } input:checked + label .container.top { transform: none; } input:checked + label .line.bottom { transform: none; transition-delay: 0.1s; } input:checked + label .line.top { transform: none; transition-delay: 0.1s; } .container { transition: transform 0.2s ease-in-out 0.1s; } input:checked + label .container { transition-delay: 0s; } .line { transition: transform 0.2s ease-in-out; } |
※アクセシビリティの観点からこの実装が理想的であるとは言えません。JavaScriptをほんの少し加えた方がよいでしょう。
Apple, Nike: ピュアCSSでタッチフレンドリーなカルーセル
AppleやNikeのカルーセルは、ピュアCSSで実装されています。CSSに一手間加えることで、タッチフレンドリーになっています。
How do Nike and Apple make such smooth and touch friendly carousels with pure CSS?
/* tl;dr */
.carousel {
scroll-snap-type: x mandatory;
}
.carousel .item {
scroll-snap-align: start;
}More detail 👇 pic.twitter.com/eBX7vAJMeA
— Steve (Builder.io) (@Steve8708) May 30, 2022
このカルーセルの特徴はパネルをスクロールした際に、各パネルにスナップすることです。これはデスクトップでもスマホでも機能し、ほんの少しのCSSで実装できます。
1 2 3 4 5 6 |
.carousel { scroll-snap-type: x mandatory; } .carousel .item { scroll-snap-align: start; } |
scroll-snap-type: x mandatory;
のx
はX軸にロックし、mandatory
はユーザーがスクロールを停止するたびにブラウザがスナップポイントにスナップされます。また、scroll-padding: 0 24px;
を加えると、スナップする距離を設定することもできます。
次に、scroll-snap-align: start;
でスナップする場所の内部アイテムを設定します。scroll-snap-align
には、要素のどの部分がコンテナにスナップするかを設定できます。値は「start, center, end」の3つがあります。
scroll-snap
プロパティの使い方については下記をご覧ください。
カルーセルの実装に必要なコードは、下記の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<div class="carousel"> <div class="item"></div> <div class="item"></div> </div> <style> .carousel { scroll-snap-type: x mandatory; scroll-padding: 0 24px; } .carousel .item { scroll-snap-align: start; } </style> |
ボーナスとして、このカルーセルにナビゲーションをつけたい場合は、数行のJavaScriptで実装できます。
Tesla: 美しく滑らかなフルページのスワイプエフェクト
scroll-snap
プロパティは前述のカルーセルだけでなく、セクションに設定しても美しく滑らかなスワイプエフェクトを実装できます。もちろん、JavaScriptは必要ありません。
How does Tesla make that beautifully smooth full page swipe effect on their homepage?
/* tl;dr */
.container {
scroll-snap-type: y mandatory;
}
.section {
scroll-snap-align: start;
scroll-snap-stop: always;
}More detail 👇 pic.twitter.com/sPjWijuMas
— Steve (Builder.io) (@Steve8708) June 3, 2022
まずは、基本のスクロールコンテナを実装します。コンテナを作成し、セクションはビューポートの高さいっぱいに設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<div class="container"> <div class="section"></div> <div class="section"></div> </div> <style> .container { height: 100vh; overflow-y: scroll; } .section { height: 100vh; } </style> |
次に、CSSでスクロールのスナップを設定します。Y軸にロックし、mandatory
はユーザーがスクロールを停止するたびにブラウザがスナップポイントにスナップされます。
1 2 3 4 5 6 7 |
.container { scroll-snap-type: y mandatory; } .section { scroll-snap-align: start; scroll-snap-stop: always; } |
一度に1つのセクションだけを移動するために、scroll-snap-stop: always;
を追加して停止します。これでデスクトップとモバイルデバイスの両方で、ネイティブでスムーズな効果を得ることができます。
Airbnb: 新感覚のスクロール、スワイプアップするドロワー
最後は、Airbnbのスマホでスワイプアップするドロワーです。CSSのかなり巧妙なテクニックが使用されています。
How Airbnb makes that cool swipe up drawer on their mobile site in CSS
Pretty clever trick!
Code example: https://t.co/XLawzyURaV
No-code example: https://t.co/xGx1kPS0zx pic.twitter.com/pX8ic4g711— Steve (Builder.io) (@Steve8708) June 27, 2022
まずは、基本構造。
1 2 3 4 5 6 7 8 9 10 11 12 |
<section class="map"></section> <section class="drawer"></section> <style> .map{ potion: fixed; } .drawer{ position: relative; margin-top: 50vh; } </style> |
このテクニックのポイントは、potion: fixed;
でマップの位置をロックすることです。そしてドロワーにposition: relative;
を設定して、マップの上に持ち上げます。margin-top: 50vh;
で上部の余白を大きくすることで、ページ上部とドロワーの開始位置の間にスペースが生まれます。これにより、ページを単にスクロールするのではなく、ドロワーをスクロールしているような錯覚を引き起こします。
sponsors