跳到主要内容
menumenu tanreiexpand_morecontrasttranslate
tanreiexpand_more
开始使用WebReactSwiftUIJetpack ComposeFlutterReact Native预设你自己的设计系统与 AI 代理一起使用 Tanrei品牌设计令牌设计系统与定制Theme Studio颜色字体排印图标形状层级动效交互状态行为布局无障碍文字颜色令牌字阶令牌形状令牌层级令牌动效令牌状态令牌间距与度量令牌组件按钮主操作按钮分段按钮按钮组带菜单的按钮工具栏复制按钮复选框单选按钮开关纸片(Chip)菜单滑块滑块字段日历DateTimePicker字段组单选组复选框组下拉选择框下拉选择字段菜单栏文件上传文件选择器 进阶放置区文本输入框 进阶文本字段纸片字段字段组合框 进阶组合框字段数字输入框 进阶数字字段颜色输入框 进阶颜色字段一次性验证码输入框 进阶一次性验证码字段嵌入式文本输入框 进阶聊天输入栏卡片分隔线模态层 进阶对话框列表列表行底部面板侧边面板轮播代码块表格弹出框步骤折叠面板描述列表图示应用外壳页头树视图时间线图片预览调整手柄可调整大小的框滚动区域徽标进度指示器计量条数字滚动器加载指示器消息条(Snackbar)工具提示键盘快捷键标签(Tag)行内代码提示块(Callout)头像空状态标签组(Tag group)骨架屏文件项色块跑马灯文本标签页标签页视图应用栏导航栏导航抽屉搜索链接分页上一页/下一页链接步骤条面包屑目录链接卡片FAB 菜单状态Tanrei 是如何构建的参与贡献许可与致谢
首页组件标签(Tag)

标签(Tag)

用一段简短的静态文字标出类别或状态,外观可以是柔和填充、带轮廓或实色填充;有语义状态时采用该状态的颜色。它是文本,从不是控件。

content_copy以 Markdown 格式查看
类别
信息传达
令牌
comp.tag
层级
基础

概览

Web
tanrei-tag
schedule
SwiftUI
TanreiTag
radio_button_unchecked
Jetpack Compose
TanreiTag
radio_button_unchecked
Flutter
TanreiTag
radio_button_unchecked
React Native
Tag
radio_button_unchecked

生成自 docs/status/status.json, specs/tag.spec.json

三种外观,带语义状态和不带语义状态

标签(Tag)是一个词或一个短语,说明某样东西是什么,或处于什么状态:文章的类别、构建的结果、版本所处的阶段、几个值当中的默认值。它位于布局之中,与旁边的文本同处一行,从不响应指针、按键或焦点。

在 Web 上它是 <tanrei-tag>。其他平台尚未实现。

用法

<tanrei-tag label="Beta"></tanrei-tag>
<tanrei-tag variant="outlined" label="设计"><span slot="icon">sell</span></tanrei-tag>

<!-- 标签的文字说出了状态。 -->
<tanrei-tag status="error" label="失败"></tanrei-tag>

<!-- 标签的文字没有说出状态:status-label 会在它之前朗读(“错误,3 个构建”),但不绘制。 -->
<tanrei-tag status="error" status-label="错误" label="3 个构建"></tanrei-tag>

<script type="module">
  import '@tanrei/web/components/tag';
</script>
import { Tag } from '@tanrei/react';

<Tag label="Beta" />
<Tag variant="outlined" label="设计"><span slot="icon">sell</span></Tag>
<Tag status="error" statusLabel="错误" label={`${failed} 个构建`} />

规格

每种外观在每种语义状态下的样子

两种尺寸、图标、圆点

sellsell

构成

构成

绘制在 Web 包所绘的测试样例 tonal 之上。
部件 说明
1 container The shape that holds the label: at least the height of its size, a pill in the default system, filled in the tonal and filled looks and edged in the outlined look. It carries no state: nothing about it answers a pointer, a press or focus.
2 label The word or short phrase the tag shows, on one line.
3 icon · 可选 A leading glyph of the system's icon set that the product names (a category's mark, a status's mark). Decorative: the label says what the tag means.
4 dot · 可选 A small filled circle in the leading position, in the look's mark color: the lightest way to show a status beside its word. Drawn where the product asks for it and no glyph is given, and always on an outlined tag that has a status.
5 outline · 可选 The outlined look's edge: one hairline inside the container, the same in every status.

尺寸

尺寸

