scroll-padding-left

스크롤 컨테이너 안쪽 왼쪽에 스크롤 전용 여백을 만듭니다. 그 컨테이너 안의 모든 요소가 스크롤되어 들어올 때 왼쪽 가장자리에서 그만큼 떨어져 멈춥니다. 실제 패딩과 달리 레이아웃은 전혀 바뀌지 않습니다.

클래스 목록

패턴: spl{값}{단위}

클래스CSS설명
spl0scroll-padding-left: 0스크롤 패딩 없음
spl8pxscroll-padding-left: 8px8px 패딩
spl16pxscroll-padding-left: 16px16px 패딩
spl2remscroll-padding-left: 2rem20px 패딩
spl4remscroll-padding-left: 4rem40px 패딩

라이브 데모

이번에는 클래스가 카드가 아니라 컨테이너에 붙습니다. 버튼을 누르면 컨테이너를 처음으로 되돌린 뒤 파란 카드를 왼쪽 정렬로 스크롤해 옵니다. 값이 커질수록 왼쪽에 더 넓은 자리가 남습니다.

1
2
3
4
5
6
대상 카드
8
9
10
11
12
13
14

카드마다 클래스를 붙이지 않아도 컨테이너 값 하나로 모든 항목의 정지 위치가 함께 조정됩니다. 컨테이너의 실제 패딩은 그대로이므로 카드가 밀려나거나 잘리지 않습니다.

클래스별 상세

spl0scroll-padding-left: 0

스크롤 패딩을 0으로 되돌립니다. 상위 컴포넌트나 공통 클래스에서 지정된 여백을 특정 스크롤 영역에서만 없앨 때 사용합니다.

<!-- Explicit default: snapped cards line up with the container edge -->
<div class="spl0 sstxm df oxa gap16px">
  <div class="ssas fs0 w28rem">Card 1</div>
  <div class="ssas fs0 w28rem">Card 2</div>
</div>

spl8pxscroll-padding-left: 8px

8px. 테두리와 포커스 링이 잘리지 않을 최소 여백입니다. 필터 칩 바처럼 작은 항목이 촘촘히 놓인 가로 스크롤에 적합합니다.

<!-- Chip filter bar: a hair of inset so borders are never clipped -->
<div class="spl8px sstxm df oxa gap8px py8px">
  <button class="ssas fs0 py8px px16px br999px">All</button>
  <button class="ssas fs0 py8px px16px br999px">New</button>
</div>

spl16pxscroll-padding-left: 16px

16px. 카드 간격이 16px인 캐러셀에서 항목마다 scroll-margin을 반복하지 않고 컨테이너 한 곳에서 같은 여백을 줍니다.

<!-- Every card gets a 16px inset without repeating a class per card -->
<div class="spl16px sstxm df oxa gap16px">
  <article class="ssas fs0 w28rem">Card 1</article>
  <article class="ssas fs0 w28rem">Card 2</article>
  <article class="ssas fs0 w28rem">Card 3</article>
</div>

spl2remscroll-padding-left: 2rem

20px. 섹션 좌우 패딩이 20px인 레이아웃에서, 스냅된 카드의 왼쪽 선을 섹션 제목의 시작선과 맞춥니다.

<!-- Align snapped cards with the section heading above the scroller -->
<section class="px2rem">
  <h2>Continue watching</h2>
  <div class="spl2rem sstxm df oxa gap16px">
    <article class="ssas fs0 w28rem">Item 1</article>
    <article class="ssas fs0 w28rem">Item 2</article>
  </div>
</section>

spl4remscroll-padding-left: 4rem

40px. 스크롤 영역 위에 40px짜리 아이콘 레일이나 고정 사이드바가 겹쳐 있을 때, 모든 스냅 위치를 그만큼 안쪽으로 밀어 가려짐을 방지합니다.

<!-- A 40px icon rail overlaps the scroller: inset every snap position -->
<div class="pr">
  <nav class="pa t0 l0 w4rem h100p bg18181B"></nav>
  <div class="spl4rem sstxm df oxa gap16px pl4rem">
    <article class="ssas fs0 w28rem">Card 1</article>
    <article class="ssas fs0 w28rem">Card 2</article>
  </div>
</div>

사용 예시

<!-- Horizontal scroller behind a fixed sidebar -->
<aside class="pf t0 l0 w25rem h100vh bg18181B">Sidebar</aside>

<div class="spl4rem sstxm df oxa gap16px">
  <div class="ssas fs0 w28rem bg18181B p2rem br8px">Card 1</div>
  <div class="ssas fs0 w28rem bg18181B p2rem br8px">Card 2</div>
</div>

실전 예시: 스트리밍 UI의 가로 미디어 행

타일마다 scroll-margin을 붙이는 대신 컨테이너에 scroll-padding을 한 번 지정한 구성입니다. 키보드 포커스 이동과 앵커 점프에도 같은 여백이 적용됩니다.

<!-- Media row in a streaming UI. One scroll-padding on the container
     replaces a scroll-margin class on every single tile, and the same
     inset applies to keyboard focus and to anchor jumps. -->
<section class="px2rem py2rem">
  <h2 class="fs2rem fw700 cFAFAFA mb16px">Trending now</h2>

  <div class="spl2rem spr2rem sstxm obxc swn df oxa gap12px">
    <a href="#t1" id="t1" class="ssas fs0 w28rem br8px oh bg18181B tdn">
      <img src="/poster-1.jpg" alt="" class="w100p h16rem ofc">
      <p class="p12px fs14px cFAFAFA">Title 1</p>
    </a>
    <a href="#t2" id="t2" class="ssas fs0 w28rem br8px oh bg18181B tdn">
      <img src="/poster-2.jpg" alt="" class="w100p h16rem ofc">
      <p class="p12px fs14px cFAFAFA">Title 2</p>
    </a>
  </div>
</section>

주의사항

레이아웃 패딩이 아닙니다

scroll-padding은 스크롤 정지 위치를 계산할 때만 쓰이는 가상의 여백입니다. 실제로 콘텐츠를 밀어내고 싶다면 pl2rem 같은 일반 padding 클래스를 함께 써야 합니다.

컨테이너에만 적용됩니다

스크롤이 실제로 일어나는 요소, 즉 oxa 같은 overflow가 걸린 요소에 붙여야 합니다. 자식 카드에 붙이면 아무 효과가 없고, 그 경우 필요한 것은 scroll-margin-left입니다.

스크롤로 들어올 때만 계산됩니다

앵커 이동, scrollIntoView, 스크롤 스냅에서만 반영됩니다. 사용자가 손으로 스크롤할 때는 아무 제한도 걸리지 않습니다.