Lism Tips

横にスクロールする列(リール)

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枚ずつぴたっと止まります。

表示例

html
<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)を付けると、端の要素も真ん中まで来られます。

表示例

html
<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)で決めます。

jsx
<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")を並べると、押した番号の要素までスクロールするボタンになります。

表示例

1 2 3
html
<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枚ずつ止まるリールになります。

表示例

html
<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 で作る形は、次のように書きます。

jsx
<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)をもとに、やさしい日本語でまとめています。

ページの一覧