长度 令牌 值(px)
container padding-inline tanrei.comp.tag.container.padding-inline.medium 8
container height tanrei.comp.tag.container.height.medium 24
绘制在 Web 包所绘的测试样例 tonal 之上。

属性

属性 类型 默认值 说明
label string "" The tag's text: a word or a short phrase ("Beta", "Out of stock"). It is what the tag draws and what assistive technology reads.
variant tonal | outlined | filled "tonal" How much the tag weighs. tonal: a quiet fill, the default. outlined: no fill and one hairline, for many tags close together. filled: a full fill, for the chosen one among its neighbours (the default among values, the required among fields) and for the one status that must not be missed.
status default | info | warning | error | success "default" What the tag reports, in the names the snackbar uses. default: a category or a neutral state, in the look's own colors. info, warning, error and success draw the look in that status's color roles. It changes colors only; the words are the label's and statusLabel's.
statusLabel string "" The status in words, in the product's language ("Error"), read by assistive technology before the label and not drawn. For a tag whose label does not itself say the status (an error tag that reads "3 builds"); a label that says it ("Failed") needs none. Ignored while status is default.
size small | medium "medium" Small (20 high, 12 text) follows a field's label, a table cell or a line of body text without making the line taller; medium (24 high, 14 text) stands beside a heading or by itself.
dot boolean false Draws the dot before the label, in the look's mark color. A glyph in the icon slot takes its place. An outlined tag with a status draws the dot whatever this says, because nothing else in that look shows the status.
disabled boolean false Draws the tag as part of something disabled — the label of a disabled field, a disabled row of a list, a disabled item of a menu — in its look's disabled colors, so that it fades with what it stands in. It changes nothing else: a tag takes no input and no focus, and what assistive technology hears of the disabled state it hears from the element the tag stands in. The component that holds the tag sets it (a Field does, for its requirement tag); a product sets it on a tag it places in a disabled element of its own.

插槽

插槽 说明
icon The leading glyph: a glyph of the system's icon set, drawn through the platform's icon helper at the tag's glyph size.

状态

行为

以 EARS 形式写成的需求。每个平台的实现都按这些 ID 逐条测试。需求原文取自规格文件,原样以英文呈现。

