게시일: 2025년 9월 29일
좋아하든 싫어하든 캐러셀은 널리 사용되고 요청되는 패턴입니다. 따라서 캐러셀을 구현할 때는 견고하고 액세스 가능해야 합니다. 첫 페인트에서 상호작용이 가능해야 하고, 유지관리가 더 쉽도록 선언적이어야 하며, 지원 기술로 테스트되는 시맨틱 구조로 빌드해야 합니다.
하지만 캐러셀을 접근 가능하게 만드는 것은 어려운 경우가 많습니다. 포커스를 관리하고, 스크린 리더 알림을 올바르게 가져오고, 화면 밖의 상호작용 요소를 처리하는 것은 복잡하므로 많은 사이트의 캐러셀에 액세스할 수 없습니다. 이러한 문제로 인해 Chrome팀은 Chrome 135에서 출시된 CSS 오버플로 모듈 레벨 5의 일환으로 대화형 CSS 캐러셀을 개발했습니다.
Chrome에서 이 기능을 처음 출시한 후 커뮤니티에서 많은 의견을 보내주셨고, Google에서는 이러한 의견을 해결하기 위해 노력해 왔습니다. 여기에는 개별 및 탐색 스크롤 마커 모드 지원과 같은 새로운 기능과 여러 버그 수정이 포함됩니다. 예를 들면 다음과 같습니다.
- Chrome 140에 도입된 대체 텍스트의 카운터 지원
- 사용 중지된
::scroll-button state
이 스크린 리더에서 올바르게 읽히지 않는 문제 수정 ::scroll-marker
이 콘텐츠 값에서 ARIA 라벨 이름을 가져오도록 보장- 모든
::scroll-marker
가상 요소가 '선택됨'으로 읽히는 버그를 수정했습니다.
CSS Overflow 5의 기능을 사용하면 첫 페인트에서 상호작용이 가능한 강력하고 접근성 높은 캐러셀을 만들 수 있습니다. 이 게시물에서는 이러한 기능을 사용하여 오랫동안 해결되지 않은 접근성 문제를 해결하는 방법에 중점을 두고 이를 수행하는 방법을 안내합니다.
일반적인 캐러셀 소개는 CSS를 사용한 캐러셀 도움말을 참고하세요. UI가 기본적으로 접근 가능하다고 보장할 수는 없습니다. 항상 페이지의 접근성을 테스트해야 합니다.
어떤 유형의 캐러셀이 필요하신가요?
코드로 바로 들어가기 전에 어떤 종류의 캐러셀을 빌드하는지 알아야 합니다. 올바른 접근성 전략은 사용자가 콘텐츠를 경험하는 방식에 따라 달라집니다. 이 게시물에서는 다음 세 가지 일반적인 유형을 다룹니다.
단일 항목 캐러셀
단일 항목 캐러셀에서는 한 번에 하나의 슬라이드만 완전히 표시되고 상호작용할 수 있습니다 (예: 히어로 배너 또는 슬라이드쇼).
자동으로 페이지가 매겨진 캐러셀
자동으로 페이지가 매겨진 캐러셀에는 제품 목록이나 TV 프로그램과 같은 콘텐츠 '페이지'가 표시됩니다.
다중 항목 캐러셀
여러 항목 캐러셀에서는 캐러셀의 여러 항목이 한 번에 표시되지만, 페이지로 나누지 않고도 개별적으로 스크롤할 수 있습니다.
각 유형의 캐러셀에는 접근성 고려사항과 권장사항이 다릅니다.
단일 항목 캐러셀
클래식 슬라이드쇼입니다. 한 번에 하나의 하위 요소만 읽도록 되어 있지만, 많은 경우 사용자는 추가 콘텐츠에 관한 맥락적 단서를 제공하기 위해 다음 또는 이전 항목의 '엿보기'를 보게 됩니다. 목표는 중앙에 있고 완전히 표시된 슬라이드만 상호작용할 수 있도록 하는 것입니다.
접근성을 높이는 방법은 다음과 같습니다.
1단계: 스크롤 스냅으로 단일 포커스 적용
스크롤 컨테이너가 항상 슬라이드로 '스냅'되어 항목이 어색하게 중간에 끼지 않도록 하려면 CSS 스크롤 스냅을 사용하세요. 이렇게 하면 스크롤 후 항목이 올바른 위치에 완벽하게 '스냅'되어 깔끔한 사용자 환경이 만들어집니다.
.carousel {
scroll-snap-type: inline mandatory;
}
.item {
scroll-snap-align: center;
}
2단계: 캐러셀 및 슬라이드 변경사항 알리기
스크린 리더를 사용하는 사용자는 캐러셀에 진입했는지와 슬라이드가 변경되는 시점을 알아야 합니다. 이를 위해서는 캐러셀 컨테이너에 몇 가지 ARIA 속성이 필요합니다.
ARIA 속성 |
설명 |
---|---|
role="region" |
캐러셀을 페이지의 랜드마크 영역으로 식별하여 더 쉽게 탐색할 수 있습니다. |
aria-label |
리전에 '추천 제품 슬라이드쇼'와 같이 설명이 포함된 이름을 지정합니다. |
aria-live="polite" |
이것이 마법의 재료입니다. 사용자를 방해하지 않고 새 슬라이드가 뷰로 스크롤되는 경우와 같이 이 영역 내의 변경사항을 정중하게 알리도록 스크린 리더에 지시합니다. |
HTML 구조는 다음과 같습니다.
<div class="carousel" role="region" aria-label="Slideshow" aria-live="polite"> ... </div>
3단계: 표시되는 슬라이드만 대화형으로 만들기
이는 사용자가 화면에 표시되지 않는 슬라이드의 버튼이나 링크로 실수로 탭하는 것을 방지하므로 접근성에 매우 중요합니다. 이렇게 하려면 새로운 scroll-state
컨테이너 쿼리와 interactivity
속성을 사용하세요.
먼저 interactivity: inert
를 사용하여 모든 슬라이드 항목을 기본적으로 비활성 상태로 만듭니다.
그런 다음 scroll-state
컨테이너 쿼리를 사용하여 현재 표시 영역에서 '스냅'된 슬라이드를 타겟팅하고 콘텐츠를 interactivity: auto
로 설정합니다.
.item {
container-type: scroll-state;
}
/* Make all content inside slides inert by default */
.item > * {
interactivity: inert;
/* When a slide is snapped inline, make its content interactive */
@container scroll-state(snapped: inline) {
> .content {
interactivity: auto;
}
}
}
이 CSS를 사용하면 브라우저에서 포커스 가능한 항목을 자동으로 처리합니다. tabindex를 관리하는 데 더 이상 JavaScript가 필요하지 않습니다. scroll-state
쿼리는 현재 슬라이드를 제외한 모든 슬라이드를 비활성 상태로 만듭니다.
페이지로 나눈 캐러셀
이 패턴은 콘텐츠가 페이지로 그룹화된 제품 또는 선택사항 갤러리에 자주 사용됩니다. 콘텐츠를 표시하는 방법에 따라 접근성을 두 가지 방식으로 처리할 수 있습니다.
개별 페이지가 있는 캐러셀
내부에 role="tabpanel"
이 있는 단일 요소와 함께 role="region"
이 있는 컨테이너를 사용합니다.
이 탭 패널은 활성 탭 또는 페이지를 반영하도록 콘텐츠를 업데이트합니다.
<div role="region" class="carousel" aria-label="Featured Products Carousel">
<div role="tabpanel">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
...
<div class="item">Item n</div> </div>
</div>
</div>
상호작용을 관리하려면 view()
타임라인에 연결된 스마트 애니메이션 트릭을 사용하세요. 이렇게 하면 탭 순서가 화면에 현재 표시된 항목에만 도달합니다.
@keyframes interactive-when-visible {
0% { interactivity: auto; }
}
.item {
interactivity: inert;
animation: interactive-when-visible steps(1);
animation-timeline: view(inline);
}
콘텐츠 목록
콘텐츠가 기본적으로 목록인 경우 올바른 시맨틱을 위해 <ul>
요소를 사용합니다.
예를 들면 다음과 같습니다.
<div class="carousel" role="region" aria-label="Related Posts">
<ul>
<li><!-- Post 1 content --></li>
<li><!-- Post 2 content --></li>
<li><!-- Post 3 content --></li>
<!-- ... -->
</ul>
</div>
이 패턴에서는 화면에 표시되지 않는 콘텐츠를 비활성 상태로 만들기 위해 상호작용 속성을 사용하지 마세요. 이렇게 하면 스크린 리더에서 알리는 항목 수에 영향을 미치므로 모든 콘텐츠는 접근성 트리에 남아 있어야 합니다.
다중 항목 캐러셀
이 패턴은 여러 하위 요소가 동시에 표시되고 읽을 수 있는 캐러셀에 사용됩니다. 예를 들어 전자상거래 사이트의 '관련 제품' 섹션이 있습니다.
이러한 캐러셀은 다음 결정에 대한 대답에 따라 다르게 작동합니다. 사용자의 포커스를 한 번에 하나의 항목으로 안내하시겠어요? 아니면 표시되는 모든 콘텐츠에 자유롭게 액세스하도록 허용하시겠어요?
패턴 1: 표시된 항목 중 하나의 상호작용 항목
이 모델에서는 여러 항목이 표시되지만 기본 항목 또는 '현재' 항목만 상호작용이 가능합니다. 다른 표시된 항목은 비활성 상태입니다. 이 패턴은 사용자에게 일련의 항목을 하나씩 안내하는 데 유용합니다.
이를 올바르게 빌드하려면 앞에서 설명한 단일 항목 캐러셀과 동일한 접근성 패턴을 사용해야 합니다. 여기에는 다음 항목이 포함됩니다.
- 스크롤 상태 컨테이너 쿼리를 사용하여 비활성 항목에 상호작용을 적용합니다.
- 모든 항목이 기본 위치 (예: 스크롤포트의 중앙)에 스냅될 수 있도록 항목 주위에 충분한 패딩을 추가합니다. 이렇게 하면 하나씩 탐색 모델이 의도적이고 부드럽게 느껴집니다.
패턴 2: 표시된 모든 항목이 상호작용 가능함
사용자가 표시된 모든 항목과 자유롭게 상호작용할 수 있도록 하는 것이 목표라면 콘텐츠가 비활성 상태가 되지 않도록 하는 것이 좋습니다.
이 패턴의 경우:
- 콘텐츠가 의미상 목록인 경우
<ul>
요소를 사용하세요. 스크린 리더 사용자에게 올바른 컨텍스트를 제공하기 때문입니다. - 상호작용 관리 (
interactivity: inert
)를 사용하지 마세요. 모든 표시 콘텐츠는 접근성 트리에 남아 있어야 하며 키보드 탭을 사용하여 도달할 수 있어야 합니다.
요약
CSS Overflow 5를 사용하면 접근성 문제가 적은 일반적인 양방향 캐러셀 패턴을 선언적으로 빌드할 수 있습니다. 시맨틱 HTML, 스크롤 상태 및 상호작용과 같은 최신 CSS, 적절한 ARIA 역할을 결합하면 첫 페인트에서 상호작용이 가능하며 성능이 우수하고 접근성이 높은 환경을 만들 수 있습니다.
이 새로운 API를 사용해 보세요. 이러한 패턴과 API는 대화형의 빠르고 액세스 가능한 구성요소를 더 쉽게 빌드할 수 있도록 설계되었지만, 전체 접근성 테스트를 대체할 수는 없습니다. 코드에 액세스할 수 있는지 항상 확인하고 기준선 타겟에 맞게 작동하는지 확인해야 합니다.