tab-navigation

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Tab Navigation

选项卡导航

Tabs organise related content under a shared context. The tab strip communicates the full set of available views; switching tabs swaps the content panel without a page navigation. They work best when all views share a heading, a primary action, or a common subject — tabs that have nothing to do with each other belong in separate pages.

选项卡(Tabs)将相关内容归置在同一上下文下。选项卡栏会展示所有可用视图;切换选项卡时,无需页面导航即可替换内容面板。当所有视图共享一个标题、主要操作或共同主题时,选项卡的效果最佳——彼此无关的选项卡应放在单独页面中。

When to Use Tabs — and When Not To

何时使用选项卡——何时不使用

Use tabs when…Use something else when…
2–7 views share a common context (same record, same settings section)There are more than 7–8 tabs — use a sidebar or section nav instead
Users switch between views frequently during a sessionThe content is sequential (use a stepper/wizard instead)
All tabs are equally valid entry pointsOne view is clearly primary — put the rest in a secondary nav or overflow
The views share a header or set of page-level actionsEach "tab" requires a different header and layout — use separate pages

适用场景…适用其他方案的场景…
2–7个视图共享同一上下文(同一记录、同一设置板块)选项卡数量超过7–8个——改用侧边栏或板块导航
用户在会话期间需要频繁切换视图内容为顺序流程(改用分步向导)
所有选项卡都是同等有效的入口点某个视图明显是主要内容——将其余视图放在二级导航或溢出菜单中
视图共享同一标题或一组页面级操作每个“选项卡”需要不同的标题和布局——使用单独页面

Tab Types

选项卡类型

Choose the visual style that fits the layout context.
选择适合布局上下文的视觉样式。

Underline / Indicator Tabs

下划线/指示器选项卡

A horizontal strip with a sliding underline or bottom border on the active tab. The lightest treatment — appropriate for page-level tabs where the tab strip sits inside the content area.
Overview  |  Activity  |  Settings
──────────
带有滑动下划线或底部边框的水平栏,当前选中的选项卡会显示该标识。视觉权重最轻——适用于选项卡栏位于内容区域内的页面级选项卡。
Overview  |  Activity  |  Settings
──────────

Contained / Boxed Tabs

容器/盒装选项卡

Each tab is a distinct box; the active tab appears connected to the panel below. Higher visual weight — appropriate for prominent tab groups near the top of a screen or within a card.
每个选项卡都是独立的盒子;选中的选项卡看起来与下方的面板相连。视觉权重较高——适用于屏幕顶部或卡片内的突出选项卡组。

Pill / Button Tabs

胶囊/按钮式选项卡

Rounded capsules that toggle between states. Lower emphasis — appropriate for secondary content switches within a section (not page-level). Often used for view toggles (e.g. "List / Grid / Map").

可切换状态的圆角胶囊样式。视觉权重较低——适用于板块内的二级内容切换(非页面级)。常用于视图切换(例如“列表/网格/地图”)。

Anatomy

组件结构

┌─────────────────────────────────────────────────┐
│  Tab A  │  Tab B  │  Tab C  │                   │  ← Tab strip (role="tablist")
├─────────┴─────────────────────────────────────────┤
│                                                   │
│   Tab panel content                               │  ← Tab panel (role="tabpanel")
│                                                   │
└───────────────────────────────────────────────────┘
  • Tab strip: Fixed height (typically 40–48px). Does not scroll with the page — consider making it sticky when the page is long.
  • Tab panel: Fills the remaining available height. The panel, not the tab strip, scrolls when content overflows.
  • Active indicator: A 2–3px bottom border in
    --color-primary
    for underline tabs; filled background for contained/pill tabs.

┌─────────────────────────────────────────────────┐
│  Tab A  │  Tab B  │  Tab C  │                   │  ← Tab strip (role="tablist")
├─────────┴─────────────────────────────────────────┤
│                                                   │
│   Tab panel content                               │  ← Tab panel (role="tabpanel")
│                                                   │
└───────────────────────────────────────────────────┘
  • Tab strip(选项卡栏): 固定高度(通常为40–48px)。不随页面滚动——当页面较长时,可将其设置为粘性定位。
  • Tab panel(选项卡面板): 填充剩余可用高度。当内容溢出时,滚动的是面板而非选项卡栏。
  • Active indicator(选中标识): 下划线选项卡使用
    --color-primary
    颜色的2–3px底部边框;容器/胶囊选项卡使用填充背景。

States

状态

StateVisual treatment
ActivePrimary colour indicator; label in
--color-text-primary
or primary
InactiveMuted label (
--color-text-secondary
); no indicator
HoverSubtle background shift (
--color-grey-50
); label slightly darkens
FocusVisible focus ring (
outline: 2px solid --color-primary; outline-offset: 2px
)
DisabledReduced opacity (
0.4
);
cursor: not-allowed
; never the active tab
Never disable the active tab. If content is unavailable, show it inside the panel with an explanation rather than disabling the tab.