ID 需求
TAG-1 THE tag SHALL draw a container at least the height of its size (comp.tag.container.height.medium for medium, and so on) with corners comp.tag.container.shape, never larger than half the container's height (a pill where the value is sys.shape.corner.full, at any height the tag grows to) and eased by sys.shape.corner-smoothing, and lay out in one row its glyph or its dot, where it has one, and its label, comp.tag.container.gap apart; the start SHALL be padded by comp.tag.container.padding-inline-with-icon.medium where it holds the glyph or the dot and by comp.tag.container.padding-inline.medium where the label meets it, the end by comp.tag.container.padding-inline.medium, and the row's tallest item (the label's line or the glyph's box) SHALL be padded at the top and bottom by at least comp.tag.container.padding-block.medium (and so on for each size). THE tag SHALL be as wide as its content and its paddings, never wider than its layout gives it, and SHALL draw no elevation.
TAG-2 WHILE status is default THE tag SHALL fill its container with the container color of its variant and draw its label, and its glyph or dot, in that variant's label and icon colors: comp.tag.tonal.container.color, comp.tag.tonal.label.color and comp.tag.tonal.icon.color for tonal, and outlined's and filled's tokens of the same names (comp.tag.outlined.container.color, comp.tag.filled.container.color, and so on).
TAG-3 WHILE status is info, warning, error or success THE tag SHALL draw its container, its label and its glyph or dot from the parts of its variant prefixed with the status: for a tonal info tag comp.tag.tonal.info.container.color, comp.tag.tonal.info.label.color and comp.tag.tonal.info.icon.color; for outlined and filled, and for warning, error and success, their own tokens of the same names (comp.tag.outlined.error.icon.color, comp.tag.filled.success.container.color, and so on). A status SHALL change these colors only: the tag's size, shape, layout and edge stay those of its variant and size, and the tag SHALL NOT draw a glyph the product did not give.
TAG-4 WHILE variant is outlined THE tag SHALL draw an edge comp.tag.outline.width wide in comp.tag.outline.color inside its container's size, following its corners, in every status, without changing the tag's size or the place of its content; WHILE variant is tonal or filled it SHALL draw no edge. A status SHALL NOT color the edge: it is the system's one hairline.
TAG-5 THE tag SHALL set its label on one line in the text style of its size (comp.tag.label.typescale.medium for medium, and so on) and the label color of its look (TAG-2, TAG-3), SHALL NOT wrap it, and SHALL cut it with an ellipsis only when the layout gives the tag less width than the label needs, keeping its paddings and its glyph or dot whole; the full label SHALL remain what assistive technology reads.
TAG-6 WHERE the icon slot holds a glyph THE tag SHALL draw it before the label in a box of comp.tag.icon.size, centred on the label's line, in the icon color of its look (TAG-2, TAG-3), with sys.icon.family.unselected and sys.icon.fill.unselected, sys.icon.weight and an optical size clamped between sys.icon.optical-size.min and sys.icon.optical-size.max, SHALL keep it from assistive technology, and SHALL draw no mark of its own in its place.
TAG-7 WHILE dot is true and the icon slot is empty THE tag SHALL draw before the label a filled circle of diameter comp.tag.dot.size in the icon color of its look (TAG-2, TAG-3), centred on the label's line, a circle whatever corners the container has, and SHALL keep it from assistive technology; WHERE the icon slot holds a glyph THE tag SHALL draw the glyph and no dot.
TAG-8 WHILE variant is outlined and status is info, warning, error or success and the icon slot is empty THE tag SHALL draw the dot of TAG-7 whether dot is true or false, because an outlined tag keeps the surface's label color and the one hairline in every status, so its mark is the only place the status shows.
TAG-9 THE tag SHALL NOT take pointer, touch or keyboard input, SHALL NOT take focus or be a stop in the focus order, and SHALL NOT change anything it draws under a pointer, a press or focus: it has no hovered, focused, pressed or selected state and no disabled state of its own — disabled draws it as part of something disabled and changes nothing it does (TAG-21) — draws no state layer, no ripple and no focus indicator, and emits no event.
TAG-10 WHERE the tag is placed inside an element that takes input (a link, a button, a list item, a table row, a card that is pressed as a whole) THE tag SHALL let input over it reach that element, SHALL stay as it is drawn while that element is hovered, focused or pressed (the state is drawn by that element, on its own container), and SHALL add its text (TAG-11) to that element's content in reading order; it SHALL NOT become a second target inside it.
TAG-11 THE tag SHALL expose its label as plain text, read where the tag sits, with no role, name or state of its own; WHILE status is not default and statusLabel is not empty THE tag SHALL expose statusLabel before the label as part of that text, set apart so that the two are read as two phrases ("Error, 3 builds"), and SHALL NOT draw it; WHILE status is default THE tag SHALL ignore statusLabel. THE tag SHALL NOT expose its variant, its size or its status in any other way: a status is given in words or not at all.
TAG-12 WHEN label, status or statusLabel changes THE tag SHALL draw and expose the new value at once, without a motion, and SHALL NOT announce the change by itself.
TAG-13 THE tag SHALL lay itself out inline with the text or the row it is placed in, as one unbreakable box, with the baseline of its label on the baseline of the text beside it; WHILE the text size is enlarged THE tag SHALL grow its container with its label, keeping the height of its size as a minimum, its paddings, and its glyph box and its dot at comp.tag.icon.size and comp.tag.dot.size.
TAG-14 WHERE the platform draws with a person's own forced colors (the web's forced-colors mode, and a platform's equivalent where it has one) THE tag SHALL draw an edge comp.tag.outline.width wide in the platform's text color inside its container in every variant, and its label, glyph and dot in that text color, so that a look whose fill the mode removes is still a bounded label; the status SHALL then rest on the label's words and statusLabel alone.
TAG-15 WHERE the layout direction is right-to-left THE tag SHALL mirror the order of its content and apply its paddings by logical start and end, so that the glyph or the dot sits at the right of the label.
TAG-16 THE tag SHALL take its layout direction from where it is used — the direction of the nearest ancestor that sets one, and the platform's own where none does — and SHALL have no direction setting of its own; WHEN that direction changes while the tag is shown THE tag SHALL draw itself for the new direction at once, without a motion of its own, keeping what it shows.
TAG-17 WHERE the layout direction is right-to-left THE tag SHALL draw the glyph of its icon slot mirrored left to right exactly when the system's icon set marks that glyph's name as mirrored or the product forces mirroring for that use, and unmirrored when the product forbids it: the icon helper mirrors the glyph inside its own box, about the box's vertical centre line, changing neither its place, size, color and fill nor the order TAG-15 gives. THE tag SHALL NOT mirror a glyph itself, and SHALL NOT mirror content the product gives as an image or a view of its own rather than by a glyph's name. The dot is never mirrored.
TAG-18 THE tag SHALL lay out its label as text of its own direction, isolated from the text around it: it takes the base direction of its first strong character, or the layout direction where it has none, so that a left-to-right word, a number with its sign or unit, a version and a date keep their own order in a right-to-left layout and reorder nothing beside them; THE tag SHALL still place the label by the layout direction, not by the text's own, and SHALL cut a label that does not fit (TAG-5) at the end of its own direction, so that a left-to-right label in a right-to-left layout loses its right end and never its beginning.
TAG-19 WHEN variant or size names a value that the active design system does not have, or status names a value this spec does not have, THE tag SHALL render with the default value (the default variant's or size's tokens, status default), and in debug builds report the unknown value.
TAG-20 IF label is empty THE tag SHALL draw nothing, take no space and expose nothing, and in debug builds report that a tag has no text: a glyph or a dot alone is not a tag. IF statusLabel is not empty while status is default THE tag SHALL ignore it and in debug builds report it.
TAG-21 WHILE disabled is true — the tag stands inside something disabled, and the component that holds it, or the product, says so — THE tag SHALL draw its fill, its label, its glyph and its dot from its look's disabled tokens (comp.tag.<variant>.disabled.container.color, comp.tag.<variant>.disabled.label.color and comp.tag.<variant>.disabled.icon.color, and their parts of each status), whatever its status, so that it fades with what it stands in and does not read as the one live part of a disabled whole; an outlined tag SHALL keep its edge and draw no fill. disabled SHALL change nothing else: the tag SHALL keep its size, its label and its place, take no input and no focus (TAG-9), and keep its text readable by assistive technology, which hears the disabled state from the element the tag stands in, never from the tag. WHERE the platform draws with a person's own forced colors THE tag SHALL draw its edge, its label, its glyph and its dot in the platform's color for disabled text (GrayText on the web) in place of its text color (TAG-14).

