• 2

    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 radio input. Add checked to the first input to set the default tab. Panels are plain div elements placed after the labels. Give the header a role="tablist" and an aria-label, connect each input to its panel via id / aria-controls, and mark each panel with role="tabpanel", aria-labelledby, and tabindex="0" so keyboard users can Tab into the content.

    Manage your account settings and preferences.

    Change your password and security settings.

    Configure how and when you receive notifications.

    <section class="tabs" style="display: grid; gap: 1rem">
      <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"
        style="grid-column: 1; grid-row: 2"
      >
        <p>Manage your account settings and preferences.</p>
      </div>
      <div
        role="tabpanel"
        id="panel-2"
        aria-labelledby="tab-2"
        tabindex="0"
        style="grid-column: 1; grid-row: 2"
      >
        <p>Change your password and security settings.</p>
      </div>
      <div
        role="tabpanel"
        id="panel-3"
        aria-labelledby="tab-3"
        tabindex="0"
        style="grid-column: 1; grid-row: 2"
      >
        <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:

    Weekly view

    Monthly view

    Yearly view

    Outer panel two.

    <section class="tabs parent">
      <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">
        <section class="tabs child">
          <header role="tablist" aria-label="Inner tabs">
            <label><input type="radio" name="inner" checked /> Week</label>
            <label><input type="radio" name="inner" /> Month</label>
            <label><input type="radio" name="inner" /> Year</label>
          </header>
          <div role="tabpanel"><p>Weekly view</p></div>
          <div role="tabpanel"><p>Monthly view</p></div>
          <div role="tabpanel"><p>Yearly view</p></div>
        </section>
      </div>
    
      <div role="tabpanel">
        <p>Outer panel two.</p>
      </div>
    </section>
    
    <style>
      .tabs {
        padding: 1rem;
    
        .parent {
          border: 1px solid var(--ui-neutral-100);
        }
    
        .child {
          background-color: var(--ui-neutral-100);
        }
      }
    </style>

    Search 5021 icons

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