状态视觉处理
选中主色调标识;标签使用
--color-text-primary
或主色调
未选中标签颜色弱化(
--color-text-secondary
);无标识
悬停背景轻微变化(
--color-grey-50
);标签颜色略微加深
聚焦显示可见的聚焦环(
outline: 2px solid --color-primary; outline-offset: 2px
禁用透明度降低(
0.4
);
cursor: not-allowed
;永远不会是选中状态
切勿禁用已选中的选项卡。如果内容不可用,应在面板内显示说明,而非禁用选项卡。

Tab Overflow

选项卡溢出处理

When the tab strip is wider than the viewport or container, do not wrap tabs onto multiple lines — it destroys the strip metaphor.
当选项卡栏宽于视口或容器时,请勿将选项卡换行显示——这会破坏选项卡栏的隐喻。

Scrollable strip

可滚动栏

The strip scrolls horizontally. Show a fade/gradient at the right edge to signal overflow. On touch devices this is the preferred solution.
css
.tab-strip {
  display: flex;
  overflow-x: auto;
  scrollbar-width: none; /* hide scrollbar visually on desktop */
}
.tab-strip::after {
  content: '';
  position: absolute; right: 0;
  background: linear-gradient(to left, var(--color-surface), transparent);
  pointer-events: none;
}
选项卡栏可水平滚动。在右侧边缘显示渐变效果以提示存在溢出内容。在触摸设备上,这是首选解决方案。
css
.tab-strip {
  display: flex;
  overflow-x: auto;
  scrollbar-width: none; /* hide scrollbar visually on desktop */
}
.tab-strip::after {
  content: '';
  position: absolute; right: 0;
  background: linear-gradient(to left, var(--color-surface), transparent);
  pointer-events: none;
}

"More" overflow menu

“更多”溢出菜单

Show as many tabs as fit, then collapse the rest into a
More ▾
dropdown. Update the "More" label when an overflowed tab is active:
Settings ▾
(showing the active hidden tab name).
For desktop dashboards with many views, prefer a sidebar nav over overflow tabs.

显示尽可能多的选项卡,将剩余的折叠到“更多 ▾”下拉菜单中。当溢出的选项卡被选中时,更新“更多”标签:
Settings ▾
(显示当前选中的隐藏选项卡名称)。
对于包含多个视图的桌面仪表板,优先使用侧边栏导航而非溢出选项卡。

Vertical Tabs

垂直选项卡

Use when there are 5+ tabs and the layout has a left sidebar. Vertical tabs allow longer labels without overflow issues and scale more gracefully.
  • Fixed width sidebar (typically 200–240px) with tab labels stacked vertically
  • Active tab: left border accent (
    3px solid --color-primary
    ) + subtle background
  • The main content area fills the remaining width

当选项卡数量为5个及以上且布局包含左侧侧边栏时使用。垂直选项卡允许更长的标签文本而不会出现溢出问题,且扩展性更好。
  • 固定宽度的侧边栏(通常为200–240px),选项卡标签垂直堆叠
  • 选中的选项卡:左侧边框强调色(
    3px solid --color-primary
    )+ 轻微背景变化
  • 主内容区域填充剩余宽度

Keyboard Navigation

键盘导航

Tabs follow the ARIA "roving tabindex" pattern for within-strip navigation.
KeyAction
Tab
Move focus to the tab strip (then into the active panel)
/
Move between tabs (horizontal strip); activate immediately or on Enter depending on content cost
/
Move between tabs (vertical strip)
Home
Jump to first tab
End
Jump to last tab
Enter
/
Space
Activate focused tab (if not already auto-activating on arrow key)
Auto-activate vs. manual activate: If switching tabs triggers a network request, use manual activation (arrow keys move focus, Enter activates) to avoid unnecessary fetches. If content is already loaded or cheap, auto-activation on arrow key is acceptable.

选项卡遵循ARIA的“roving tabindex”模式进行栏内导航。
按键操作
Tab
将焦点移至选项卡栏(然后进入选中的面板)
/
在选项卡间切换(水平栏);根据内容加载成本,立即激活或按Enter激活
/
在选项卡间切换(垂直栏)
Home
跳转到第一个选项卡
End
跳转到最后一个选项卡
Enter
/
Space
激活获得焦点的选项卡(如果未设置为按箭头键自动激活)
自动激活 vs 手动激活: 如果切换选项卡会触发网络请求,请使用手动激活(箭头键移动焦点,Enter激活)以避免不必要的请求。如果内容已加载或加载成本低,按箭头键自动激活是可接受的。

ARIA

ARIA

html
<div role="tablist" aria-label="Product sections">
  <button
    role="tab"
    id="tab-overview"
    aria-selected="true"
    aria-controls="panel-overview"
    tabindex="0"
  >Overview</button>
  <button
    role="tab"
    id="tab-activity"
    aria-selected="false"
    aria-controls="panel-activity"
    tabindex="-1"
  >Activity</button>
</div>

<div
  role="tabpanel"
  id="panel-overview"
  aria-labelledby="tab-overview"
></div>

<div
  role="tabpanel"
  id="panel-activity"
  aria-labelledby="tab-activity"
  hidden
></div>
  • aria-selected="true"
    on the active tab,
    false
    on all others
  • tabindex="0"
    on the active tab,
    -1
    on all others (roving tabindex)
  • hidden
    attribute (or
    display: none
    ) on inactive panels — screen readers skip hidden panels
  • aria-label
    on the
    tablist
    when the heading above doesn't sufficiently describe the group

html
<div role="tablist" aria-label="Product sections">
  <button
    role="tab"
    id="tab-overview"
    aria-selected="true"
    aria-controls="panel-overview"
    tabindex="0"
  >Overview</button>
  <button
    role="tab"
    id="tab-activity"
    aria-selected="false"
    aria-controls="panel-activity"
    tabindex="-1"
  >Activity</button>
</div>

<div
  role="tabpanel"
  id="panel-overview"
  aria-labelledby="tab-overview"
></div>

<div
  role="tabpanel"
  id="panel-activity"
  aria-labelledby="tab-activity"
  hidden
></div>
  • 选中的选项卡设置
    aria-selected="true"
    ,其他选项卡设置
    false
  • 选中的选项卡设置
    tabindex="0"
    ,其他选项卡设置
    -1
    (roving tabindex)
  • 未选中的面板设置
    hidden
    属性(或
    display: none
    )——屏幕阅读器会跳过隐藏的面板
  • 当上方的标题无法充分描述选项卡组时,在
    tablist
    上设置
    aria-label

State Persistence

状态持久化

Remember the active tab across page loads and navigations:
  • URL fragment or query param:
    ?tab=activity
    — the most robust approach; supports deep linking and browser back/forward
  • localStorage: Acceptable for preferences (e.g. a preferred dashboard view) that don't need to be shareable
  • Do not use
    sessionStorage
    — tabs closing lose the state unexpectedly
When the URL contains a tab param, jump to that tab on load even if it's not the first tab.

在页面加载和导航过程中记住选中的选项卡:
  • URL片段或查询参数:
    ?tab=activity
    ——最可靠的方案;支持深度链接和浏览器前进/后退
  • localStorage: 适用于无需共享的偏好设置(例如首选的仪表板视图)
  • 请勿使用
    sessionStorage
    ——关闭标签页会意外丢失状态
当URL包含选项卡参数时,加载页面时直接跳转到该选项卡,即使它不是第一个选项卡。

Nested Tabs

嵌套选项卡

Avoid tabs within tabs. Nested tabbing creates confusion about scope — a user editing content in "Tab A › Sub-tab 2" has no clear mental model of what the outer tab means.
If you find yourself nesting tabs, reconsider the information architecture:
  • Can the inner tabs become a secondary nav (pills, a sidebar within the panel)?
  • Can the outer tabs become a top-level page nav instead?
One level of tabs maximum in the primary content area.

避免选项卡嵌套。嵌套选项卡会造成范围混淆——用户在“选项卡A › 子选项卡2”中编辑内容时,无法清晰理解外层选项卡的含义。
如果必须使用嵌套选项卡,请重新考虑信息架构:
  • 内层选项卡能否改为二级导航(胶囊按钮、面板内的侧边栏)?
  • 外层选项卡能否改为顶级页面导航?
主内容区域最多只能有一层选项卡。

Review Checklist

审核清单

  • Are there 2–7 tabs, each sharing a common subject or context?
  • Is the tab strip not wrapping to multiple lines on any target viewport?
  • Does tab overflow use scrollable strip or a "More" menu — not wrapping?
  • Is the active tab clearly distinguished by colour and/or indicator?
  • Do hover and focus states meet contrast requirements?
  • Are disabled tabs avoided (showing unavailability inside the panel instead)?
  • Does keyboard navigation follow roving tabindex (←/→ between tabs, Tab into panel)?
  • Is
    role="tablist"
    ,
    role="tab"
    ,
    role="tabpanel"
    , and
    aria-selected
    set correctly?
  • Are inactive panels hidden from the accessibility tree (
    hidden
    attribute)?
  • Is the active tab persisted in the URL (for deep-linkable views) or localStorage?
  • Are nested tabs avoided?
  • 选项卡数量为2–7个,且每个选项卡共享同一主题或上下文?
  • 在任何目标视口上,选项卡栏都不会换行显示?
  • 选项卡溢出使用可滚动栏或“更多”菜单——而非换行?
  • 选中的选项卡通过颜色和/或标识清晰区分?
  • 悬停和聚焦状态满足对比度要求?
  • 避免使用禁用的选项卡(改为在面板内显示不可用说明)?
  • 键盘导航遵循roving tabindex模式(使用←/→在选项卡间切换,Tab进入面板)?
  • 正确设置了
    role="tablist"
    role="tab"
    role="tabpanel"
    aria-selected
  • 未选中的面板从无障碍树中隐藏(设置
    hidden
    属性)?
  • 选中的选项卡状态持久化在URL(支持深度链接的视图)或localStorage中?
  • 避免使用嵌套选项卡?