各平台名称对照

对等并不意味着 API 完全相同。同一份契约,由各平台以自己的惯用方式表达。

规格 Web SwiftUI Jetpack Compose Flutter React Native
组件 tanrei-tag TanreiTag TanreiTag TanreiTag Tag
label · 属性 label title label label label
variant · 属性 variant variant variant variant variant
status · 属性 status status status status status
statusLabel · 属性 statusLabel statusLabel statusDescription statusSemanticLabel statusAccessibilityLabel
size · 属性 size size size size size
dot · 属性 dot showsDot showDot showDot dot
disabled · 属性 disabled isDisabled enabled enabled disabled
备注 <tanrei-tag> with the label as the label attribute and the glyph in the icon slot. The host is display: inline-flex with vertical-align: baseline and no role, no tabindex and no listeners; pointer-events stay as they are, so a press over a tag inside a link or a button reaches that element (TAG-10). statusLabel is reflected as the status-label attribute and drawn as visually hidden text before the label in the shadow root, followed by a comma and a space (TAG-11); the glyph and the dot are aria-hidden. The label is one dir="auto" run with text-overflow: ellipsis (TAG-18). Under forced-colors: active the container takes a CanvasText border of the outline width (TAG-14). disabled is a reflected boolean attribute that draws the look's disabled tokens and nothing else: no aria-disabled, no inert, no listener (TAG-21); under forced-colors: active the edge and the text are GrayText. TanreiTag(_ title: String, variant:, status:, statusLabel:, size:, showsDot:, icon:), the glyph given by name through icon:. Not a Button and not focusable; allowsHitTesting(false) so a press reaches a row or a link that holds it. The view is one accessibility element whose label is statusLabel and the title joined by a comma, with the static text trait. isDisabled: (a parameter, not .disabled(_:), which would say the tag is a control): it draws the look's disabled tokens and changes nothing else (TAG-21). TanreiTag(label, variant, status, statusDescription, size, showDot, icon), the glyph given by name through icon. No clickable and no focusable modifier. The label's text semantics are replaced by statusDescription and the label joined by a comma where a status label is given; the glyph and the dot are cleared from semantics. enabled is the inverse flag: it draws the look's disabled tokens and changes nothing else (TAG-21). TanreiTag(label: …, variant:, status:, statusSemanticLabel:, size:, showDot:, icon:), the glyph given by name through icon. Wrapped in IgnorePointer, with no Focus. One Semantics(label:) over the drawn parts, which are excluded. enabled is the inverse flag: it draws the look's disabled tokens and changes nothing else (TAG-21). <Tag label="Beta" />; the glyph is the icon prop (a glyph name). pointerEvents="none" and not focusable. One accessible element with accessibilityRole="text" whose accessibilityLabel is the status label and the label joined by a comma. Follows the app's direction where an ancestor's is not known. disabled: it draws the look's disabled tokens and changes nothing else (TAG-21).

