横にスクロールする列(リール)
has--snap と -ov:auto を使って、画像などを横にスクロールして見せる列(リール)を作る例です。Flex と Grid の2通りがあります。
リールは、画像やカードを横一列に並べ、指やスクロールで横に送って見る形です。並べた要素が画面からはみ出した分を、横のスクロールで見せます。Lism では、has--snap(スクロールで止まる位置)と、はみ出しをスクロールにする -ov:auto を組み合わせて作ります。
どんなときに使う?#
- 写真や商品のカードを、横に送りながら見せたいとき
- スマートフォンでは横に送る形、広い画面では普通に並べる形にしたいとき
Flex で作る#
l--flex の箱に has--snap -ov:auto を付けます。-ov は overflow(はみ出したときの扱い)の略です。中の要素には -fxsh:0(flex-shrink: 0。縮めない)と幅を付けて、はみ出すようにします。横にスクロールすると、1枚ずつぴたっと止まります。
表示例
<div class="l--flex has--snap -ov:auto -bgc -p:20 -g:20 -bdrs:30" style="--bgc: var(--black)">
<div class="l--frame -ar:16/9 -bdrs:20 -fxsh:0 -w" style="--w: 90%"><img src="/img/sample-landscape.svg" alt="" /></div>
<div class="l--frame -ar:16/9 -bdrs:20 -fxsh:0 -w" style="--w: 90%"><img src="/img/sample-landscape.svg" alt="" /></div>
<div class="l--frame -ar:16/9 -bdrs:20 -fxsh:0 -w" style="--w: 90%"><img src="/img/sample-landscape.svg" alt="" /></div>
</div>
幅を 90% にすると、次の1枚が少しだけ見えるので、「横に続きがある」と分かりやすくなります。
止まる位置を真ん中にする#
has--snap の変数 --snapAlign に center を入れると、要素が箱の真ん中で止まります。最初と最後の要素に外側の余白(-ms・-me)を付けると、端の要素も真ん中まで来られます。
表示例
<div class="l--flex has--snap -ov:auto -g:20 -p:15 -bgc -bdrs:20" style="--snapAlign: center; --bgc: var(--black)">
<div class="l--frame -ar:16/9 -fxsh:0 -w -ms -bdrs:20" style="--w: 80%; --ms: 10%"><img src="/img/sample-landscape.svg" alt="" /></div>
<div class="l--frame -ar:16/9 -fxsh:0 -w -bdrs:20" style="--w: 80%"><img src="/img/sample-landscape.svg" alt="" /></div>
<div class="l--frame -ar:16/9 -fxsh:0 -w -me -bdrs:20" style="--w: 80%; --me: 10%"><img src="/img/sample-landscape.svg" alt="" /></div>
</div>
has--snap が持つ変数は次の3つです。
| 変数 | 既定値 | 意味 |
|---|---|---|
--snapType |
both mandatory |
止まり方(scroll-snap-type) |
--snapAlign |
start |
子の要素のどこで止まるか(scroll-snap-align) |
--snapStop |
normal |
速く送ったとき途中で止まるか(scroll-snap-stop) |
Grid で作る#
l--grid でも作れます。-gaf:column で、要素を横の向きに足していくようにします(-gaf は grid-auto-flow の略)。1つの列の幅は grid-auto-columns(React では gac)で決めます。
<Grid hasSnap ov="auto" gaf="column" gac="100%" g="20" bdrs="20" tabIndex="0">
<Frame ar="16/9" bdrs="20"><img src="/img/sample-landscape.svg" alt="" /></Frame>
<Frame ar="16/9" bdrs="20"><img src="/img/sample-landscape.svg" alt="" /></Frame>
</Grid>
gac は、画面の幅で値を切り替える書き方に対応していません。幅ごとに変えたいときは、gac="var(--cols)" として、切り替えに対応した cols に値を渡します(例:cols={['70%', '40%']})。
広い画面ではリールをやめたいときは、gaf を row に戻します。たとえば gaf={['column', null, 'row']} と gtc={[null, null, 'repeat(2, 1fr)']} を組み合わせると、広い画面では2列に並びます(gtc は grid-template-columns)。
番号のボタンで送る#
リールの各要素に id を付け、その id へのリンク(href="#id")を並べると、押した番号の要素までスクロールするボタンになります。
表示例
<div class="l--flex has--snap -ov:auto -g:15 -bdrs:20">
<div id="demo-reel-1" class="l--frame -ar:16/9 -fxsh:0 -w -bdrs:20" style="--w: 75%"><img src="/img/sample-landscape.svg" alt="" /></div>
<div id="demo-reel-2" class="l--frame -ar:16/9 -fxsh:0 -w -bdrs:20" style="--w: 75%"><img src="/img/sample-landscape.svg" alt="" /></div>
<div id="demo-reel-3" class="l--frame -ar:16/9 -fxsh:0 -w -bdrs:20" style="--w: 75%"><img src="/img/sample-landscape.svg" alt="" /></div>
</div>
<div class="l--flex -g:15 -jc:center -hl:0 -mbs:15">
<a class="l--center -c:inherit -bgc:base-2 -w -h -bdrs:10 -td:none -hov:-o" style="--w: 2em; --h: 2em" href="#demo-reel-1">1</a>
<a class="l--center -c:inherit -bgc:base-2 -w -h -bdrs:10 -td:none -hov:-o" style="--w: 2em; --h: 2em" href="#demo-reel-2">2</a>
<a class="l--center -c:inherit -bgc:base-2 -w -h -bdrs:10 -td:none -hov:-o" style="--w: 2em; --h: 2em" href="#demo-reel-3">3</a>
</div>
React の例では、リールの箱の style に scrollBehavior: 'smooth' も入れて、なめらかに送っています。
縦向きのリール#
縦長の比率(3/4)を付けた箱に has--snap -ov:auto を付け、同じ比率の画像を縦に積むと、縦にスクロールして1枚ずつ止まるリールになります。
表示例
<div class="-max-w -mx:auto" style="--max-w: 12rem">
<div class="has--snap -ov:auto -ar -bdrs:20 -bgc" style="--ar: 3/4; --bgc: var(--black)">
<div class="l--frame -ar" style="--ar: 3/4"><img src="/img/sample-portrait.svg" alt="" /></div>
<div class="l--frame -ar" style="--ar: 3/4"><img src="/img/sample-portrait.svg" alt="" /></div>
<div class="l--frame -ar" style="--ar: 3/4"><img src="/img/sample-portrait.svg" alt="" /></div>
</div>
</div>
React・Astro で書く場合#
Flex で作る形は、次のように書きます。
<Flex hasSnap ov="auto" bgc="black" p="20" g="20" bdrs="30" style={{ scrollPadding: 'var(--p)' }}>
<Frame ar="16/9" bdrs="20" fxsh="0" w="90%">
<img src="/img/sample-landscape.svg" alt="" />
</Frame>
<Frame ar="16/9" bdrs="20" fxsh="0" w="90%">
<img src="/img/sample-landscape.svg" alt="" />
</Frame>
</Flex>
scrollPadding: 'var(--p)' は、止まる位置を箱の内側の余白の分だけずらす指定です。幅を画面ごとに変えるときは w={['80%', '60%']} のように配列で渡します。
関連するページ#
公式ドキュメント
2026年10月5日時点の内容(lism-css 1.0.1・@lism-css/ui 0.40.1)をもとに、やさしい日本語でまとめています。