Navs and tabs

Bootstrap에 포함된 네비게이션 컴포넌트를 어떻게 사용하는지에 대한 문서와 예시를 다룹니다.

출처: 문서

본문

기본 nav (Base nav)

Bootstrap의 네비게이션은 기본 .nav 클래스부터 active와 disabled 상태까지 공통의 마크업과 스타일을 공유합니다. modifier 클래스를 바꿔 각 스타일 사이를 전환하세요.

기본 .nav 컴포넌트는 flexbox로 만들어져 모든 종류의 네비게이션 컴포넌트를 만들기 위한 강력한 기반을 제공합니다. 몇 가지 스타일 오버라이드(리스트 작업용), 더 큰 클릭 영역을 위한 링크 패딩, 기본적인 disabled 스타일이 포함되어 있습니다.

기본 .nav 컴포넌트에는 .active 상태가 포함되지 않습니다. 아래 예시들은 주로 이 특정 클래스가 특별한 스타일을 트리거하지 않는다는 것을 보여주기 위해 클래스를 포함한 것입니다.

active 상태를 보조 기술에 전달하려면 aria-current 속성을 사용하세요 — 현재 페이지에는 page 값을, 집합 안의 현재 항목에는 true를 사용합니다.

<ul class="nav">
  <li class="nav-item">
    <a class="nav-link active" aria-current="page" href="#">Active</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link disabled" aria-disabled="true">Disabled</a>
  </li>
</ul>

전역적으로 클래스가 사용되므로 마크업이 매우 유연할 수 있습니다. 위처럼 <ul>을 사용하거나, 항목의 순서가 중요하다면 <ol>을, 아니면 <nav> 요소로 직접 만들 수도 있습니다. .nav는 display: flex를 사용하기 때문에 nav 링크는 추가 마크업 없이 nav 항목처럼 동작합니다.

<nav class="nav">
  <a class="nav-link active" aria-current="page" href="#">Active</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link disabled" aria-disabled="true">Disabled</a>
</nav>

사용 가능한 스타일 (Available styles)

modifier와 유틸리티로 .navs 컴포넌트의 스타일을 바꾸세요. 필요에 따라 섞고 매치하거나 직접 만들 수도 있습니다.

가로 정렬 (Horizontal alignment)

flexbox 유틸리티로 nav의 가로 정렬을 바꾸세요. 기본적으로 nav는 왼쪽 정렬이지만, 쉽게 가운데나 오른쪽 정렬로 바꿀 수 있습니다.

.justify-content-center로 가운데 정렬:

<ul class="nav justify-content-center">
  <li class="nav-item">
    <a class="nav-link active" aria-current="page" href="#">Active</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link disabled" aria-disabled="true">Disabled</a>
  </li>
</ul>

.justify-content-end로 오른쪽 정렬:

<ul class="nav justify-content-end">
  <li class="nav-item">
    <a class="nav-link active" aria-current="page" href="#">Active</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link disabled" aria-disabled="true">Disabled</a>
  </li>
</ul>

세로 (Vertical)

.flex-column 유틸리티로 flex 항목 방향을 바꿔 네비게이션을 쌓으세요. 일부 뷰포트에서만 쌓아야 하나요? 반응형 버전(예: .flex-sm-column)을 사용하세요.

<ul class="nav flex-column">
  <li class="nav-item">
    <a class="nav-link active" aria-current="page" href="#">Active</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link disabled" aria-disabled="true">Disabled</a>
  </li>
</ul>

언제나 그렇듯이 <ul> 없이도 세로 네비게이션을 만들 수 있습니다.

<nav class="nav flex-column">
  <a class="nav-link active" aria-current="page" href="#">Active</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link disabled" aria-disabled="true">Disabled</a>
</nav>

Tabs

위의 기본 nav에 .nav-tabs 클래스를 추가해 탭 인터페이스를 만듭니다. 탭 JavaScript 플러그인으로 탭 가능한 영역을 만드는 데 사용하세요.