令牌

令牌 引用 解析值(浅色)
--tanrei-comp-tag-container-gap sys.space.space50 4px
--tanrei-comp-tag-container-height-medium — 24px
--tanrei-comp-tag-container-height-small — 20px
--tanrei-comp-tag-container-padding-block-medium — 2px
--tanrei-comp-tag-container-padding-block-small — 2px
--tanrei-comp-tag-container-padding-inline-with-icon-medium sys.space.space75 6px
--tanrei-comp-tag-container-padding-inline-with-icon-small sys.space.space50 4px
--tanrei-comp-tag-container-padding-inline-medium sys.space.space100 8px
--tanrei-comp-tag-container-padding-inline-small sys.space.space75 6px
--tanrei-comp-tag-container-shape sys.shape.corner.full 9999px
--tanrei-comp-tag-dot-size sys.space.space100 8px
--tanrei-comp-tag-filled-container-color sys.color.primary #1b1b1b
--tanrei-comp-tag-filled-disabled-container-color — #1b1b1b · 12%
--tanrei-comp-tag-filled-disabled-error-container-color — #1b1b1b · 12%
--tanrei-comp-tag-filled-disabled-error-icon-color — #1b1b1b · 38%
--tanrei-comp-tag-filled-disabled-error-label-color — #1b1b1b · 38%
--tanrei-comp-tag-filled-disabled-icon-color — #1b1b1b · 38%
--tanrei-comp-tag-filled-disabled-info-container-color — #1b1b1b · 12%
--tanrei-comp-tag-filled-disabled-info-icon-color — #1b1b1b · 38%
--tanrei-comp-tag-filled-disabled-info-label-color — #1b1b1b · 38%
--tanrei-comp-tag-filled-disabled-label-color — #1b1b1b · 38%
--tanrei-comp-tag-filled-disabled-success-container-color — #1b1b1b · 12%
--tanrei-comp-tag-filled-disabled-success-icon-color — #1b1b1b · 38%
--tanrei-comp-tag-filled-disabled-success-label-color — #1b1b1b · 38%
--tanrei-comp-tag-filled-disabled-warning-container-color — #1b1b1b · 12%
--tanrei-comp-tag-filled-disabled-warning-icon-color — #1b1b1b · 38%
--tanrei-comp-tag-filled-disabled-warning-label-color — #1b1b1b · 38%
--tanrei-comp-tag-filled-error-container-color sys.color.error #cd262f
--tanrei-comp-tag-filled-error-icon-color comp.tag.filled.error.label.color #ffffff
--tanrei-comp-tag-filled-error-label-color sys.color.on-error #ffffff
--tanrei-comp-tag-filled-icon-color comp.tag.filled.label.color #ffffff
--tanrei-comp-tag-filled-info-container-color sys.color.info #3066cb
--tanrei-comp-tag-filled-info-icon-color comp.tag.filled.info.label.color #ffffff
--tanrei-comp-tag-filled-info-label-color sys.color.on-info #ffffff
--tanrei-comp-tag-filled-label-color sys.color.on-primary #ffffff
--tanrei-comp-tag-filled-success-container-color sys.color.success #077b32
--tanrei-comp-tag-filled-success-icon-color comp.tag.filled.success.label.color #ffffff
--tanrei-comp-tag-filled-success-label-color sys.color.on-success #ffffff
--tanrei-comp-tag-filled-warning-container-color sys.color.warning #9b5c00
--tanrei-comp-tag-filled-warning-icon-color comp.tag.filled.warning.label.color #ffffff
--tanrei-comp-tag-filled-warning-label-color sys.color.on-warning #ffffff
--tanrei-comp-tag-icon-size sys.icon.extra-small 16px
--tanrei-comp-tag-outline-color sys.color.outline-variant #000000 · 8%
--tanrei-comp-tag-outline-width sys.border.hairline 1px
--tanrei-comp-tag-outlined-container-color — #000000 · 0%
--tanrei-comp-tag-outlined-disabled-container-color — #000000 · 0%
--tanrei-comp-tag-outlined-disabled-error-container-color — #000000 · 0%
--tanrei-comp-tag-outlined-disabled-error-icon-color — #1b1b1b · 38%
--tanrei-comp-tag-outlined-disabled-error-label-color — #1b1b1b · 38%
--tanrei-comp-tag-outlined-disabled-icon-color — #1b1b1b · 38%
--tanrei-comp-tag-outlined-disabled-info-container-color — #000000 · 0%
--tanrei-comp-tag-outlined-disabled-info-icon-color — #1b1b1b · 38%
--tanrei-comp-tag-outlined-disabled-info-label-color — #1b1b1b · 38%
--tanrei-comp-tag-outlined-disabled-label-color — #1b1b1b · 38%
--tanrei-comp-tag-outlined-disabled-success-container-color — #000000 · 0%
--tanrei-comp-tag-outlined-disabled-success-icon-color — #1b1b1b · 38%
--tanrei-comp-tag-outlined-disabled-success-label-color — #1b1b1b · 38%
--tanrei-comp-tag-outlined-disabled-warning-container-color — #000000 · 0%
--tanrei-comp-tag-outlined-disabled-warning-icon-color — #1b1b1b · 38%
--tanrei-comp-tag-outlined-disabled-warning-label-color — #1b1b1b · 38%
--tanrei-comp-tag-outlined-error-container-color comp.tag.outlined.container.color #000000 · 0%
--tanrei-comp-tag-outlined-error-icon-color sys.color.error #cd262f
--tanrei-comp-tag-outlined-error-label-color comp.tag.outlined.label.color #1b1b1b
--tanrei-comp-tag-outlined-icon-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-tag-outlined-info-container-color comp.tag.outlined.container.color #000000 · 0%
--tanrei-comp-tag-outlined-info-icon-color sys.color.info #3066cb
--tanrei-comp-tag-outlined-info-label-color comp.tag.outlined.label.color #1b1b1b
--tanrei-comp-tag-outlined-label-color sys.color.on-surface #1b1b1b
--tanrei-comp-tag-outlined-success-container-color comp.tag.outlined.container.color #000000 · 0%
--tanrei-comp-tag-outlined-success-icon-color sys.color.success #077b32
--tanrei-comp-tag-outlined-success-label-color comp.tag.outlined.label.color #1b1b1b
--tanrei-comp-tag-outlined-warning-container-color comp.tag.outlined.container.color #000000 · 0%
--tanrei-comp-tag-outlined-warning-icon-color sys.color.warning #9b5c00
--tanrei-comp-tag-outlined-warning-label-color comp.tag.outlined.label.color #1b1b1b
--tanrei-comp-tag-tonal-container-color sys.color.secondary-container #eeeeee
--tanrei-comp-tag-tonal-disabled-container-color — #1b1b1b · 12%
--tanrei-comp-tag-tonal-disabled-error-container-color — #1b1b1b · 12%
--tanrei-comp-tag-tonal-disabled-error-icon-color — #1b1b1b · 38%
--tanrei-comp-tag-tonal-disabled-error-label-color — #1b1b1b · 38%
--tanrei-comp-tag-tonal-disabled-icon-color — #1b1b1b · 38%
--tanrei-comp-tag-tonal-disabled-info-container-color — #1b1b1b · 12%
--tanrei-comp-tag-tonal-disabled-info-icon-color — #1b1b1b · 38%
--tanrei-comp-tag-tonal-disabled-info-label-color — #1b1b1b · 38%
--tanrei-comp-tag-tonal-disabled-label-color — #1b1b1b · 38%
--tanrei-comp-tag-tonal-disabled-success-container-color — #1b1b1b · 12%
--tanrei-comp-tag-tonal-disabled-success-icon-color — #1b1b1b · 38%
--tanrei-comp-tag-tonal-disabled-success-label-color — #1b1b1b · 38%
--tanrei-comp-tag-tonal-disabled-warning-container-color — #1b1b1b · 12%
--tanrei-comp-tag-tonal-disabled-warning-icon-color — #1b1b1b · 38%
--tanrei-comp-tag-tonal-disabled-warning-label-color — #1b1b1b · 38%
--tanrei-comp-tag-tonal-error-container-color sys.color.error-container #ffedeb
--tanrei-comp-tag-tonal-error-icon-color sys.color.error #cd262f
--tanrei-comp-tag-tonal-error-label-color sys.color.on-error-container #3a211f
--tanrei-comp-tag-tonal-icon-color comp.tag.tonal.label.color #262626
--tanrei-comp-tag-tonal-info-container-color sys.color.info-container #edf0ff
--tanrei-comp-tag-tonal-info-icon-color sys.color.info #3066cb
--tanrei-comp-tag-tonal-info-label-color sys.color.on-info-container #212839
--tanrei-comp-tag-tonal-label-color sys.color.on-secondary-container #262626
--tanrei-comp-tag-tonal-success-container-color sys.color.success-container #e2f6df
--tanrei-comp-tag-tonal-success-icon-color sys.color.success #077b32
--tanrei-comp-tag-tonal-success-label-color sys.color.on-success-container #1b2c1c
--tanrei-comp-tag-tonal-warning-container-color sys.color.warning-container #ffeee0
--tanrei-comp-tag-tonal-warning-icon-color sys.color.warning #9b5c00
--tanrei-comp-tag-tonal-warning-label-color sys.color.on-warning-container #362410
--tanrei-comp-tag-label-typescale-medium sys.typescale.label 500 14px/1.4286
--tanrei-comp-tag-label-typescale-small sys.typescale.label-small 500 12px/1.3333

