Skip to main content

Command Palette

Search for a command to run...

탭 구현 하기 - 앵커와 버튼

Updated
•2 min read•View as Markdown

시작하기 전에

진행 중인 사이드 프로젝트를 하면서 위와 같은 UI를 보여줘야 했는데, 카테고리에 따라 내용을 달리 해야 했다.

이전에는 내용을 달리 보여줘야 하는거면 react-router-dom의 Link를 사용해서 URL만 바꿔서 다른 내용을 보여주면 되는 거 아닌가? 라고 생각을 했지만 이번 사이트 프로젝트에서는 탭으로 구현을 해야 했다.

내 포트폴리오 사이트를 만들면서 페이지 이동하는 부분을 a 태그로 구현한 적이 있어서 이번 프로젝트에도 비슷하게 적용을 하면 되지 않을까 싶었다.

하지만 요구 사항으로는 탭으로 작동해야 하고 탭 내 카테고리 클릭 시 부드러운 스크롤을 통해 섹션 이동이 되어야 했다. 이럴 경우에는 어떤 방법을 써야 할 지 헷갈렸다. 그래서 이번 블로그를 작성하면서 조금 더 확실하게 알아보고자 한다.

링크(Anchor)

특정 URL로 이동하거나 페이지 내부에서 특정 영역으로 이동할 때 사용한다.

Next 혹은 react-router-dom에서는 Link로 쓰이지만 내부는 <a> 태그로 구현이 되어있다.

구현방법

<a href='/'>{link.title}</a>
<a href='#work'>{link.title}</a>
<a href='#experience'>{link.title}</a>

탭

anchor와 비슷하지만 URL 이동 및 페이지 내에서 스크롤 이동이 없다.

구현 방법

<!-- O: 앵커 형식 탭 -->
<div class="weekly">
    <div role="tablist">
        <a id="mon-anchor" href="#mon" role="tab" aria-selected="true">월</a>
        <a id="tue-anchor" href="#tue" role="tab" aria-selected="false">화</a>
    </div>
    <div id="mon" tabindex="0" role="tabpanel" aria-labelledby="mon-anchor">
        월요일엔 빨간 장미를...
    </div>
    <div id="tue" tabindex="0" role="tabpanel" aria-labelledby="tue-anchor" hidden>
        화요일엔 노란 장미를...
    </div>
</div>

<!-- O: 버튼 형식 탭 -->
<div class="weekly">
    <div role="tablist">
        <button type="button" id="mon-anchor" aria-controls="mon" role="tab" aria-selected="true">월</button>
        <button type="button" id="tue-anchor" aria-controls="tue" role="tab" aria-selected="false">화</button>
    </div>
    <div id="mon" tabindex="0" role="tabpanel" aria-labelledby="mon-anchor">
        월요일엔 빨간 장미를...
    </div>
    <div id="tue" tabindex="0" role="tabpanel" aria-labelledby="tue-anchor" hidden>
        화요일엔 노란 장미를...
    </div>
</div>

두 가지 중 어떤 게 적절할까?

우선 탭을 구현하는 데 있어서 다음과 같은 부분을 생각해볼 수 있다.

  • 페이지 이동이 아닌 동적 컨텐츠 변화이기 때문에 <button> 태그가 더 적합하다.

  • <a> 태그를 사용할 경우 스크린 리더가 링크로 오해할 수 있기 때문에 스크린 리더가 확실히 버튼이라고 인식할 수 있는 <button> 태그가 더 적합하다.

  • 키보드 탐색에 있어서, 탭으로 사용하고자 할 경우 <a> 태그에 href를 제거하면 tabIndex가 -1이 되어버리기 때문에 키보드 포커스를 받지 못한다.

이러한 이유들 때문에 최종적으로 button 태그를 사용하기로 했다.

button에 role 부여하기

<div role="tablist" aria-label="콘텐츠 탭">
  <button role="tab" aria-selected="true" aria-controls="panel-1" id="tab-1">
    재료
  </button>
  <button role="tab" aria-selected="false" aria-controls="panel-2" id="tab-2">
    조리도구
  </button>
  <button role="tab" aria-selected="false" aria-controls="panel-3" id="tab-3">
    요리순서
  </button>
  <button role="tab" aria-selected="false" aria-controls="panel-3" id="tab-3">
    후기
  </button>
</div>

ARIA 속성을 부여하면 해당 버튼이 탭으로 동작한다는 것을 확실하게 할 수 있다.

More from this blog

shadcn UI의 checkbox는 왜 indeterminate이라는 상태가 존재하는가?

예전에 shadcn으로 checkbox UI를 만들어보다가 shadcn 코드베이스에 indeterminate 라는 상태가 있는 것을 보게 되었다. 체크 상태는 체크/체크 해제 밖에 없는 것 아닌가? 라고 생각했고, 한 번 indeterminate의 정체가 뭔지 살펴보기로 했다. 체크박스에는 체크와 해제 외에 세 번째 상태가 있다. 이 상태의 이름은 inde

Oct 10, 20269 min read9

코드제로투원 프로젝트 회고

약 6개월간 진행한 프로젝트를 2주 전에 끝마쳤다. 원래 사이드프로젝트에 대한 회고를 잘 작성하지 않는 편이어서, 이번에도 고민을 좀 했지만, 여태까지 프로젝트를 하면서 가장 많이 기억에 남은 기억이라 이렇게 회고를 작성하려고 한다. 참여하게 된 계기 올해 1월, 코드제로투원이라는 스터디 플랫폼 사이드프로젝트에 참여했다. 직전에는 자취생들을 위한 식단 추천

Jul 17, 20265 min read40
코드제로투원 프로젝트 회고

haseung-log

33 posts