π μ»΄ν¬λνΈ μ 보
- μ»΄ν¬λνΈ μ΄λ¦: Carousel
- μ»΄ν¬λνΈ μ€λͺ
: μΊλ¬μ
μ μ½ν
μΈ λ₯Ό μννλ©° νμνλ μ»΄ν¬λνΈλ‘, μ¬μ©μκ° μ΄μ /λ€μ νλͺ©μΌλ‘ μ΄λνκ±°λ νΉμ νλͺ©μ μ νν μ μμ
- μ¬μ© μ¬λ‘: μ ν μ΄λ―Έμ§, νλ‘λͺ¨μ
λ°°λ, μΆμ² μν λ±μ μννλ©° νμν λ μ¬μ©
π μ°Έμ‘° λ° λ νΌλ°μ€
- ARIA Authoring Practices: W3C ARIA Carousel Pattern
- μλ νμ μ μ§, μ΄μ /λ€μ 컨νΈλ‘€, μ¬λΌμ΄λ μ ν λ±μ μ κ·Όμ± κ³ λ €μ¬ν μ μ
- κΈ°ν λ νΌλ°μ€: Ant Design μΊλ¬μ
μ»΄ν¬λνΈ λΆμ
π μ κ·Όμ± λ° ARIA μ μ© μ¬λΆ
- ARIA Pattern μ μ©: ARIA Carousel Pattern
- μ¬μ©λ ARIA μμ±:
aria-roledescription="carousel", aria-label, aria-live="off"(μλ νμ μ) λλ aria-live="polite"(μλ νμ μ€μ§ μ), aria-controls, aria-selected λ±μ΄ μ¬μ©λ¨.
- μ κ·Όμ± κ΄λ ¨ κ³ λ €μ¬ν:
- ν€λ³΄λ μ΄μ μ΄ carousel λ΄λΆμ μ§μ
νλ©΄ μλ νμ μ μ§
- μ΄μ /λ€μ 컨νΈλ‘€μ ν€λ³΄λλ‘ μ‘°μ κ°λ₯ν΄μΌ ν¨
- μλ νμ μμλ
aria-live="off"λ₯Ό μ¬μ©νμ¬ λΆνμν μ
λ°μ΄νΈ μλ¦Ό λ°©μ§
- μλ νμ μ΄ μ€μ§λ μνμμλ
aria-live="polite"λ₯Ό μ¬μ©νμ¬ μ¬λΌμ΄λ λ³κ²½ μ¬ν μλ¦Ό
- μ¬λΌμ΄λ λ³κ²½ μ μ΄μ μ μ μ§νμ¬ μ€ν¬λ¦° 리λ μ¬μ©μκ° μ»¨ν
μ€νΈλ₯Ό μμ§ μλλ‘ ν¨
- μ κ·Όμ± κΈ°λ₯ μμ½:
- μλ νμ μ μ΄, μ΄μ /λ€μ λ° νΉμ μ¬λΌμ΄λλ‘ μ΄λ, νμ¬ μ¬λΌμ΄λ μν μ 보 μ 곡 λ±μ κΈ°λ₯μ ν΅ν΄ μ κ·Όμ± ν₯μ
ποΈ λ§ν¬μ
ꡬ쑰 λΆμ
- HTML μλ§¨ν± νκ·Έ μ¬μ©:
- W3C Example:
<section> νκ·Έλ‘ carousel μ»΄ν¬λνΈ μμ νμ
<div> νκ·Έμ ARIA μν (role)μ μ¬μ©νμ¬ μ¬λΌμ΄λ λͺ©λ‘κ³Ό 컨νΈλ‘€ μμ ꡬλΆ
- Ant Design Example:
<div> νκ·Έλ₯Ό μ¬μ©νμ¬ μ 체 carousel μ»΄ν¬λνΈ κ΅¬μ±
- 'slick' ν΄λμ€λ₯Ό μ¬μ©νμ¬ μ¬λΌμ΄λ νΈλ, 컨νΈλ‘€λ¬ λ± κ΅¬λΆ
- λ§ν¬μ
ꡬ쑰 λΉκ΅:
<section id="myCarousel" class="carousel" aria-roledescription="carousel" aria-label="Highlighted television shows">
<div class="carousel-inner">
<div class="controls">
<button class="rotation pause">...</button>
<button class="previous" aria-controls="myCarousel-items">...</button>
<button class="next" aria-controls="myCarousel-items">...</button>
</div>
<div id="myCarousel-items" class="carousel-items" aria-live="off">
<div class="carousel-item active" role="group" aria-roledescription="slide" aria-label="1 of 6">...</div>
<div class="carousel-item" role="group" aria-roledescription="slide" aria-label="2 of 6">...</div>
...
</div>
</div>
</section>
<div class="ant-carousel">
<div class="slick-slider">
<div class="slick-list">
<div class="slick-track">
<div class="slick-slide slick-active slick-current" aria-hidden="false">...</div>
<div class="slick-slide" aria-hidden="true">...</div>
...
</div>
</div>
<ul class="slick-dots slick-dots-bottom">
<li class="slick-active"><button>1</button></li>
<li><button>2</button></li>
...
</ul>
</div>
</div>
<div class="gui-carousel" carousel-pagination="dots" carousel-controls="auto" carousel-scrollbar="auto"
carousel-snapstop="auto" aria-label="Featured Items Carousel">
<div class="gui-carousel--scroller">
<div class="gui-carousel--snap">
<figure class="animate-visibility captioned-image">
<img loading="lazy" width="1280" height="720" src="https://picsum.photos/seed/this/1280/720.webp"
alt="Blue ocean with a large wave">
<figcaption>
<a href="#">Learn more about large ocean waves</a>
</figcaption>
</figure>
</div>
...
</div>
</div>
- ꡬ쑰μ μ ν μ΄μ :
- W3Cλ
<section>, <div>, role μμ± λ±μ νμ©νμ¬ μΊλ¬μ
κ³Ό μ¬λΌμ΄λλ₯Ό ꡬ쑰ννκ³ μμ. ARIA μμ±μ μ κ·Ή νμ©νμ¬ μ κ·Όμ±μ λμ
- Ant Designμ μΊλ¬μ
μ
<div> νκ·Έμ μ‘°ν©μΌλ‘ ꡬμ±νκ³ , 'slick' ν΄λμ€λ₯Ό μ¬μ©νμ¬ κ΅¬λΆν¨. μ¬λΌμ΄λ 리μ€νΈμ μΈλμΌμ΄ν°λ₯Ό λ³λλ‘ λ§ν¬μ
ν¨
- Web Devλ
<div>μ 컀μ€ν
μμ±μ μ¬μ©νμ¬ μΊλ¬μ
μ ꡬμ±ν¨. <figure>μ <figcaption>μ μ¬μ©νμ¬ μ΄λ―Έμ§μ μΊ‘μ
μ μλ―Έλ‘ μ μΌλ‘ λ§ν¬μ
ν¨
π‘ UI λΌμ΄λΈλ¬λ¦¬ λΉκ΅ λΆμ
- Ant Design: 'slick' ν΄λμ€λ₯Ό νμ©νμ¬ κ΅¬μ‘°λ₯Ό ꡬμ±ν¨. μ¬λΌμ΄λλ
<div>λ‘, μΈλμΌμ΄ν°λ <ul><li>λ‘ λ§ν¬μ
. ARIA μμ± μ¬μ©μ΄ μ νμ μ
- Web Dev: 컀μ€ν
μμ±μ μ¬μ©νμ¬ μΊλ¬μ
μ λμμ μ μ΄ν¨. μ΄λ―Έμ§μ μΊ‘μ
μ μλ§¨ν± νκ·Έλ₯Ό μ¬μ©νμ¬ μλ―Έλ‘ μ λ§ν¬μ
μ ꡬνν¨
βοΈ κ΅¬ν λ° μ€κ³ κ³ λ €μ¬ν
- μ£Όμ μ€κ³ κ³ λ €μ¬ν:
- μΊλ¬μ
μλ μ¬μ μ μ κ·Όμ±μ μν΄ μΌμμ μ§ μ»¨νΈλ‘€μ μ 곡νκ³ , μ΄μ μ΄ μ»΄ν¬λνΈ λ΄λΆμ μμ λ μλ μ¬μμ λ©μΆ€
- μ΄μ /λ€μ 컨νΈλ‘€μ ν€λ³΄λλ‘ μ‘°μν μ μμ΄μΌ νλ©°, μ¬λΌμ΄λ λͺ©λ‘ λ°μΌλ‘ μ΄μ μ΄ μ΄λνμ§ μλλ‘ ν¨
- μΈλμΌμ΄ν°λ₯Ό ν΅ν΄ μ΄ μ¬λΌμ΄λ μμ νμ¬ λ³΄μ¬μ§λ μ¬λΌμ΄λ μ 보λ₯Ό μ 곡
- μ½λ μμ:
<section class="carousel" aria-roledescription="carousel">
<h2 id="carousel-heading" class="carousel-heading">Featured Products</h2>
<div class="carousel-controls">
<button class="carousel-control prev" aria-controls="carousel-items">
<span class="icon" aria-hidden="true">‹</span>
<span class="text">Previous</span>
</button>
<button class="carousel-control next" aria-controls="carousel-items">
<span class="text">Next</span>
<span class="icon" aria-hidden="true">›</span>
</button>
</div>
<div class="carousel-inner">
<ul id="carousel-items" class="carousel-items" aria-live="off">
<li class="carousel-item active" role="group" aria-roledescription="slide" aria-label="1 of 3">...</li>
<li class="carousel-item" role="group" aria-roledescription="slide" aria-label="2 of 3">...</li>
<li class="carousel-item" role="group" aria-roledescription="slide" aria-label="3 of 3">...</li>
</ul>
</div>
<div class="carousel-indicators">
<button aria-controls="carousel-items" aria-label="Slide 1" aria-selected="true">1</button>
<button aria-controls="carousel-items" aria-label="Slide 2">2</button>
<button aria-controls="carousel-items" aria-label="Slide 3">3</button>
</div>
</section>
π ν
μ€νΈ λ° κ²ν
- μ κ·Όμ± ν
μ€νΈ:
- μ€ν¬λ¦° 리λ μ¬μ© μ μ¬λΌμ΄λ μ½ν
μΈ μ½κΈ°, νμ¬ μ¬λΌμ΄λ μ 보 μ 곡, μ΄μ /λ€μ 컨νΈλ‘€ μ‘°μ κ°λ₯νμ§ νμΈ
- ν€λ³΄λλ§μΌλ‘ μ»΄ν¬λνΈ λ΄ μ΄λ λ° μ»¨νΈλ‘€ μ‘°μμ΄ κ°λ₯νμ§ ν
μ€νΈ
- λΈλΌμ°μ νΈνμ± ν
μ€νΈ: μ£Όμ λ°μ€ν¬ν/λͺ¨λ°μΌ λΈλΌμ°μ μμ λ μ΄μμ λ° κΈ°λ₯ λμ μ¬λΆ νμΈ
- μ¬μ©μ νΌλλ°±: λ€μν μ¬μ©μλ₯Ό λμμΌλ‘ μΊλ¬μ
μ»΄ν¬λνΈ μ¬μ©μ± ν
μ€νΈλ₯Ό μ§ννκ³ , κ°μ μ¬νμ μλ ΄
π μΆκ° μ°Έκ³ μ¬ν
π― μν , μμ±, μν λ° νκ·Έ μμ±
- Role, Attribute, State
- Role:
aria-roledescription="carousel", role="group", aria-roledescription="slide" λ± νμ©
- Attribute:
aria-label, aria-controls, aria-selected λ± νμ©νμ¬ μ»΄ν¬λνΈ μν λ° μνΈμμ© μ€λͺ
- State:
aria-live="off"(μλ νμ μ)μ aria-live="polite"(μλ νμ μ€μ§ μ)λ₯Ό μ¬μ©νμ¬ νμ¬ μνμ λ°λ₯Έ μλ¦Ό μ μ΄
- JavaScript λ° CSS μ¬μ© μ¬λΆ
- JavaScript μ¬μ© μ¬λΆ: μ¬λΌμ΄λ μ ν, μλ μ¬μ, μΈλμΌμ΄ν° λκΈ°ν λ±μ μ²λ¦¬νκΈ° μν΄ JavaScript νμ©
- CSS μ μ© μ¬ν:
overflow: hiddenμ μ¬μ©νμ¬ λ³΄μ΄λ μμ μΈ μ¬λΌμ΄λ κ°μΆ€ μ²λ¦¬. transformκ³Ό transitionμ μ¬μ©νμ¬ μ¬λΌμ΄λ μ ν μ λλ©μ΄μ
ꡬν
π μ»΄ν¬λνΈ μ 보
π μ°Έμ‘° λ° λ νΌλ°μ€
π μ κ·Όμ± λ° ARIA μ μ© μ¬λΆ
aria-roledescription="carousel",aria-label,aria-live="off"(μλ νμ μ) λλaria-live="polite"(μλ νμ μ€μ§ μ),aria-controls,aria-selectedλ±μ΄ μ¬μ©λ¨.aria-live="off"λ₯Ό μ¬μ©νμ¬ λΆνμν μ λ°μ΄νΈ μλ¦Ό λ°©μ§aria-live="polite"λ₯Ό μ¬μ©νμ¬ μ¬λΌμ΄λ λ³κ²½ μ¬ν μλ¦ΌποΈ λ§ν¬μ ꡬ쑰 λΆμ
<section>νκ·Έλ‘ carousel μ»΄ν¬λνΈ μμ νμ<div>νκ·Έμ ARIA μν (role)μ μ¬μ©νμ¬ μ¬λΌμ΄λ λͺ©λ‘κ³Ό 컨νΈλ‘€ μμ ꡬλΆ<div>νκ·Έλ₯Ό μ¬μ©νμ¬ μ 체 carousel μ»΄ν¬λνΈ κ΅¬μ±<section>,<div>,roleμμ± λ±μ νμ©νμ¬ μΊλ¬μ κ³Ό μ¬λΌμ΄λλ₯Ό ꡬ쑰ννκ³ μμ. ARIA μμ±μ μ κ·Ή νμ©νμ¬ μ κ·Όμ±μ λμ<div>νκ·Έμ μ‘°ν©μΌλ‘ ꡬμ±νκ³ , 'slick' ν΄λμ€λ₯Ό μ¬μ©νμ¬ κ΅¬λΆν¨. μ¬λΌμ΄λ 리μ€νΈμ μΈλμΌμ΄ν°λ₯Ό λ³λλ‘ λ§ν¬μ ν¨<div>μ 컀μ€ν μμ±μ μ¬μ©νμ¬ μΊλ¬μ μ ꡬμ±ν¨.<figure>μ<figcaption>μ μ¬μ©νμ¬ μ΄λ―Έμ§μ μΊ‘μ μ μλ―Έλ‘ μ μΌλ‘ λ§ν¬μ ν¨π‘ UI λΌμ΄λΈλ¬λ¦¬ λΉκ΅ λΆμ
<div>λ‘, μΈλμΌμ΄ν°λ<ul><li>λ‘ λ§ν¬μ . ARIA μμ± μ¬μ©μ΄ μ νμ μβοΈ κ΅¬ν λ° μ€κ³ κ³ λ €μ¬ν
π ν μ€νΈ λ° κ²ν
π μΆκ° μ°Έκ³ μ¬ν
π― μν , μμ±, μν λ° νκ·Έ μμ±
aria-roledescription="carousel",role="group",aria-roledescription="slide"λ± νμ©aria-label,aria-controls,aria-selectedλ± νμ©νμ¬ μ»΄ν¬λνΈ μν λ° μνΈμμ© μ€λͺaria-live="off"(μλ νμ μ)μaria-live="polite"(μλ νμ μ€μ§ μ)λ₯Ό μ¬μ©νμ¬ νμ¬ μνμ λ°λ₯Έ μλ¦Ό μ μ΄overflow: hiddenμ μ¬μ©νμ¬ λ³΄μ΄λ μμ μΈ μ¬λΌμ΄λ κ°μΆ€ μ²λ¦¬.transformκ³Όtransitionμ μ¬μ©νμ¬ μ¬λΌμ΄λ μ ν μ λλ©μ΄μ ꡬν