测试样例

作为基准的渲染结果。所有平台都以相同的 ID 为每个样例截取快照,以便相互比较。

生成自 specs/tag.spec.json, tokens/comp/tag.tokens.json, design/tokens/

指南

徽标、纸片还是 Tag

这三者只需区分一次,依据是它们各自做什么:

组件 它是什么 位于哪里 是否接受输入
徽标 附着在另一个元素上的圆点或计数。 在锚点的角上,布局之外。 否。输入会落到锚点上。
纸片(Chip) 一个控件。 在布局之中。 是:它可以被按下、切换或移除,并且有焦点和状态。
Tag 一段静态的文字标签。 在布局之中,与文本同行。 从不。
  1. 如果它可以被按下、选中或移除,它就是纸片。如果它通向某个地方,它就是链接。
  2. 如果它是叠在别的东西上面的一个数字或圆点,它就是徽标。
  3. 如果它只是一个词,说明某样东西是什么或处于什么状态,它就是 Tag。

Tag 绝不会因为加了处理函数而变成控件。在链接、按钮、列表项或整体可按下的行里,它始终是那个元素的文本:落在它上面的输入会到达那个元素,悬停、聚焦和按下也由那个元素自己绘制。

如何选择外观

variant 绘制什么 用于
tonal(默认) 柔和的填充。 大多数 Tag。
outlined 没有填充,只有一道细线。 许多 Tag 挨在一起的地方:表格的一列、一串类别。
filled 实色填充。 相邻几个当中被选定的那一个:几个值当中的默认值、几个字段当中的必填项。也用于那个绝不能被漏看的语义状态。

