scroll-margin-bottom
요소가 스크롤되어 화면에 들어올 때, 요소의 아래쪽에 확보할 여백을 지정합니다. 고정 푸터나 모바일 액션 바가 스크롤 대상을 가리는 문제를 해결하는 데 주로 쓰이며, 요소의 실제 레이아웃에는 아무 영향도 주지 않습니다.
클래스 목록
패턴: smb{값}{단위}
| 클래스 | CSS | 설명 |
|---|---|---|
smb0 | scroll-margin-bottom: 0 | 스크롤 여백 없음 |
smb8px | scroll-margin-bottom: 8px | 8px 여백 |
smb16px | scroll-margin-bottom: 16px | 16px 여백 |
smb2rem | scroll-margin-bottom: 2rem | 20px 여백 |
smb4rem | scroll-margin-bottom: 4rem | 40px 여백 |
라이브 데모
버튼을 누르면 컨테이너를 맨 아래로 보낸 뒤 파란 블록을 아래 정렬로 스크롤해 옵니다. 클래스에 따라 블록이 아래 가장자리에서 얼마나 떨어져 멈추는지 비교해 보세요.
smb0이면 블록이 컨테이너 안쪽 아래 모서리에 딱 붙고, smb4rem이면 40px 위에서 멈춥니다. 블록의 크기나 위치 자체는 전혀 변하지 않습니다.
클래스별 상세
smb0scroll-margin-bottom: 0
스크롤 여백을 0으로 되돌립니다. 공통 레이아웃에서 푸터 보정값이 걸려 있는데 특정 블록만 화면 아래 끝까지 붙여야 할 때 사용합니다.
<!-- Reset an inherited offset for one row -->
<div class="sstym oya h40rem">
<div class="ssae smb2rem h20rem">Row 1</div>
<div class="ssae smb0 h20rem">Flush against the bottom edge</div>
</div>smb8pxscroll-margin-bottom: 8px
8px. 테두리나 포커스 링이 아래 모서리에서 잘리지 않을 정도의 최소 여백입니다. 촘촘한 목록 항목에 적합합니다.
<!-- Message list: keep the focus ring off the bottom edge -->
<div class="oya h40rem df fdc gap8px">
<article class="smb8px p16px br8px">Message 1</article>
<article class="smb8px p16px br8px">Message 2</article>
</div>smb16pxscroll-margin-bottom: 16px
16px. 항목 간격을 16px로 잡은 세로 피드에서 아래 정렬 시 여백을 목록 리듬과 맞춥니다.
<!-- Vertical snap feed with a 16px rhythm -->
<div class="sstym oya h40rem df fdc gap16px">
<section class="ssae smb16px h30rem">Post 1</section>
<section class="ssae smb16px h30rem">Post 2</section>
</div>smb2remscroll-margin-bottom: 2rem
20px. 입력 필드 아래에 나타나는 검증 메시지나 도움말 텍스트가 함께 보이도록 자리를 확보합니다.
<!-- Reserve room for the helper text under a validated field -->
<form class="oya h40rem">
<div class="smb2rem">
<label for="email">Email</label>
<input id="email" class="w100p p12px">
<p class="fs12px cEF4444">Enter a valid address</p>
</div>
</form>smb4remscroll-margin-bottom: 4rem
40px. 높이 40px짜리 고정 푸터, 모바일 하단 액션 바, 쿠키 배너가 스크롤 대상을 가리지 않게 하는 대표적인 값입니다.
<!-- Clear a 40px fixed footer / mobile action bar -->
<article id="terms" class="smb4rem p2rem">
<h2>Terms</h2>
<p>Long text...</p>
</article>
<footer class="pf b0 l0 w100p h4rem df jcc aic bg18181B">
<button class="py12px px2rem br8px bn bg6366F1 cFFFFFF">Agree</button>
</footer>사용 예시
<!-- Correct scroll target when a fixed footer exists -->
<section id="bottom-section" class="smb4rem">
<p>The bottom offset keeps it above the 40px fixed footer</p>
</section>
<!-- Bottom margin in vertical scroll snap -->
<div class="ssae smb2rem bg18181B p2rem br8px">
Reserve extra space below the snap point
</div>실전 예시: 채팅 입력창이 있는 대화창
메시지를 보낸 뒤 새 말풍선으로 스크롤할 때, 하단에 고정된 입력창 높이만큼 여백을 확보하지 않으면 방금 보낸 메시지가 입력창 뒤에 숨습니다.
<!-- Chat window: after sending, scroll the new message into view so it
lands above the composer instead of behind it -->
<div class="df fdc h100vh">
<div id="log" class="obc oya swt fg1 p16px df fdc gap12px">
<article class="p12px br8px bg18181B">Hi there</article>
<article id="last" class="smb4rem p12px br8px bg6366F1 cFFFFFF">
Just sent this one
</article>
</div>
<!-- 40px tall composer pinned to the bottom -->
<form class="h4rem df aic gap8px px16px bt1pxsolid27272A">
<input class="fg1 p12px br8px bg0F0F17 bn cFAFAFA">
<button class="py8px px16px br8px bn bg6366F1 cFFFFFF cp">Send</button>
</form>
</div>
<script>
document.getElementById('last')
.scrollIntoView({ behavior: 'smooth', block: 'end' });
</script>주의사항
스크롤로 들어올 때만 의미가 있습니다
scroll-margin은 앵커 이동, scrollIntoView, 스크롤 스냅처럼 브라우저가 요소를 화면에 맞춰 줄 때만 계산됩니다. 사용자가 직접 스크롤할 때나 일반 레이아웃에는 아무 영향이 없습니다.
아래 정렬일 때만 보입니다
아래쪽 여백은 요소를 아래 기준으로 맞출 때만 반영됩니다. 위 정렬로 스크롤한다면 scroll-margin-top이 필요한 상황입니다. 고정 헤더와 고정 푸터가 모두 있다면 위아래 값을 같이 지정하세요.
값은 실제 푸터 높이와 맞추세요
여백이 푸터보다 작으면 여전히 가려지고, 지나치게 크면 대상이 화면 한가운데 떠 버립니다. 푸터 높이가 자주 바뀐다면 컨테이너 쪽 scroll-padding-bottom으로 한 곳에서 관리하는 편이 낫습니다.