<ul class="nav nav-tabs">
  <li class="nav-item">
    <a class="nav-link active" aria-current="page" href="#">Active</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link disabled" aria-disabled="true">Disabled</a>
  </li>
</ul>

Pills

같은 HTML에서 .nav-pills를 사용하세요:

<ul class="nav nav-pills">
  <li class="nav-item">
    <a class="nav-link active" aria-current="page" href="#">Active</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link disabled" aria-disabled="true">Disabled</a>
  </li>
</ul>

Underline (밑줄)

같은 HTML에서 .nav-underline을 사용하세요:

<ul class="nav nav-underline">
  <li class="nav-item">
    <a class="nav-link active" aria-current="page" href="#">Active</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link disabled" aria-disabled="true">Disabled</a>
  </li>
</ul>

채우기와 균등화 (Fill and justify)

두 modifier 클래스 중 하나로 .nav의 내용물이 사용 가능한 전체 너비를 차지하도록 강제하세요. .nav-items로 사용 가능한 모든 공간을 비례적으로 채우려면 .nav-fill을 사용하세요. 모든 가로 공간이 차지되지만 모든 nav 항목의 너비가 같은 것은 아닙니다.

<ul class="nav nav-pills nav-fill">
  <li class="nav-item">
    <a class="nav-link active" aria-current="page" href="#">Active</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Much longer nav link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link disabled" aria-disabled="true">Disabled</a>
  </li>
</ul>

<nav> 기반 네비게이션을 사용할 때는 <a> 요소 스타일에 .nav-link만 필요하므로 .nav-item을 안전하게 생략할 수 있습니다.

<nav class="nav nav-pills nav-fill">
  <a class="nav-link active" aria-current="page" href="#">Active</a>
  <a class="nav-link" href="#">Much longer nav link</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link disabled" aria-disabled="true">Disabled</a>
</nav>

동일한 너비의 요소를 원한다면 .nav-justified를 사용하세요. 모든 가로 공간이 nav 링크로 점유되지만, 위의 .nav-fill과 달리 모든 nav 항목이 같은 너비가 됩니다.

<ul class="nav nav-pills nav-justified">
  <li class="nav-item">
    <a class="nav-link active" aria-current="page" href="#">Active</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Much longer nav link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link disabled" aria-disabled="true">Disabled</a>
  </li>
</ul>

.nav-fill 예시와 비슷하게 <nav> 기반 네비게이션을 사용한 경우입니다.

<nav class="nav nav-pills nav-justified">
  <a class="nav-link active" aria-current="page" href="#">Active</a>
  <a class="nav-link" href="#">Much longer nav link</a>
  <a class="nav-link" href="#">Link</a>
  <a class="nav-link disabled" aria-disabled="true">Disabled</a>
</nav>

flex 유틸리티 사용하기 (Working with flex utilities)

반응형 nav 변형이 필요하다면 일련의 flexbox 유틸리티를 사용하는 것을 고려하세요. 다소 장황하지만, 이 유틸리티들은 반응형 브레이크포인트에 걸쳐 더 큰 커스터마이즈를 제공합니다. 아래 예시에서 nav는 가장 낮은 브레이크포인트에서 쌓인 다음, small 브레이크포인트부터 사용 가능한 너비를 채우는 가로 레이아웃으로 적응합니다.

<nav class="nav nav-pills flex-column flex-sm-row">
  <a class="flex-sm-fill text-sm-center nav-link active" aria-current="page" href="#">Active</a>
  <a class="flex-sm-fill text-sm-center nav-link" href="#">Longer nav link</a>
  <a class="flex-sm-fill text-sm-center nav-link" href="#">Link</a>
  <a class="flex-sm-fill text-sm-center nav-link disabled" aria-disabled="true">Disabled</a>
</nav>

접근성에 관해 (Regarding accessibility)

navs로 네비게이션 바를 제공한다면 <ul>의 가장 논리적인 부모 컨테이너에 role="navigation"을 추가하거나, 네비게이션 전체를 <nav> 요소로 감싸세요. role을 <ul> 자체에 추가하지 마세요. 그러면 보조 기술이 실제 리스트로 알리지 못하게 됩니다.