语义状态

status 为 default、info、warning、error 或 success。它只改变颜色。outlined 的 Tag 在每种语义状态下都保留表面的文本颜色和它的细线,所以它总会以该状态的颜色画一个圆点(或你提供的图标):这个标记是该状态唯一显现的地方。

Tag 自己不绘制任何表示状态的图标。在有帮助的地方请自己指定一个,就像本站为自己的状态表中的六种状态所做的那样:

本站的六种状态

radio_button_uncheckedscheduleclock_loader_40clock_loader_80check_circleblock

尺寸

size 高度 文本 用于
small 20 12 字段的标签旁边、表格单元格里、一行正文之中。它不会把这一行撑高。
medium(默认) 24 14 标题旁边,或单独使用。

字段和字段组的“必填”和“选填”小标签,就是小号的这个组件:必填用 filled,选填用 tonal。它们读取 Tag 的令牌,没有自己的令牌,所以重新设定小号 Tag 样式的设计系统,也就同时重新设定了它们的样式。

位于禁用元素之中

Tag 没有自己的状态,但它可以位于一个被禁用的元素之中:禁用字段的标签、列表中禁用的一行、菜单中禁用的一项。disabled 用它所属外观的禁用颜色(comp.tag.<variant>.disabled.*)来绘制它,无论语义状态如何,让它随所在的元素一起变淡,而不是看起来像其中唯一可用的部分。除此之外它什么都不改变:Tag 保持自己的尺寸和文字,不接受输入,也不获得焦点。字段和字段组在禁用时会为它们的必填和选填小标签设置它;你把 Tag 放进自己的禁用元素时,请自己设置。

常态的 Tag,以及位于禁用元素之中的 Tag

推荐

  • 用文字说出状态。“失败”无需更多说明;以错误颜色显示“3 个构建”的 Tag 则需要 statusLabel。
  • 给 Tag 留出放得下标签文字的空间。放不下的文字会以省略号截断,而 Tag 没有悬停或聚焦可以用来显示其余部分。
  • 一组 Tag 属于同一个集合时,例如一篇文章的类别,请把它们放进列表(在 Web 上是 <ul> 和 <li>),并为列表命名。

