Chrome135+ 에서 CSS로 캐러셀 만들기
캐러셀이란?
캐러셀은 여러개의 컨텐츠를 슬라이드 형태로 보여주는 UI 요소입니다.
캐러셀은 보통 자동으로 슬라이드되거나 드래그를 통해 컨텐츠를 이동하지만,
좌우 버튼이나 페이지네이션을 포함하여 특정 컨텐츠로 이동할 수도 있습니다.
기존에도 javascript 없이 캐러셀을 구현할 수 있지만,
좌우 버튼이나 페이지네이션을 포함시킬 수는 없었습니다.
Chrome 135부터는 CSS Overflow Module Level 5을 사용하여
css만으로 좌우 버튼과 페이지네이션을 포함하는 캐러셀을 구현할 수 있습니다.
이 포스트에서는 이 기능을 사용하여 캐러셀을 구현하는 방법을 소개합니다.
캐러셀 예제
CSS Carousel Gallery 에서는 CSS로 만든 다양한 캐러셀 예제를 확인할 수 있습니다.
캐러셀 만들기
우선, 기본적인 형태의 캐러셀을 만들어 보겠습니다.
html
<div class="scroll-layout">
<ul class="carousel">
<li class="carousel-item"></li>
<li class="carousel-item"></li>
<li class="carousel-item"></li>
<li class="carousel-item"></li>
<li class="carousel-item"></li>
<li class="carousel-item"></li>
<li class="carousel-item"></li>
<li class="carousel-item"></li>
<li class="carousel-item"></li>
<li class="carousel-item"></li>
</ul>
</div>
css
li {
list-style-type: none;
}
.scroll-layout {
width: 100vw;
display: flex;
justify-content: center;
}
.carousel {
width: 80%;
display: grid;
grid: 30vmin / auto-flow 40%;
gap: 15px;
padding: 0;
margin: 0;
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
scrollbar-width: none;
}
.carousel-item {
border: 3px solid #888;
scroll-snap-align: center;
}
좌우 버튼 추가하기
::scroll-button
의사 요소를 이용해 캐러셀에 좌우 버튼을 추가할 수 있습니다.
css
.carousel {
anchor-name: --carousel;
&::scroll-button(*) {
position: fixed;
position-anchor: --carousel;
width: 48px;
height: 48px;
border-radius: 50%;
border: 2px solid #999;
margin: 5px;
}
&::scroll-button(left) {
position-area: inline-start center;
content: "⬅" / "Scroll Left";
}
&::scroll-button(right) {
position-area: inline-end center;
content: "⮕" / "Scroll Right";
}
}
좌우 버튼은 기본적으로 스크롤 영역의 85% 를 스크롤합니다.
하나의 컨텐츠씩 스크롤하려면 아래와 같이 설정합니다.
css
.carousel-item {
scroll-snap-stop: always;
}
페이지네이션 추가하기
::scroll-marker-group
의사 요소와
::scroll-marker
의사 요소를 이용해 페이지네이션을 추가할 수 있습니다.
css
.carousel {
scroll-marker-group: after;
&::scroll-marker-group {
position: fixed;
position-anchor: --carousel;
position-area: block-end;
display: grid;
place-content: safe center;
grid: 16px / auto-flow 16px;
gap: 15px;
padding: 15px;
}
}
.carousel-item {
&::scroll-marker {
content: " ";
border: 1px solid #bbb;
border-radius: 50%;
outline-offset: 4px;
}
&::scroll-marker:is(:hover, :focus-visible) {
border-color: LinkText;
}
&::scroll-marker:target-current {
background: LinkText;
border-color: LinkText;
}
}