• Tabs New

    A set of label elements with hidden radio inputs inside a .tabs container. No JavaScript needed -- CSS :has() handles panel switching.

    Default

    • Each label wraps a hidden radio input. Add checked to set the default tab.
      CSS uses :has() to watch the checked state inside [role="tablist"] and show the panel at the matching position, with no JavaScript.
    • Give the header role="tablist" and an aria-label.
      The tab bar styling targets [role="tablist"] directly. Screen readers also use this to announce the group and let users navigate between tabs.
    • Connect each input to its panel with matching id and aria-controls.
      Lets assistive technology jump directly from a tab to its associated content.
    • Mark each panel with role="tabpanel", aria-labelledby, and tabindex="0".
      All [role="tabpanel"] elements are hidden by default. The Nth panel is revealed when the Nth tab is checked. aria-labelledby names the panel after its tab, and tabindex="0" makes it reachable by keyboard.

    Manage your account settings and preferences.

    Change your password and security settings.

    Configure how and when you receive notifications.

    <section class="tabs">
      <header role="tablist" aria-label="Account settings">
        <label>
          <input
            type="radio"
            name="tabs"
            id="tab-1"
            checked
            aria-controls="panel-1"
          />
          Account
        </label>
        <label>
          <input type="radio" name="tabs" id="tab-2" aria-controls="panel-2" />
          Password
        </label>
        <label>
          <input type="radio" name="tabs" id="tab-3" aria-controls="panel-3" />
          Notifications
        </label>
      </header>
    
      <div role="tabpanel" id="panel-1" aria-labelledby="tab-1" tabindex="0">
        <p>Manage your account settings and preferences.</p>
      </div>
      <div role="tabpanel" id="panel-2" aria-labelledby="tab-2" tabindex="0">
        <p>Change your password and security settings.</p>
      </div>
      <div role="tabpanel" id="panel-3" aria-labelledby="tab-3" tabindex="0">
        <p>Configure how and when you receive notifications.</p>
      </div>
    </section>

    Disabled tab

    Add disabled to the radio input to disable a tab.

    Overview content goes here.

    Analytics content goes here.

    Reports content goes here.

    <section class="tabs">
      <header role="tablist" aria-label="Dashboard">
        <label>
          <input
            type="radio"
            name="tabs"
            id="tab-1"
            checked
            aria-controls="panel-1"
          />
          Overview
        </label>
        <label>
          <input type="radio" name="tabs" id="tab-2" aria-controls="panel-2" />
          Analytics
        </label>
        <label>
          <input
            type="radio"
            name="tabs"
            id="tab-3"
            disabled
            aria-controls="panel-3"
          />
          Reports
        </label>
      </header>
    
      <div role="tabpanel" id="panel-1" aria-labelledby="tab-1" tabindex="0">
        Overview content goes here.
      </div>
      <div role="tabpanel" id="panel-2" aria-labelledby="tab-2" tabindex="0">
        Analytics content goes here.
      </div>
      <div role="tabpanel" id="panel-3" aria-labelledby="tab-3" tabindex="0">
        Reports content goes here.
      </div>
    </section>

    With content

    Tab panels can contain any content.

    Name Role Status
    Alice Engineer Active
    Bob Designer Away
    Carol Manager Active

    No activity yet

    Actions taken by your team will appear here.

    Role
  • <section class="tabs" style="display: grid; gap: 1rem">
      <header role="tablist" aria-label="Team">
        <label>
          <input
            type="radio"
            name="tabs"
            id="tab-1"
            checked
            aria-controls="panel-1"
          />
          Members
        </label>
        <label>
          <input type="radio" name="tabs" id="tab-2" aria-controls="panel-2" />
          Activity
        </label>
        <label>
          <input type="radio" name="tabs" id="tab-3" aria-controls="panel-3" />
          Invite
        </label>
      </header>
    
      <div role="tabpanel" id="panel-1" aria-labelledby="tab-1" tabindex="0">
        <table>
          <thead>
            <tr>
              <th>Name</th>
              <th>Role</th>
              <th>Status</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Alice</td>
              <td>Engineer</td>
              <td>Active</td>
            </tr>
            <tr>
              <td>Bob</td>
              <td>Designer</td>
              <td>Away</td>
            </tr>
            <tr>
              <td>Carol</td>
              <td>Manager</td>
              <td>Active</td>
            </tr>
          </tbody>
        </table>
      </div>
    
      <div role="tabpanel" id="panel-2" aria-labelledby="tab-2" tabindex="0">
        <section class="empty">
          <svg><!-- icon --></svg>
          <h3>No activity yet</h3>
          <p>Actions taken by your team will appear here.</p>
        </section>
      </div>
    
      <div role="tabpanel" id="panel-3" aria-labelledby="tab-3" tabindex="0">
        <form style="display: grid; gap: 1em">
          <label class="field">
            <span>Email address</span>
            <input type="email" placeholder="colleague@example.com" />
          </label>
          <div class="field">
            <span>Role</span>
            <button type="button" class="outlined" popovertarget="role">
              Member
            </button>
            <div id="role" popover>
              <menu>
                <li>
                  <label>
                    <input type="radio" name="role" value="member" checked /> Member
                  </label>
                </li>
                <li>
                  <label>
                    <input type="radio" name="role" value="admin" /> Admin
                  </label>
                </li>
                <li>
                  <label>
                    <input type="radio" name="role" value="viewer" /> Viewer
                  </label>
                </li>
              </menu>
            </div>
          </div>
          <button type="submit">Send invite</button>
        </form>
      </div>
    </section>

    Nested

    Tabs can be nested freely. Each level is fully independent — switching tabs in the outer component has no effect on the inner one and vice versa.

    Outer panel one — contains a nested tabs:

    There's another tabs component in the other tab

    Woof

    Meow

    Outer panel two.

    <!-- Level 1 -->
    <section class="tabs first">
      <header role="tablist" aria-label="Outer tabs">
        <label> <input type="radio" name="outer" checked /> Overview </label>
        <label><input type="radio" name="outer" /> Settings</label>
      </header>
    
      <div role="tabpanel">
        <p>Outer panel one — contains a nested tabs:</p>
        <!-- Level 2 -->
        <section class="tabs second">
          <header role="tablist" aria-label="Inner tabs">
            <label><input type="radio" name="inner" /> Info</label>
            <label> <input type="radio" name="inner" checked /> Animals </label>
          </header>
    
          <div role="tabpanel">
            <p>There's another tabs component in the other tab</p>
          </div>
          <div role="tabpanel">
            <!-- Level 3 -->
            <section class="tabs third">
              <header role="tablist" aria-label="Inner tabs">
                <label> <input type="radio" name="third" checked /> Dog </label>
                <label><input type="radio" name="third" /> Cat</label>
              </header>
    
              <div role="tabpanel"><p>Woof</p></div>
              <div role="tabpanel"><p>Meow</p></div>
            </section>
          </div>
        </section>
      </div>
    
      <div role="tabpanel">
        <p>Outer panel two.</p>
      </div>
    </section>
    
    <style>
      .tabs {
        padding: 1rem;
    
        .first {
          border: 1px solid var(--ui-neutral-100);
        }
    
        .second {
          background-color: var(--ui-neutral-100);
        }
    
        .third {
          background-color: var(--ui-neutral-0);
        }
      }
    </style>

    Search 5021 icons

    Type a name to find icons from the Tabler icon set.