네비게이션 바는 .nav-tabs 클래스로 시각적으로 탭처럼 스타일되어 있어도 role="tablist", role="tab", role="tabpanel" 속성을 주면 안 됩니다. 이것들은 ARIA Authoring Practices Guide의 tabs 패턴에 설명된 대로 동적 탭 인터페이스에만 적합합니다. 동적 탭 인터페이스의 예시는 이 섹션의 JavaScript behavior를 참고하세요. 동적 탭 인터페이스에서는 JavaScript가 활성 탭에 aria-selected="true"를 추가해 선택 상태를 처리하므로 aria-current 속성이 필요하지 않습니다.

드롭다운 사용하기 (Using dropdowns)

약간의 추가 HTML과 dropdowns JavaScript 플러그인으로 드롭다운 메뉴를 추가하세요.

드롭다운이 있는 Tabs (Tabs with dropdowns)

<ul class="nav nav-tabs">
  <li class="nav-item">
    <a class="nav-link active" aria-current="page" href="#">Active</a>
  </li>
  <li class="nav-item dropdown">
    <a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false">Dropdown</a>
    <ul class="dropdown-menu">
      <li><a class="dropdown-item" href="#">Action</a></li>
      <li><a class="dropdown-item" href="#">Another action</a></li>
      <li><a class="dropdown-item" href="#">Something else here</a></li>
      <li><hr class="dropdown-divider"></li>
      <li><a class="dropdown-item" href="#">Separated link</a></li>
    </ul>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link disabled" aria-disabled="true">Disabled</a>
  </li>
</ul>

드롭다운이 있는 Pills (Pills with dropdowns)

<ul class="nav nav-pills">
  <li class="nav-item">
    <a class="nav-link active" aria-current="page" href="#">Active</a>
  </li>
  <li class="nav-item dropdown">
    <a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false">Dropdown</a>
    <ul class="dropdown-menu">
      <li><a class="dropdown-item" href="#">Action</a></li>
      <li><a class="dropdown-item" href="#">Another action</a></li>
      <li><a class="dropdown-item" href="#">Something else here</a></li>
      <li><hr class="dropdown-divider"></li>
      <li><a class="dropdown-item" href="#">Separated link</a></li>
    </ul>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link disabled" aria-disabled="true">Disabled</a>
  </li>
</ul>

CSS

변수 (Variables)

v5.2.0에서 추가됨

Bootstrap의 진화하는 CSS 변수 접근 방식의 일부로, navs는 이제 향상된 실시간 커스터마이즈를 위해 .nav, .nav-tabs, .nav-pills에 로컬 CSS 변수를 사용합니다. CSS 변수의 값은 Sass로 설정되므로 Sass 커스터마이즈도 여전히 지원됩니다.

.nav 기본 클래스에서:

