CSSの進化がすごすぎる! 2つの画像を比較するスライダーは数行のコードで実装できるようになりました
Post on:2023年11月28日
2つの画像を重ねて表示し、画像を比較できるスライダーを実装するには、今まではJavaScriptのライブラリなどを使用していたかもしれません。
ほんの少しのJavaScriptと、あとはシンプルなHTMLとCSSで2つの画像を比較するスライダーを実装するテクニックを紹介します。
まずは、実際の動作をデモページでご覧ください。縦線のレンジバーをマウスでドラッグすると、2つの画像を比較できます。
See the Pen
Easy comparison slider by coliss (@coliss)
on CodePen.
HTMLはシンプルです。2つの画像をsection
で内包し、縦線のレンジバーをinput type="range"
で実装します。
1 2 3 4 5 6 7 8 9 |
<div class="compare"> <section class="before"> <img src="Runner.svg" alt="" /> </section> <section class="after"> <img src="Roboto.svg" alt="" /> </section> <input type="range" id="range"> </div> |
input type="range"
は、決められた最小値と最大値の間で値を取得できるフォームの要素です。スタイル無しで実装すると、下記の通りです。
2つの画像はCSS Gridで互いに重ね、CSSのmask
でそれぞれの画像を表示します。縦線のレンジバーはいっぱいに伸ばして、スライダー内のどこでも操作できるようにします。
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 |
@layer demo { .compare { display: grid; > * { grid-area: 1 / 1; } > section { display: grid; place-content: center; } } .before { mask: linear-gradient(to right, #000 0, var(--pos, 50%), #0000 0); } .after { mask: linear-gradient(to right, #0000 0, var(--pos, 50%), #000 0); } input[type="range"] { z-index: 1; appearance: none; background: transparent; cursor: pointer; &::-webkit-slider-thumb { appearance: none; width: 4px; height: 100dvh; background-color: CanvasText; } &::-moz-range-thumb { appearance: none; width: 4px; height: 100dvh; background-color: CanvasText; } } } @layer demo.support { * { box-sizing: border-box; margin: 0; } html { block-size: 100%; color-scheme: dark light; } body { min-block-size: 100%; font-family: system-ui, sans-serif; display: grid; } img { max-block-size: 80dvh; max-inline-size: 100%; } } |
画像の切り替えは、JavaScriptで行います。スライダー値をカスタムプロパティに書き込み、それがmask
の--pos
値になります。
1 2 |
range.oninput = () => document.body.style.setProperty('--pos', range.value + '%') |
元ネタは下記ポストより。
Compare Stuff
super simple and effective CSS/HTML/JSsteal this code:https://t.co/b2MR6jLfIY pic.twitter.com/QPxBeZRKoa
— Adam Argyle (@argyleink) November 13, 2023
sponsors