🗂️ 탭 UI 컴포넌트

탭 UI
완전 정복

콘텐츠를 깔끔하게 분류하는 탭 컴포넌트. 언더라인 탭, 알약형 탭, 카드형 탭까지 — 3가지 스타일을 직접 클릭해서 확인하고 코드를 복사해가세요.

🗂️ 3가지 탭 스타일 🎬 전환 애니메이션 ♿ 키보드 접근성 📋 복사 가능한 코드
① Concept

탭 UI란?

같은 공간에 여러 콘텐츠를 넣되, 탭 버튼으로 하나씩 전환하는 UI예요. 스크롤 없이 많은 정보를 정돈된 방식으로 보여줄 수 있어요.

💡

탭 동작 원리: 탭 버튼을 클릭하면 ① 모든 패널을 숨기고 (display:none) ② 선택한 패널만 표시 (display:block) ③ 탭 버튼의 active 클래스 이동. 이 세 단계가 전부예요.

📑

언제 쓰나요?

제품 상세 페이지(설명/리뷰/배송), 프로필 페이지(게시글/팔로워/좋아요), 대시보드(개요/통계/설정) 등 카테고리별로 콘텐츠를 분리할 때 최적이에요.

접근성 고려

탭 버튼에 role="tab", aria-selected를 넣고, 패널에 role="tabpanel"을 추가해요. 키보드 화살표 키로도 탭을 이동할 수 있어야 해요.

🔗

URL 연동

#tab-review처럼 해시(#)를 URL에 저장하면 공유 링크로 특정 탭을 바로 열 수 있어요. 뒤로가기 버튼도 자연스럽게 동작해 UX가 좋아져요.

🚫

언제 피해야 할까?

탭이 2개 이하면 그냥 두 섹션으로 나누는 게 나아요. 탭이 6개 이상이면 화면이 작을 때 넘쳐요. 검색 엔진은 탭 안의 콘텐츠를 잘 못 읽을 수 있어요.

② Types

탭 스타일 3가지

프로젝트 분위기에 맞는 스타일을 골라 쓸 수 있어요. 아래 데모에서 직접 클릭해보세요.

〰️

언더라인 탭

활성 탭 아래 선이 그어지는 심플한 스타일이에요. GitHub, Google 등 많은 사이트에서 쓰는 클래식 패턴입니다. 콘텐츠 위주의 사이트에 잘 어울려요.

💊

알약형(Pill) 탭

활성 탭이 둥근 배경으로 강조돼요. 현대적이고 모바일 친화적이에요. 앱처럼 느껴지는 디자인에 잘 어울려요. 탭 수가 많아도 스크롤 가능해요.

🗂️

카드형 탭

탭이 파일 탭처럼 생겼어요. 활성 탭이 아래 콘텐츠 박스와 연결된 느낌이에요. 관리자 패널, 설정 페이지 같은 도구형 UI에 잘 어울려요.

③ Code

코드 해설

탭 UI의 핵심 코드예요. HTML 구조, CSS 상태 스타일, JavaScript 전환 로직 순서로 살펴봐요.

1 — HTML 구조 (시맨틱 마크업)

data-tab 속성으로 탭 버튼과 패널을 연결해요. aria 속성으로 접근성도 챙겨요.

index.html
<div class="tab-wrap" role="tablist">

  <!-- 탭 버튼 -->
  <div class="tab-nav">
    <button class="tab-btn active" data-tab="intro"
            role="tab" aria-selected="true">소개</button>
    <button class="tab-btn" data-tab="features"
            role="tab" aria-selected="false">기능</button>
    <button class="tab-btn" data-tab="pricing"
            role="tab" aria-selected="false">가격</button>
  </div>

  <!-- 탭 패널 -->
  <div class="tab-panel active" id="panel-intro"   role="tabpanel">소개 내용</div>
  <div class="tab-panel"        id="panel-features" role="tabpanel">기능 내용</div>
  <div class="tab-panel"        id="panel-pricing"  role="tabpanel">가격 내용</div>

</div>

2 — CSS (패널 표시/숨김 + 애니메이션)

style.css
/* 패널: 기본 숨김 */
.tab-panel        { display: none; }
.tab-panel.active { display: block; animation: fadeTab .2s ease both; }