--#{$prefix}nav-link-padding-x: #{$nav-link-padding-x};
--#{$prefix}nav-link-padding-y: #{$nav-link-padding-y};
@include rfs($nav-link-font-size, --#{$prefix}nav-link-font-size);
--#{$prefix}nav-link-font-weight: #{$nav-link-font-weight};
--#{$prefix}nav-link-color: #{$nav-link-color};
--#{$prefix}nav-link-hover-color: #{$nav-link-hover-color};
--#{$prefix}nav-link-disabled-color: #{$nav-link-disabled-color};

.nav-tabs modifier 클래스에서:

--#{$prefix}nav-tabs-border-width: #{$nav-tabs-border-width};
--#{$prefix}nav-tabs-border-color: #{$nav-tabs-border-color};
--#{$prefix}nav-tabs-border-radius: #{$nav-tabs-border-radius};
--#{$prefix}nav-tabs-link-hover-border-color: #{$nav-tabs-link-hover-border-color};
--#{$prefix}nav-tabs-link-active-color: #{$nav-tabs-link-active-color};
--#{$prefix}nav-tabs-link-active-bg: #{$nav-tabs-link-active-bg};
--#{$prefix}nav-tabs-link-active-border-color: #{$nav-tabs-link-active-border-color};

.nav-pills modifier 클래스에서:

--#{$prefix}nav-pills-border-radius: #{$nav-pills-border-radius};
--#{$prefix}nav-pills-link-active-color: #{$nav-pills-link-active-color};
--#{$prefix}nav-pills-link-active-bg: #{$nav-pills-link-active-bg};

v5.3.0에서 추가됨

.nav-underline modifier 클래스에서:

--#{$prefix}nav-underline-gap: #{$nav-underline-gap};
--#{$prefix}nav-underline-border-width: #{$nav-underline-border-width};
--#{$prefix}nav-underline-link-active-color: #{$nav-underline-link-active-color};

Sass 변수

$nav-link-padding-y:                .5rem;
$nav-link-padding-x:                1rem;
$nav-link-font-size:                null;
$nav-link-font-weight:              null;
$nav-link-color:                    var(--#{$prefix}link-color);
$nav-link-hover-color:              var(--#{$prefix}link-hover-color);
$nav-link-transition:               color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out;
$nav-link-disabled-color:           var(--#{$prefix}secondary-color);
$nav-link-focus-box-shadow:         $focus-ring-box-shadow;

$nav-tabs-border-color:             var(--#{$prefix}border-color);
$nav-tabs-border-width:             var(--#{$prefix}border-width);
$nav-tabs-border-radius:            var(--#{$prefix}border-radius);
$nav-tabs-link-hover-border-color:  var(--#{$prefix}secondary-bg) var(--#{$prefix}secondary-bg) $nav-tabs-border-color;
$nav-tabs-link-active-color:        var(--#{$prefix}emphasis-color);
$nav-tabs-link-active-bg:           var(--#{$prefix}body-bg);
$nav-tabs-link-active-border-color: var(--#{$prefix}border-color) var(--#{$prefix}border-color) $nav-tabs-link-active-bg;

$nav-pills-border-radius:           var(--#{$prefix}border-radius);
$nav-pills-link-active-color:       $component-active-color;
$nav-pills-link-active-bg:          $component-active-bg;

$nav-underline-gap:                 1rem;
$nav-underline-border-width:        .125rem;
$nav-underline-link-active-color:   var(--#{$prefix}emphasis-color);

JavaScript 동작 (JavaScript behavior)

탭 JavaScript 플러그인(개별로 포함하거나 컴파일된 bootstrap.js 파일을 통해 포함)을 사용해 네비게이션 탭과 pills를 확장해 로컬 콘텐츠의 탭 가능한 패널(tabbable panes)을 만드세요.

<ul class="nav nav-tabs" id="myTab" role="tablist">
  <li class="nav-item" role="presentation">
    <button class="nav-link active" id="home-tab" data-bs-toggle="tab" data-bs-target="#home-tab-pane" type="button" role="tab" aria-controls="home-tab-pane" aria-selected="true">Home</button>
  </li>
  <li class="nav-item" role="presentation">
    <button class="nav-link" id="profile-tab" data-bs-toggle="tab" data-bs-target="#profile-tab-pane" type="button" role="tab" aria-controls="profile-tab-pane" aria-selected="false">Profile</button>
  </li>
  <li class="nav-item" role="presentation">
    <button class="nav-link" id="contact-tab" data-bs-toggle="tab" data-bs-target="#contact-tab-pane" type="button" role="tab" aria-controls="contact-tab-pane" aria-selected="false">Contact</button>
  </li>
  <li class="nav-item" role="presentation">
    <button class="nav-link" id="disabled-tab" data-bs-toggle="tab" data-bs-target="#disabled-tab-pane" type="button" role="tab" aria-controls="disabled-tab-pane" aria-selected="false" disabled>Disabled</button>
  </li>
</ul>
<div class="tab-content" id="myTabContent">
  <div class="tab-pane fade show active" id="home-tab-pane" role="tabpanel" aria-labelledby="home-tab" tabindex="0">...</div>
  <div class="tab-pane fade" id="profile-tab-pane" role="tabpanel" aria-labelledby="profile-tab" tabindex="0">...</div>
  <div class="tab-pane fade" id="contact-tab-pane" role="tabpanel" aria-labelledby="contact-tab" tabindex="0">...</div>
  <div class="tab-pane fade" id="disabled-tab-pane" role="tabpanel" aria-labelledby="disabled-tab" tabindex="0">...</div>
</div>

이것은 <ul> 기반 마크업, 또는 임의의 "직접 만든(roll your own)" 마크업과도 동작합니다. <nav>를 사용한다면 role="tablist"를 직접 추가하지 말아야 합니다. 그러면 요소의 네이티브 role인 navigation landmark를 덮어쓰기 때문입니다. 대신 대체 요소(아래 예시에서는 단순한 <div>)로 전환하고 그 주위를 <nav>로 감싸세요.

<nav>
  <div class="nav nav-tabs" id="nav-tab" role="tablist">
    <button class="nav-link active" id="nav-home-tab" data-bs-toggle="tab" data-bs-target="#nav-home" type="button" role="tab" aria-controls="nav-home" aria-selected="true">Home</button>
    <button class="nav-link" id="nav-profile-tab" data-bs-toggle="tab" data-bs-target="#nav-profile" type="button" role="tab" aria-controls="nav-profile" aria-selected="false">Profile</button>
    <button class="nav-link" id="nav-contact-tab" data-bs-toggle="tab" data-bs-target="#nav-contact" type="button" role="tab" aria-controls="nav-contact" aria-selected="false">Contact</button>
    <button class="nav-link" id="nav-disabled-tab" data-bs-toggle="tab" data-bs-target="#nav-disabled" type="button" role="tab" aria-controls="nav-disabled" aria-selected="false" disabled>Disabled</button>
  </div>
</nav>
<div class="tab-content" id="nav-tabContent">
  <div class="tab-pane fade show active" id="nav-home" role="tabpanel" aria-labelledby="nav-home-tab" tabindex="0">...</div>
  <div class="tab-pane fade" id="nav-profile" role="tabpanel" aria-labelledby="nav-profile-tab" tabindex="0">...</div>
  <div class="tab-pane fade" id="nav-contact" role="tabpanel" aria-labelledby="nav-contact-tab" tabindex="0">...</div>
  <div class="tab-pane fade" id="nav-disabled" role="tabpanel" aria-labelledby="nav-disabled-tab" tabindex="0">...</div>
</div>

탭 플러그인은 pills에서도 동작합니다.

<ul class="nav nav-pills mb-3" id="pills-tab" role="tablist">
  <li class="nav-item" role="presentation">
    <button class="nav-link active" id="pills-home-tab" data-bs-toggle="pill" data-bs-target="#pills-home" type="button" role="tab" aria-controls="pills-home" aria-selected="true">Home</button>
  </li>
  <li class="nav-item" role="presentation">
    <button class="nav-link" id="pills-profile-tab" data-bs-toggle="pill" data-bs-target="#pills-profile" type="button" role="tab" aria-controls="pills-profile" aria-selected="false">Profile</button>
  </li>
  <li class="nav-item" role="presentation">
    <button class="nav-link" id="pills-contact-tab" data-bs-toggle="pill" data-bs-target="#pills-contact" type="button" role="tab" aria-controls="pills-contact" aria-selected="false">Contact</button>
  </li>
  <li class="nav-item" role="presentation">
    <button class="nav-link" id="pills-disabled-tab" data-bs-toggle="pill" data-bs-target="#pills-disabled" type="button" role="tab" aria-controls="pills-disabled" aria-selected="false" disabled>Disabled</button>
  </li>
</ul>
<div class="tab-content" id="pills-tabContent">
  <div class="tab-pane fade show active" id="pills-home" role="tabpanel" aria-labelledby="pills-home-tab" tabindex="0">...</div>
  <div class="tab-pane fade" id="pills-profile" role="tabpanel" aria-labelledby="pills-profile-tab" tabindex="0">...</div>
  <div class="tab-pane fade" id="pills-contact" role="tabpanel" aria-labelledby="pills-contact-tab" tabindex="0">...</div>
  <div class="tab-pane fade" id="pills-disabled" role="tabpanel" aria-labelledby="pills-disabled-tab" tabindex="0">...</div>
</div>

세로 pills와 함께. 이상적으로는 세로 탭에 대해 탭 리스트 컨테이너에 aria-orientation="vertical"도 추가해야 합니다.

<div class="d-flex align-items-start">
  <div class="nav flex-column nav-pills me-3" id="v-pills-tab" role="tablist" aria-orientation="vertical">
    <button class="nav-link active" id="v-pills-home-tab" data-bs-toggle="pill" data-bs-target="#v-pills-home" type="button" role="tab" aria-controls="v-pills-home" aria-selected="true">Home</button>
    <button class="nav-link" id="v-pills-profile-tab" data-bs-toggle="pill" data-bs-target="#v-pills-profile" type="button" role="tab" aria-controls="v-pills-profile" aria-selected="false">Profile</button>
    <button class="nav-link" id="v-pills-disabled-tab" data-bs-toggle="pill" data-bs-target="#v-pills-disabled" type="button" role="tab" aria-controls="v-pills-disabled" aria-selected="false" disabled>Disabled</button>
    <button class="nav-link" id="v-pills-messages-tab" data-bs-toggle="pill" data-bs-target="#v-pills-messages" type="button" role="tab" aria-controls="v-pills-messages" aria-selected="false">Messages</button>
    <button class="nav-link" id="v-pills-settings-tab" data-bs-toggle="pill" data-bs-target="#v-pills-settings" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false">Settings</button>
  </div>
  <div class="tab-content" id="v-pills-tabContent">
    <div class="tab-pane fade show active" id="v-pills-home" role="tabpanel" aria-labelledby="v-pills-home-tab" tabindex="0">...</div>
    <div class="tab-pane fade" id="v-pills-profile" role="tabpanel" aria-labelledby="v-pills-profile-tab" tabindex="0">...</div>
    <div class="tab-pane fade" id="v-pills-disabled" role="tabpanel" aria-labelledby="v-pills-disabled-tab" tabindex="0">...</div>
    <div class="tab-pane fade" id="v-pills-messages" role="tabpanel" aria-labelledby="v-pills-messages-tab" tabindex="0">...</div>
    <div class="tab-pane fade" id="v-pills-settings" role="tabpanel" aria-labelledby="v-pills-settings-tab" tabindex="0">...</div>
  </div>
</div>

접근성 (Accessibility)

ARIA Authoring Practices Guide의 tabs 패턴에 설명된 동적 탭 인터페이스는 구조, 기능, 현재 상태를 스크린 리더 같은 보조 기술 사용자에게 전달하기 위해 role="tablist", role="tab", role="tabpanel", 추가 aria- 속성이 필요합니다. 모범 사례로, 탭에는 새 페이지나 위치로 이동하는 링크가 아니라 동적 변경을 트리거하는 컨트롤이므로 <button> 요소를 사용하는 것을 권장합니다.

ARIA Authoring Practices 패턴에 따라 현재 활성 탭만 키보드 포커스를 받습니다. JavaScript 플러그인이 초기화되면 모든 비활성 탭 컨트롤에 tabindex="-1"을 설정합니다. 현재 활성 탭이 포커스를 받으면 커서 키가 이전/다음 탭을 활성화합니다. Home과 End 키는 각각 첫 번째와 마지막 탭을 활성화합니다. 플러그인은 그에 따라 이동하는 tabindex를 변경합니다. 단, JavaScript 플러그인은 커서 키 상호작용에서 가로/세로 탭 리스트를 구분하지 않는다는 점에 주의하세요: 탭 리스트 방향과 무관하게 위와 왼쪽 커서는 이전 탭으로, 아래와 오른쪽 커서는 다음 탭으로 이동합니다.

일반적으로 키보드 탐색을 돕기 위해, 탭 패널 안에서 의미 있는 콘텐츠를 포함한 첫 번째 요소가 이미 포커스 가능하지 않다면 탭 패널 자체도 포커스 가능하게 만드는 것을 권장합니다. JavaScript 플러그인은 이 측면을 처리하려 하지 않으므로, 적절한 곳에서는 마크업에 tabindex="0"을 추가해 탭 패널을 명시적으로 포커스 가능하게 만들어야 합니다.

탭 JavaScript 플러그인은 드롭다운 메뉴를 포함하는 탭 인터페이스를 지원하지 않습니다. 사용성과 접근성 문제를 모두 일으키기 때문입니다. 사용성 관점에서, 현재 표시된 탭의 트리거 요소가 닫힌 드롭다운 메뉴 안에 있어 즉시 보이지 않는다는 사실이 혼란을 일으킬 수 있습니다. 접근성 관점에서 현재 이런 구조를 표준 WAI ARIA 패턴에 매핑할 합리적인 방법이 없어, 보조 기술 사용자가 쉽게 이해할 수 있게 만들 수 없습니다.

data 속성 사용하기 (Using data attributes)

JavaScript를 전혀 작성하지 않고 요소에 data-bs-toggle="tab" 또는 data-bs-toggle="pill"을 지정하기만 하면 탭이나 pill 네비게이션을 활성화할 수 있습니다. .nav-tabs나 .nav-pills에 이 data 속성들을 사용하세요.

<!-- Nav tabs -->
<ul class="nav nav-tabs" id="myTab" role="tablist">
  <li class="nav-item" role="presentation">
    <button class="nav-link active" id="home-tab" data-bs-toggle="tab" data-bs-target="#home" type="button" role="tab" aria-controls="home" aria-selected="true">Home</button>
  </li>
  <li class="nav-item" role="presentation">
    <button class="nav-link" id="profile-tab" data-bs-toggle="tab" data-bs-target="#profile" type="button" role="tab" aria-controls="profile" aria-selected="false">Profile</button>
  </li>
  <li class="nav-item" role="presentation">
    <button class="nav-link" id="messages-tab" data-bs-toggle="tab" data-bs-target="#messages" type="button" role="tab" aria-controls="messages" aria-selected="false">Messages</button>
  </li>
  <li class="nav-item" role="presentation">
    <button class="nav-link" id="settings-tab" data-bs-toggle="tab" data-bs-target="#settings" type="button" role="tab" aria-controls="settings" aria-selected="false">Settings</button>
  </li>
</ul>

<!-- Tab panes -->
<div class="tab-content">
  <div class="tab-pane active" id="home" role="tabpanel" aria-labelledby="home-tab" tabindex="0">...</div>
  <div class="tab-pane" id="profile" role="tabpanel" aria-labelledby="profile-tab" tabindex="0">...</div>
  <div class="tab-pane" id="messages" role="tabpanel" aria-labelledby="messages-tab" tabindex="0">...</div>
  <div class="tab-pane" id="settings" role="tabpanel" aria-labelledby="settings-tab" tabindex="0">...</div>
</div>

JavaScript로 (Via JavaScript)

JavaScript로 탭 가능한 tabs를 활성화하세요(각 탭을 개별적으로 활성화해야 합니다):

const triggerTabList = document.querySelectorAll('#myTab button')
triggerTabList.forEach(triggerEl => {
  const tabTrigger = new bootstrap.Tab(triggerEl)

  triggerEl.addEventListener('click', event => {
    event.preventDefault()
    tabTrigger.show()
  })
})

여러 방법으로 개별 탭을 활성화할 수 있습니다:

const triggerEl = document.querySelector('#myTab button[data-bs-target="#profile"]')
bootstrap.Tab.getInstance(triggerEl).show() // Select tab by name

const triggerFirstTabEl = document.querySelector('#myTab li:first-child button')
bootstrap.Tab.getInstance(triggerFirstTabEl).show() // Select first tab

Fade 효과 (Fade effect)

탭이 페이드 인되게 하려면 각 .tab-pane에 .fade를 추가하세요. 첫 번째 탭 패널은 초기 콘텐츠를 보이게 하기 위해 .show도 가져야 합니다.

<div class="tab-content">
  <div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab" tabindex="0">...</div>
  <div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab" tabindex="0">...</div>
  <div class="tab-pane fade" id="messages" role="tabpanel" aria-labelledby="messages-tab" tabindex="0">...</div>
  <div class="tab-pane fade" id="settings" role="tabpanel" aria-labelledby="settings-tab" tabindex="0">...</div>
</div>

메서드 (Methods)

모든 API 메서드는 비동기이며 전환을 시작합니다. 전환이 시작되는 즉시 호출자에게 반환되지만, 끝나기 전에 반환됩니다. 또한 전환 중인 컴포넌트에 대한 메서드 호출은 무시됩니다. JavaScript 문서에서 자세히 알아보세요.

콘텐츠를 탭 요소로 활성화합니다.

생성자를 사용해 탭 인스턴스를 만들 수 있습니다. 예를 들어:

const bsTab = new bootstrap.Tab('#myTab')
메서드 설명
dispose 요소의 탭을 파괴합니다.
getInstance DOM 요소와 연결된 탭 인스턴스를 가져올 수 있게 해 주는 정적 메서드입니다. 이렇게 사용할 수 있습니다: bootstrap.Tab.getInstance(element).
getOrCreateInstance DOM 요소와 연결된 탭 인스턴스를 반환하거나, 초기화되지 않은 경우 새로 만드는 정적 메서드입니다. 이렇게 사용할 수 있습니다: bootstrap.Tab.getOrCreateInstance(element).
show 주어진 탭을 선택하고 연결된 패널을 표시합니다. 이전에 선택된 다른 탭은 선택 해제되고 연결된 패널은 숨겨집니다. 탭 패널이 실제로 표시되기 전에(shown.bs.tab 이벤트 전에) 호출자에게 반환합니다.

이벤트 (Events)

새 탭을 표시할 때 이벤트는 다음 순서로 발생합니다:

  • hide.bs.tab (현재 활성 탭에서)
  • show.bs.tab (표시될 탭에서)
  • hidden.bs.tab (이전 활성 탭에서, hide.bs.tab 이벤트와 같은 탭)
  • shown.bs.tab (갓 표시된 새 활성 탭에서, show.bs.tab 이벤트와 같은 탭)

이미 활성화된 탭이 없었다면 hide.bs.tab과 hidden.bs.tab 이벤트는 발생하지 않습니다.

이벤트 타입 설명
hide.bs.tab 새 탭이 표시될 때(즉, 이전 활성 탭이 숨겨질 때) 발생하는 이벤트입니다. event.target과 event.relatedTarget을 사용해 각각 현재 활성 탭과 곧 활성화될 새 탭을 대상으로 하세요.
hidden.bs.tab 새 탭이 표시된 후(즉, 이전 활성 탭이 숨겨진 후) 발생하는 이벤트입니다. event.target과 event.relatedTarget을 사용해 각각 이전 활성 탭과 새 활성 탭을 대상으로 하세요.
show.bs.tab 탭 표시 시, 새 탭이 표시되기 전에 발생하는 이벤트입니다. event.target과 event.relatedTarget을 사용해 각각 활성 탭과 이전 활성 탭(가능한 경우)을 대상으로 하세요.
shown.bs.tab 탭이 표시된 후 탭 표시 시 발생하는 이벤트입니다. event.target과 event.relatedTarget을 사용해 각각 활성 탭과 이전 활성 탭(가능한 경우)을 대상으로 하세요.
const tabEl = document.querySelector('button[data-bs-toggle="tab"]')
tabEl.addEventListener('shown.bs.tab', event => {
  event.target // newly activated tab
  event.relatedTarget // previous active tab
})

더 알아보기 (Learn more)