避免

  • 不要让 Tag 可以被按下。可以被按下、切换或移除的标签是纸片;通向某个地方的是链接。
  • 不要使用没有标签文字的 Tag。单独一个圆点或图标不是 Tag,它什么也不会绘制。
  • 不要指望靠颜色来传达状态。在强制颜色模式下,每个 Tag 看起来都一样:一道边线,加上文本颜色的标签文字。
  • 不要用 Tag 表示图标上的计数。那是徽标。

无障碍

角色
none
标注
The tag has no role and no name of its own: it is text, read where it sits. What is read is label, preceded by statusLabel where the tag has a status and the product gave one ("Error, 3 builds"). The glyph and the dot are decorative and hidden. Inside a link, a button, a list item or a table cell the tag's text is part of that element's content.
最小目标
即使外观尺寸更小,点击区域也满足最小目标尺寸。 minimum 32px · pointer 44px · spacing 8px · touch 48px

键盘操作

按键 动作

备注

  • Not interactive: the tag takes no input and no focus (TAG-9), so there is no target to size. minimumTarget holds trivially. A label that must be pressed, selected or removed is a chip; one that leads somewhere is a link.
  • A status never rests on color alone (WCAG 1.4.1): the label says it ("Failed", "Stable"), or statusLabel adds it in words. The component cannot tell whether a label says its status, so this is the product's to check; the docs page says so with examples.
  • Several tags in a row are the product's to group: where they are a set (an article's categories), the product lays them out in its platform's list semantics (ul and li on the web) and names the list. The tag does not group itself and has no list role.
  • A tag does not announce a change of its text or status (TAG-12). Where a change must be announced (a build that finishes while the person watches), the product puts the tag in a live region or reports the change with a snackbar.
  • A label cut by TAG-5 is still read in full by assistive technology, but a person who sees the ellipsis has no way to read the rest from the tag itself: it takes no hover and no focus. Give a tag room for its label, or let the element that holds it (a table cell, a list item) show the full text.
  • Contrast in the default system: every label is a role drawn on its paired role (on-secondary-container on secondary-container, on-error-container on error-container, on-primary on primary, on-error on error, on-surface on a surface), each held to 4.5:1 by the token invariants. The status color used for a glyph or a dot keeps 3:1 against its status container and against every surface (it is held to 4.5:1 as text on surfaces). The outlined look's edge is decorative.
  • Forced colors (TAG-14): a filled or tonal tag loses its fill, so every look gains an edge in the text color. Statuses then look alike, which is why the status must be in words.

生成自 specs/tag.spec.json, tokens/sys/measure.tokens.json

组件负责的部分

  • 它没有角色,也没有名称:它的标签文字在 Tag 所在的位置作为文本朗读。在链接、按钮或表格单元格里,它是那个元素内容的一部分。
  • statusLabel 作为另一个短语在标签文字之前朗读(“错误,3 个构建”),从不绘制。status 为 default 时它会被忽略。
  • 图标和圆点对辅助技术隐藏。
  • 它不接受输入,也不获得焦点,所以不会给焦点顺序增加停靠点,也不会给一行增加目标。
  • 被截断的标签文字仍然会完整朗读。
  • 在强制颜色模式下,每种外观都会多出一道文本颜色的边线,标签文字、图标和圆点也都采用这个颜色;禁用的 Tag 则采用禁用文本的颜色。
  • disabled 不暴露任何东西:说明自己被禁用的,是 Tag 所在的那个元素。
  • 在从右到左的布局中,图标或圆点移到标签文字的右侧,图标集标记为需要镜像的图标会被镜像,从左到右书写的标签文字保持自己的顺序,并在它自己的末尾截断。
  • 未知的变体、尺寸或语义状态,空的标签文字,以及没有语义状态却设置了的 statusLabel,会在调试构建中报告。

需要你做的事

  • 检查每个 Tag 的文字是否说出了它的状态。组件无法判断“3 个构建”是好消息还是坏消息。
  • 用页面的语言来写 statusLabel。
  • 只在位于禁用元素之中的 Tag 上设置 disabled,并确保那个元素说明了这一点(一个禁用的控件,或 aria-disabled):变淡的 Tag 依赖于它。
  • 如果某个变化必须在发生时就朗读出来(例如用户正看着的构建完成了),请把 Tag 放进实时区域(live region),或者用消息条(Snackbar)来报告这个变化。Tag 自己不会朗读。