@keyframes fadeTab {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* 탭 버튼 — 언더라인 스타일 */
.tab-btn {
  border: none; background: none; cursor: pointer;
  padding: 12px 20px; font-weight: 500;
  color: #6b7280; position: relative;
}
.tab-btn::after {
  content: ''; position: absolute;
  bottom: 0; left: 0; right: 0; height: 2px;
  background: #4f46e5;
  transform: scaleX(0); transition: transform .2s;
}
.tab-btn.active { color: #4f46e5; font-weight: 700; }
.tab-btn.active::after { transform: scaleX(1); }

3 — JavaScript (탭 전환 로직)

이벤트 위임으로 탭 버튼 클릭을 처리해요. data-tab 값으로 패널을 찾아요.

script.js
// 탭 초기화 함수 (여러 탭 그룹에 재사용 가능)
function initTabs(wrapper) {
  const buttons = wrapper.querySelectorAll('[data-tab]');
  const panels  = wrapper.querySelectorAll('.tab-panel');

  buttons.forEach(function(btn) {
    btn.addEventListener('click', function() {
      const target = this.dataset.tab;

      // 모든 버튼 비활성화
      buttons.forEach(function(b) {
        b.classList.remove('active');
        b.setAttribute('aria-selected', 'false');
      });

      // 모든 패널 숨기기
      panels.forEach(function(p) {
        p.classList.remove('active');
      });

      // 선택한 탭/패널 활성화
      this.classList.add('active');
      this.setAttribute('aria-selected', 'true');
      wrapper.querySelector(`#panel-${target}`)
             ?.classList.add('active');
    });
  });
}

// 사용: 탭 그룹마다 호출
document.querySelectorAll('.tab-wrap').forEach(initTabs);
💡

재사용성 팁: initTabs 함수를 wrapper 요소에 인자로 넘기면 페이지에 탭 그룹이 여러 개 있어도 각각 독립적으로 동작해요. document.querySelectorAll('.tab-wrap').forEach(initTabs) 한 줄로 모든 탭을 초기화할 수 있어요.

④ Demo

3가지 스타일 직접 체험

탭을 클릭해서 각 스타일을 확인해보세요. 코드는 위 섹션에서 복사할 수 있어요.

① 언더라인 탭

언더라인 탭이에요

클래식하고 깔끔한 스타일이에요. 활성 탭 아래에 보라색 선이 생겨요. GitHub, Notion 같은 사이트에서 자주 볼 수 있는 패턴이에요.

주요 기능

  • CSS ::after 가상 요소로 언더라인 구현
  • scaleX() 트랜지션으로 자연스러운 등장 효과
  • hover 시에도 배경색 변화로 피드백 제공

가격 안내

바이브툴킷의 모든 코드는 무료로 복사해서 사용하실 수 있어요. 상업적 이용도 가능해요.

⭐⭐⭐⭐⭐ 사용자 후기

"탭 UI 만드는 방법을 몰랐는데 이 페이지 덕분에 바로 사이트에 적용했어요!"

② 알약형(Pill) 탭

전체 카테고리

모든 분류의 도구를 한 번에 볼 수 있어요. 알약형 탭은 선택된 항목이 배경색으로 명확하게 강조돼요. 모바일 앱에서 자주 보이는 스타일이에요.

CSS 도구

  • CSS 변수 활용법
  • Flexbox 레이아웃
  • CSS Grid 레이아웃
  • 반응형 디자인
  • CSS 애니메이션 ← 현재 페이지

JavaScript 도구

  • 클릭 이벤트 기초
  • 로컬 스토리지
  • 스크롤 이벤트
  • fetch API ← 다음 도구

SEO 도구

  • 메타 태그 (SEO)
  • 오픈그래프 (OG)
  • 사이트맵 만들기

③ 카드형 탭

대시보드 개요

카드형 탭은 파일 탭처럼 생겨서 관리자 패널, 설정 페이지에 잘 어울려요. 활성 탭이 아래 패널 콘텐츠와 연결된 느낌을 줍니다.

설정

설정 페이지처럼 탭마다 독립적인 설정 항목이 있을 때 카드형이 직관적이에요.

통계

방문자 수, 클릭 수 등 다양한 통계를 탭으로 분리해서 보여줄 수 있어요.

⑤ Prompt Tip

AI 프롬프트 팁

탭 UI를 AI에게 요청할 때 구체적인 스타일과 탭 이름을 알려주면 완성도 높은 코드를 받을 수 있어요.

✦ 바이브코더 프롬프트

아래 프롬프트를 복사해서 AI에 붙여넣어 보세요.

내 제품 상세 페이지에 탭 UI를 추가해줘.

탭 목록:
- 상품 설명 (기본 활성)
- 사용 방법
- 리뷰 (23개)
- 배송/교환

스타일: 언더라인 탭 (활성 탭 아래 파란 선)
전환 효과: 아래에서 위로 페이드인 (0.2s)

요구사항:
- 탭 클릭 시 해당 패널만 표시
- 키보드 접근성 (aria-selected 포함)
- 모바일에서도 가로 스크롤로 탭 표시
- 순수 HTML + CSS + Vanilla JS (라이브러리 없이)
⑥ FAQ

자주 묻는 질문

탭 UI를 구현할 때 자주 맞닥뜨리는 질문들이에요.

display:none으로 숨겨진 콘텐츠는 구글이 읽을 수 있지만, 페이지 랭킹에서 덜 중요하게 처리할 수 있어요. SEO가 중요한 콘텐츠(상품 설명, 리뷰 등)는 탭 대신 모두 표시된 섹션으로 구성하거나, 탭 URL을 별도 페이지로 만드는 것을 고려해봐요.
탭 클릭 시 window.location.hash = '#' + tabId로 해시를 업데이트하고, 페이지 로드 시 window.location.hash를 읽어 해당 탭을 활성화하면 돼요. 이렇게 하면 특정 탭 URL을 공유하거나 뒤로가기 버튼으로 탭 이동이 가능해요.
WAI-ARIA 탭 패턴에 따르면 좌우 화살표 키로 탭을 이동하고, Enter/Space로 선택해야 해요. keydown 이벤트에서 ArrowLeft, ArrowRight를 감지해 이전/다음 탭 버튼으로 포커스를 이동하고 클릭 이벤트를 트리거하면 돼요.
탭 네비게이션에 overflow-x: auto를 추가하면 수평 스크롤이 생겨요. 탭이 6개 이상이면 "더보기" 드롭다운으로 넘치는 탭을 숨기는 패턴도 있어요. 혹은 탭 대신 사이드바 네비게이션이나 셀렉트박스로 전환하는 것도 좋은 UX예요.
useState로 활성 탭 ID를 관리하고, 탭 버튼 클릭 시 상태를 업데이트해요. 조건부 렌더링({activeTab === 'intro' && <IntroPanel />})으로 패널을 표시해요. Radix UI의 Tabs 컴포넌트나 shadcn/ui를 쓰면 접근성까지 포함된 완성된 컴포넌트를 바로 사용할 수 있어요.