aria-labelledby
를 알기 전에, aria-label
이 무엇인지 알아야한다.
aria
는 HTML요소에 접근 가능한 설명용 텍스트를 넣을 수 있다.aria
의 속성 중 label
과 관련된 속성을 사용하는 것.aria-label
은 화면에 현재 요소를 설명할 텍스트가 없을 경우 사용하는 설명용 텍스트를 담고 있고,aria-labelledby
는 화면에 현재 요소를 설명할 텍스트가 있을 경우에aria-label
은 모든 html 태그에서 사용이 가능하다.aria-label
을 사용하여 액세스 가능한 레이블로 사용할 문자열을 지정할 수 있다.그렇다면 aria-labelledby
는 무엇일까?
aria-labelledby
를 사용하면 어떤 요소의 레이블로서 DOM 에 있는 다른 요소의 ID
를 지정할 수 있다.aria-labelledby
은 레이블을 지정하는 대상이 레이블을 지정하는 주체로 참조한다.aria-labelledby
에 있는 내용이 최우선 된다.대부분 이러한 아코디언 메뉴를 ul
그리고 li
를 사용해서 만들지만,
나는 MUI 라이브러리를 사용하고 있어, 어려움이 있었다.
그러다 찾게된 것이 aria-labelledby
이였다.
메뉴의 구성은 아래와 같다.
// 내가 만들고 싶은 메뉴 구성
- 메인메뉴 1
- 서브메뉴 1-1
- 서브메뉴 1-2
- 메인메뉴 2
- 서브메뉴 2-1
- 서브메뉴 2-2
- 서브메뉴 2-3
- 메인메뉴 3
- 서브메뉴 3-1
...
// 메뉴 값
const menu = [
{
main: "메인메뉴 1"
submenu: [
"서브메뉴 1-1","서브메뉴 1-2"
],
},
{
main: "메인메뉴 2"
submenu: [
"서브메뉴 2-1","서브메뉴 2-2","서브메뉴 2-3"
],
},
.
.
.
],
메인메뉴의 id
값을 자동으로 찾아 서브메뉴가 자동으로 연결되길 바랬다.
그리고 아래와 같이 성공했다 :)
<MenuWrapper>
{MenuInfo.map((menu, index) => (
<Accordions
key={menu.id}
expanded={expanded === index}
onChange={handleChange(index)}
>
<AcoSummarys aria-controls={`${index}-content`} id={`{index}-header`}>
<Typography>{menu.summary}</Typography>
</AcoSummarys>
{menu.detail.map((detail, idx) => (
// aria-labelledby 를 사용해 AcoSummarys 컴포넌트의 id 를 참조하여
// 하위메뉴 출력
<AcoDetails
key={idx}
aria-labelledby={`{index}-header`}
id={`{index}-content`}
>
<Typography>{detail}</Typography>
</AcoDetails>
))}
</Accordions>
))}
</MenuWrapper>
이렇게 해서, 메뉴 구성 끝!
위의 예제 사진과 동일하게 구성되었다.
MUI 라이브러리를 사용하고 있는데, 배열값을 아코디언 메뉴로 구성하고 싶을때 사용해야겠다.