空の状態
あるはずのコンテンツがない場所に置くものです。結果のない検索、まだ何も追加されていないリスト、最初の項目ができる前のページなどで、何がないのか、なぜないのか、何をすればよいのかを伝え、そのためのアクションを示します。
- カテゴリ
- コミュニケーション
- トークン
comp.empty-state- レベル
- 基礎
- Web
tanrei-empty-stateschedule - SwiftUI
TanreiEmptyStateradio_button_unchecked - Jetpack Compose
TanreiEmptyStateradio_button_unchecked - Flutter
TanreiEmptyStateradio_button_unchecked - React Native
EmptyStateradio_button_unchecked
生成元 docs/status/status.json, specs/empty-state.spec.json
まだ何も追加されていないリストと、何も見つからなかった検索
空の状態は、コンテンツがあるはずの場所に何もないときに、その場所に置きます。リスト、行、検索結果の代わりになります。何がないのかを短い言葉で、なぜないのか、何をすればよいのかを 1 文で伝え、そのためのコントロールを示します。控えめで平らです。塗りも縁もありません。コンテンツとして、ある場所で読まれます。フォーカスを受けず、状態も持ちません。
Web では <tanrei-empty-state> です。ほかのプラットフォームはまだ実装していません。
説明は要素自身の内容です。タイトルは headline 属性で渡すと level のレベルの見出しとして公開されます。プロダクト側の見出しやそのほかのコンテンツにする場合は title スロットに入れます。アイコンセットのグリフやプロダクト側の画像は media スロットに、プロダクト側のボタンやリンクは actions スロットに入れます。文言はすべて利用者側で用意します。Tanrei は言葉を同梱しません。
<!-- ビューの中の領域:グリフ、タイトル、1 文、アクション。 -->
<tanrei-empty-state headline="プロジェクトはまだありません">
<span slot="media">folder_open</span>
プロジェクトは、1 つのデザインシステムのレイヤ、エクスポート、メンバーをまとめます。
<tanrei-button slot="actions">新しいプロジェクト</tanrei-button>
<tanrei-button slot="actions" variant="text">レイヤをインポート</tanrei-button>
</tanrei-empty-state>
<!-- 全体が空のページ:large にして、タイトルをページの見出しにします。 -->
<tanrei-empty-state size="large">
<h1 slot="title">このページは存在しません</h1>
アドレスの入力が間違っているか、ページが移動した可能性があります。
<a slot="actions" class="tanrei-link" href="/">トップページへ</a>
</tanrei-empty-state>
<!-- サイドパネルの中:リストが始まるはずだった先頭側の端に寄せます。 -->
<tanrei-empty-state align="start" headline="ベースとの違いはまだありません">
左側で値を変更すると、ここに一覧表示されます。
</tanrei-empty-state>
<!-- 絞り込みの結果として現れる場合:表示されたときに 1 回、控えめに読み上げます。 -->
<tanrei-empty-state id="no-rows" live hidden headline="条件に一致する項目はありません">
3 つの条件で絞り込んでいます。1 つ外すと、表示される項目が増えます。
<tanrei-button slot="actions" variant="outlined">絞り込みを解除</tanrei-button>
</tanrei-empty-state>
<script type="module">
import '@tanrei/web/components/empty-state';
import '@tanrei/web/empty-state.css'; // サーバーで描画した空の状態が、要素の定義前に保つ場所
</script>import { Button, EmptyState } from '@tanrei/react';
{rows.length === 0 && (
<EmptyState live headline="条件に一致する項目はありません">
3 つの条件で絞り込んでいます。1 つ外すと、表示される項目が増えます。
<Button slot="actions" variant="outlined" onClick={clearFilters}>絞り込みを解除</Button>
</EmptyState>
)}パーツを 1 つずつ加えたもの
先頭側の端に寄せたものと、large のサイズ
構成要素
構成要素
title の上に描いています。| パーツ | 説明 |
|---|---|
1 container | The block that holds the message, as wide as the region it stands in and as tall as its content and its padding, with no fill, no edge and no elevation: it is drawn on the surface of the region whose content is missing. It carries no state. |
2 media · 任意 | What pictures the empty place, above the title: a glyph of the system's icon set, in a quiet color, or a picture of the product's own. Decorative: the title says it. |
3 title | What is missing, in a few words ("No results", "No projects yet"). The one part at the surface's full text color. Plain text unless the product gives a heading; it wraps and is never cut. |
4 description · 任意 | Why the place is empty, or what the person can do about it, in a sentence or two, in a quiet color. The product's content: text, with links where it needs them. |
5 actions · 任意 | One or two of the product's own Buttons or links that fill the place or change what was asked for ("New project", "Clear the filter"), in a row below the text. |
寸法
寸法
| 長さ | トークン | 値(px) |
|---|---|---|
container padding-inline | tanrei.comp.empty-state.container.padding-inline | 16 |
title の上に描いています。プロパティ
| プロパティ | 型 | 既定値 | 説明 |
|---|---|---|---|
title | string | "" | What is missing, in a few words, in the product's language ("No results for tokne"). Exposed as a heading of the level `level` gives, since it is drawn as one. The title slot takes its place where the product needs inline content or a heading element of its own. |
level | number | 2 | The level of the heading the title prop is exposed as, 1 to 6, so that the empty state takes its place in the outline of the page around it: 2, the default, for the main region of a view under the page's own title; deeper inside a section, a card or a panel that has a heading of its own. Ignored where the title slot holds the product's own content, whose role and level are the product's. |
size | medium | large | "medium" | Medium is for an empty region inside a view: a list, a table's body, a card, a panel, a search's results. Large is for a view that is empty as a whole: the main region of a page before its first item, a page that was not found. It changes the room above and below, the glyph's size and the text styles. A design system may add values. |
align | center | start | "center" | Where the parts stand on the inline axis. Center, the default, is for a region that is otherwise blank. Start puts every part at the region's start edge with its text aligned there, for a narrow column, a list in a side panel or a table whose header stays in view, where the content would have begun at that edge. |
live | boolean | false | Whether the empty state is announced. False, the default, is for a place that is empty when its view is presented: it is read where it stands. True is for one that appears in answer to what the person did (a search that found nothing, a filter that matches no row, the last item removed): it is a live region, announced once, politely, when it is shown and when its text changes. It is never announced assertively and never takes focus: an empty place is not an error. It changes nothing that is drawn. |
スロット
| スロット | 説明 |
|---|---|
default | The description: text, with the product's own links and inline content. Empty draws the title alone. |
media | A glyph of the system's icon set, by name, drawn through the platform's icon helper at the media size; or a picture of the product's own (an illustration), which keeps its own size and colors. |
title | The product's own title content in place of the title prop: a heading of the level the page's outline needs, or text with inline content. The empty state draws it in the title's style and changes neither its role nor its level. |
actions | The actions: the product's own Buttons or links, one or two, the main one first. The empty state lays them out below the text and does nothing else to them. |
状態
振る舞い
EARS 記法による要件です。各プラットフォームの実装は、この ID に対応するテストで検証されます。要件の原文は仕様ファイルのものをそのまま掲載しています。
| ID | 要件 |
|---|---|
EMP-1 | THE empty state SHALL lay itself out as a block that takes the whole inline size of the region it is placed in and is as tall as its content and its padding: it SHALL lay out in one column, in this order, its media, its title, its description and its actions, those it has, padded above the first and below the last by the block padding of its size (comp.empty-state.container.padding-block.medium for medium, comp.empty-state.container.padding-block.large for large) and at the start and the end by comp.empty-state.container.padding-inline. THE empty state SHALL draw no fill, no edge and no elevation, SHALL bring no outer space of its own, SHALL set no height of its own and SHALL NOT scroll: where the region is taller, placing the block in it is the region's. |
EMP-2 | WHILE align is center THE empty state SHALL centre every part on the inline axis of its container and centre the lines of its title and its description; WHILE align is start THE empty state SHALL place every part at the container's start edge, inside the inline padding, and align the lines of its text to the start. In both THE empty state SHALL keep its title and its description no wider than comp.empty-state.content.measure times the description's font size, and no wider than the container less its inline padding. |
EMP-3 | WHERE the media slot holds a glyph THE empty state SHALL draw it first, in a box of the media size of its size (comp.empty-state.media.size.medium for medium, comp.empty-state.media.size.large for large), in comp.empty-state.media.color, 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, and SHALL begin the title comp.empty-state.media.gap below it. WHERE the slot holds a picture or a view of the product's own THE empty state SHALL draw it in the same place at its own size, never wider than the container less its inline padding and with its proportions kept, and SHALL NOT color, clip or mirror it. THE empty state SHALL keep the media from assistive technology, and SHALL draw no media the product did not give. |
EMP-4 | THE empty state SHALL draw its title in the text style of its size (comp.empty-state.title.typescale.medium for medium, comp.empty-state.title.typescale.large for large) and in comp.empty-state.title.color; the title SHALL wrap and SHALL never be cut. THE empty state SHALL expose a title given as text as a heading — of the level the level prop gives on a platform whose headings have levels, and with the platform's heading trait on one whose headings have none — because it is drawn larger and heavier than what follows it, and a text drawn as a heading and not exposed as one tells by its look alone what its structure is. IF level is not a whole number from 1 to 6 THE empty state SHALL use 2 and report it in debug builds. WHERE the title slot holds content THE empty state SHALL draw that content in the title's place, style and color instead of the title prop, and SHALL change neither its role nor its level: a title the product gives as a heading stays a heading of the level the product gave it, and inline content the product gives stays what it is. THE empty state SHALL set the title's letter-spacing by the script of its text, as every title is set (PRS-20): no negative letter-spacing WHERE its language is Chinese, Japanese or Korean, and none WHERE its script joins its letters or stacks marks on them. |
EMP-5 | WHERE the default slot holds content THE empty state SHALL draw it as the description, comp.empty-state.title.gap below the title, in the text style of its size (comp.empty-state.description.typescale.medium for medium, comp.empty-state.description.typescale.large for large) and in comp.empty-state.description.color; the description SHALL wrap and SHALL never be cut or limited to a number of lines. A link in the description is the product's own and is drawn by its own spec, in its own color and underlined. |
EMP-6 | WHERE the actions slot holds content THE empty state SHALL lay it out in one row comp.empty-state.actions.gap below the text, in the order given from the start, comp.empty-state.actions.item-gap apart, centred or at the start as align says (EMP-2); WHERE the row does not fit the container THE empty state SHALL wrap it, comp.empty-state.actions.item-gap between its lines, and SHALL never cut or shrink an action below its own minimum. THE empty state SHALL NOT restyle, resize, reorder or rename the actions, and SHALL emit no event of its own: an action's press is that control's. |
EMP-7 | THE empty state 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, selected or disabled state and draws no state layer and no focus indicator. What the product places in it — a link in the description, a Button in the actions — takes input and focus by its own spec, in the order the parts are drawn, and text in the title and the description SHALL remain selectable where the platform lets text be selected. |
EMP-8 | WHILE live is false THE empty state SHALL be exposed to assistive technology as plain content, read where it stands in reading order: its title as a heading (of the level level gives, or the product's own content in the title slot as the product gave it), then its description, then its actions as the controls they are. It SHALL have no role and no name of its own, SHALL NOT be announced when it is shown or when its text changes, SHALL NOT move focus, and SHALL NOT be exposed as an alert, a status, a dialog or a note: an empty place is content, not a message. |
EMP-9 | WHILE live is true THE empty state SHALL be a polite live region. WHEN it is shown after its page or view was first presented, and WHEN its title or its description changes while it is shown, THE empty state SHALL have assistive technology announce it once, after what is being read: the title, then the description, and not the names of its actions. It SHALL never announce assertively and SHALL NOT move keyboard or screen-reader focus. A live empty state that is drawn with the first presentation of its page or view SHALL NOT announce itself then. live SHALL change nothing that is drawn. |
EMP-10 | WHEN title, the title slot's content, the description, the media or the actions change THE empty state SHALL draw and expose the new value at once, without a motion, and SHALL announce it only as EMP-9 says. THE empty state SHALL neither show nor hide itself: whether the place is empty is the product's to know, and the product puts the empty state there and takes it away. |
EMP-11 | WHILE the text size is enlarged THE empty state SHALL grow its title and its description, and the measure with them, keep its paddings and gaps, wrap, and grow in height; it SHALL keep a glyph's box at the media size of its size, SHALL cut nothing and set no fixed height, SHALL lose no content when the reader raises line height, paragraph spacing, letter spacing or word spacing, and SHALL need no horizontal scrolling at a width of 320 points with text at 200 %, its actions then each on a line of their own where two do not fit side by side. |
EMP-12 | 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 empty state SHALL draw its glyph, its title and its description in the platform's text color, and leave links, Buttons and a picture of the product's own to their own specs and colors; nothing the empty state draws relies on a fill. |
EMP-13 | WHERE the layout direction is right-to-left THE empty state SHALL apply its paddings by logical start and end and mirror the order of its actions, so that the first action is at the right; WHILE align is start it SHALL place every part at the right edge and align its text to the right; WHILE align is center the column stays centred. |
EMP-14 | THE empty state 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 empty state is shown THE empty state SHALL draw itself for the new direction at once, without a motion of its own, keeping what it shows. |
EMP-15 | WHERE the layout direction is right-to-left THE empty state SHALL draw the glyph of its media 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 EMP-13 gives. THE empty state SHALL NOT mirror a glyph itself, and SHALL NOT mirror content the product gives as a picture or a view of its own rather than by a glyph's name. |
EMP-16 | THE empty state SHALL lay out a title given as text 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 title that quotes what the person typed, a file's name or a number keeps its own order in a right-to-left layout; THE empty state SHALL still place the title and align its lines by the layout direction and by align, not by the text's own. The description's direction is its content's. |
EMP-17 | WHEN size names a value that the active design system does not have, or align names a value this spec does not have, THE empty state SHALL render with the default value, and in debug builds report the unknown value. |
EMP-18 | IF the title, the title slot and the description are all empty THE empty state SHALL draw nothing, take no space and expose nothing, and in debug builds report that an empty state says nothing: a glyph or actions alone do not tell a person what is missing. IF the description is given and the title and the title slot are empty THE empty state SHALL still render and in debug builds report that an empty state has no title. |
プラットフォーム別の名前対応
パリティは API が同一であることを意味しません。同じ契約を、各プラットフォームの流儀で表現します。
| 仕様 | Web | SwiftUI | Jetpack Compose | Flutter | React Native |
|---|---|---|---|---|---|
| コンポーネント | tanrei-empty-state | TanreiEmptyState | TanreiEmptyState | TanreiEmptyState | EmptyState |
title · プロパティ | headline | title | title | title | title |
level · プロパティ | level | headingLevel | headingLevel | headingLevel | headingLevel |
size · プロパティ | size | size | size | size | size |
align · プロパティ | align | alignment | alignment | alignment | align |
live · プロパティ | live | isLive | live | live | live |
| 備考 | It is the form the callout takes. <tanrei-empty-state> with the description as light-DOM children, the glyph or the picture in the media slot, the title in the title slot (<p slot="title">, or <h2 slot="title"> where it is a heading) or the headline attribute (HTML's global title attribute would show a tooltip over the whole block, as on the callout), which the shadow root draws as an element with role="heading" and aria-level from level (a number property and attribute, 2 by default), and Buttons or links in the actions slot. Everything the product writes stays in the document: the title where it is slotted, the description, the links and the Buttons are light-DOM content, read by a crawler and by a page without script. **Before the element is defined** the stylesheet of @tanrei/web gives tanrei-empty-state:not(:defined) display: block, the block and inline padding of its size, the description's text style and color, and text-align by its align, so the content is readable in its place and the block keeps most of its height; a headline attribute does not show until the element is defined, which is why a page that must read without script gives the title in the slot. The host has no role, no tabindex and no listeners; the glyph is aria-hidden. With live the announcement is made through a visually hidden role="status" region in the shadow root that exists from the element's first render and is filled, with the title and the description's text, only when the element is connected or changed after the document's first presentation (EMP-9); the host itself gets no live role, so slotted content is not read twice. The text block's width is max-inline-size: calc(var(--tanrei-comp-empty-state-content-measure) * 1em) on the element that carries the description's font size (EMP-2). The description takes its color and text style through inherited color and font, so text placed directly in the element is styled. In a table the element goes in one <td colspan> of a body row, or directly after the table, which keeps its caption and its header row (the Table spec says nothing of an empty body); in a list it takes the list's place rather than being an item. Nothing changes under forced-colors: active but the colors the mode sets (EMP-12). | TanreiEmptyState(_ title: String, size:, alignment:, isLive:, media:, actions:) { description }, the glyph given by name through icon: or a view through media:; a heading title is the title: view builder with the header trait set by the product. Not the platform's own unavailable-content view, whose sizes and colors are the platform's: the same structure drawn from Tanrei's tokens. isLive posts one announcement with the title and the description when the view appears after its screen did. Not built on this platform yet: EMP-4's title given as text exposed as a heading, and level. | TanreiEmptyState(title, size, alignment, live, media, actions) { description }, the glyph given by name through icon or a composable through media. With live the text column has liveRegion = LiveRegionMode.Polite, set only after the first composition of its screen. Not built on this platform yet: EMP-4's title given as text exposed as a heading, and level. | TanreiEmptyState(title: …, size:, alignment:, live:, icon:, media:, actions: […], child: description); titleWidget: takes a heading of the product's own. With live the text is wrapped in Semantics(liveRegion: true) after the first frame of its route, and announced through SemanticsService.announce with polite assertiveness where the platform does not read live regions. Not built on this platform yet: EMP-4's title given as text exposed as a heading, and level. | <EmptyState title="No projects yet" icon="folder_open" actions={…}>description</EmptyState>; media takes an element of the product's own. With live, accessibilityLiveRegion="polite" on Android and one AccessibilityInfo.announceForAccessibility call on iOS when it mounts after its screen. Follows the app's direction where an ancestor's is not known. Not built on this platform yet: EMP-4's title given as text exposed as a heading, and level. |
トークン
| トークン | 参照先 | 解決値(ライト) |
|---|---|---|
--tanrei-comp-empty-state-actions-gap | sys.space.space200 | 16px |
--tanrei-comp-empty-state-actions-item-gap | sys.space.space100 | 8px |
--tanrei-comp-empty-state-container-padding-block-large | sys.space.space800 | 64px |
--tanrei-comp-empty-state-container-padding-block-medium | sys.space.space400 | 32px |
--tanrei-comp-empty-state-container-padding-inline | sys.space.space200 | 16px |
--tanrei-comp-empty-state-content-measure | — | 30 |
--tanrei-comp-empty-state-description-color | sys.color.on-surface-variant | |
--tanrei-comp-empty-state-media-color | sys.color.on-surface-variant | |
--tanrei-comp-empty-state-media-gap | sys.space.space200 | 16px |
--tanrei-comp-empty-state-media-size-large | — | 48px |
--tanrei-comp-empty-state-media-size-medium | sys.icon.large | 32px |
--tanrei-comp-empty-state-title-color | sys.color.on-surface | |
--tanrei-comp-empty-state-title-gap | sys.space.space50 | 4px |
--tanrei-comp-empty-state-description-typescale-large | sys.typescale.body-large | 400 16px/1.625 |
--tanrei-comp-empty-state-description-typescale-medium | sys.typescale.body | 400 14px/1.5714 |
--tanrei-comp-empty-state-title-typescale-large | sys.typescale.heading-3 | 500 20px/1.4 |
--tanrei-comp-empty-state-title-typescale-medium | sys.typescale.heading-5 | 500 16px/1.5 |
フィクスチャ
基準となる描画パターンです。全プラットフォームが同じ ID でスナップショットを撮り、結果を比較できるようにしています。
size: medium (12)
title
title: No projects yet description
title: No projects yet media
title: No projects yet slots: media actions
title: No projects yet slots: media, actions start
title: No projects yet align: start slots: media, actions search-no-results
title: No results for “tokne” live: true slots: media, actions table-no-rows
title: No entries match these filters slots: actions list-no-items
title: Nothing differs from the base yet align: start long-text
title: No results for “the contrast of a status… slots: media, actions actions-rtl
title: لا توجد مشاريع بعد direction: rtl slots: media, actions start-rtl
title: لا توجد مشاريع بعد align: start direction: rtl slots: media, actions search-no-results-rtl
title: لا نتائج عن “tokne” live: true direction: rtl slots: media, actions size: large (4)
large
title: No projects yet size: large slots: media, actions large-title
title: This page does not exist size: large large-start
title: This page does not exist size: large align: start slots: actions title-slot
size: large slots: title, actions 生成元 specs/empty-state.spec.json, tokens/comp/empty-state.tokens.json, design/tokens/
| 種類 | 何であるか | どこにあるか |
|---|---|---|
| 空の状態 | ないコンテンツの場所に置くもの。 | リスト、行、検索結果があるはずの場所。 |
| コールアウト | そこにあるコンテンツについての通知。 | そのコンテンツのそば、流れの中。 |
| スナックバー | たった今起きたことの結果。 | コンテンツの上に、短い間。 |
| 検索のステータステキスト | 見つかった件数(「tokne に一致する結果はありません」)。 | 検索自身のステータス行。 |
空の場所はエラーではありません。読み込みに失敗したコンテンツは、同じ場所に置くエラーステータスのコールアウトです。まだ読み込み中のコンテンツはローディングインジケーターです。読み込み中、空、失敗という領域の 3 つの状態を切り替えるのは、その領域です。空の状態が自分で現れたり隠れたりすることはありません。
size |
上下の余白 | グリフ | タイトル | 説明 | 用途 |
|---|---|---|---|---|---|
medium(既定) |
32 | 32 | 16 | 14 | ビューの中の領域。リスト、表の本体、カード、パネル、検索結果。 |
large |
64 | 48 | 20 | 16 | 全体が空のビュー。最初の項目ができる前のページ、見つからなかったページ。 |
ブロックの幅は領域の幅で、高さは内容とパディングの分です。領域のほうが高い場合に、その中でブロックをどこに置くか(中央に置く、表の最小の高さを保つなど)は、領域が決めます。テキストは 1 行あたり欧文でおよそ 60 文字、和文でおよそ 30 文字(説明の文字サイズの 30 倍)までに収めます。幅の広い表の中央に置いた 1 文が、端から端まで伸びることはありません。
align の center(既定)は、ほかに何もない領域のためのものです。start は、幅の狭い列、サイドパネルのリスト、ヘッダーが見えたままの表のためのものです。メッセージは、コンテンツが始まるはずだった位置から始まります。
headline は見出しとして描かれるので、見出しとして公開されます。既定のレベルは 2 で、ページ自身のタイトルの下にあるビューの主要な領域に向いています。ページのアウトラインに合わせて level を設定します。見出しを持つセクション、カード、パネルの中では、より深いレベルにします。title スロットのタイトルはほかのタイトルと同じように描かれ、空の状態はそのロールもレベルも変えません。プロダクト側の見出し要素を入れるか、見出しにしてはならないタイトルならテキストを入れます。
サーバーで描画するページでは、タイトルを title スロットで渡します。headline 属性は要素が描くため、要素が定義されるまで表示されません。
グリフは、要素に入れた名前で渡します。<span slot="media">folder_open</span> のように書きます。メディアのサイズで、控えめな色で描かれます。スロットに入れたそれ以外のもの(<img>、<svg>、プロダクト側の要素)は画像です。自身のサイズと色を保ち、ブロックより広くなることはなく、左右反転もしません。メディアは装飾であり、支援技術からは隠されます。先へ進む唯一の手段を画像の中に置かないでください。Tanrei はイラストを同梱しません。
アクションは、プロダクト側のボタンまたはリンクで、1 つか 2 つです。主となるものを先に置きます。空の状態はそれらを折り返す行に並べるだけで、ほかには何もしません。ラベルが行より長いアクションは、その行の幅になります。このときボタンはラベルを折り返すので、途中で切れるものも、ブロックからはみ出すものもありません。
幅の狭い列では、アクションが 1 行ずつになり、長いラベルは折り返す
live は、人がたった今行ったことの結果として現れる空の状態のためのものです。どの行にも一致しない絞り込みや、最後の項目の削除などです。表示されたときと、テキストが変わったときに、1 回、控えめに読み上げられます。読み上げるのはタイトル、次に説明で、アクションは読み上げません。hidden を付けてページに置いておくか、必要になったときに追加します。
押したことへの応答として表示される、ライブの空の状態
ページのマークアップにあり、ページの読み込み時に表示されているものは、そのときには読み上げられません。Web では、ページの読み込み後にスクリプトが追加したライブの空の状態は読み上げられます。要素は、何かへの応答として追加されたものと、シングルページアプリケーションの新しいビューとともに追加されたものを区別できません。新しいビューの一部であるだけの空の状態には、live を付けないでください。
検索では、結果の件数は検索自身のステータステキストであり、すでに読み上げられます。検索のビューに空の状態も表示する場合は、live を付けないでください。同じ言葉が 2 回読み上げられてしまいます。
行のない表は、キャプションとヘッダー行を保ちます。空の状態は、本体の行があるはずの場所に置きます。列全体にまたがる 1 つのセルの中か、表のすぐ後です。項目のないリストは、項目が 1 つのリストではありません。空の状態はリストの代わりに置きます。
説明、タイトルのスロット、アクションは要素自身の子なので、文書の中にあります。ページ内検索で見つかり、翻訳され、選択でき、スクリプトなしで読めます。@tanrei/web/empty-state.css は、まだ定義されていない空の状態に、パディング、テキストスタイル、配置を与えます。そのため、言葉は定義後と同じ場所で読めます。定義されるまでは、グリフなしで表示されます。
- 何がないのかをタイトルに平易な言葉で書き、何をすればよいのかを説明に書きます。
- その場所を埋めるアクションか、求めた条件を変えるアクションを示します。
- 結果のない検索では、人が入力した言葉をタイトルに引用します。
- ステータスの色やアラートのロールを与えない。空の場所は、コンテンツについての事実です。
- ビューを開いたときから空である場所に
liveを使わない。 - 中央に置いた灰色の文を手で描かない。項目ではないものを 1 つだけ入れたリストも作りません。
- オプションのないメニューのような、コントロールの中の 1 行の「何もありません」には使わない。それはコントロール自身のテキストです。
- ロール
none- ラベル付け
- An empty state that is not live has no role and no name: it is content, read where it stands — the title (a heading of the level level gives, or the product's own content in the title slot as the product gave it), the description, then the actions, which are the product's own controls with their own names. A live empty state is a polite live region instead (the status role on the web), announced once when it is shown after its view was presented and when its text changes. The glyph or the picture is hidden.
- 最小ターゲット
- 見た目のサイズが小さくても、ヒット領域は最小ターゲットサイズを満たします。 minimum 32px · pointer 44px · spacing 8px · touch 48px
キーボード操作
| キー | 動作 |
|---|
備考
- Not interactive: the empty state takes no input and no focus (EMP-7), so there is no target of its own to size and minimumTarget holds trivially. Its actions meet the minimum target by their own specs.
- Never an alert. An empty place is a fact about the content, not something that went wrong: it is announced only when it results from what the person just did (live), and then politely (EMP-9). A failure to load is a different thing and is said by a callout with the error status in the same place.
- It replaces content, so it must not hide that the container is still there. A table that has no rows keeps its caption and its header; the empty state stands where the body's rows would be (on the web, outside the table element or in one cell that spans the columns, as the product's table allows). A list with no items is not exposed as a list of one item: the empty state stands in the list's place.
- In a search, the count of results is the search's own status text, which is already a live region (SRC-48). Where the product also shows an empty state in the search's view, only one of the two is live, or the same words are announced twice: leave the empty state's live false there and let the status text speak.
- The title is a heading (EMP-4) because it looks like one (WCAG 1.3.1). Its level is the product's to fit the page's outline: 2 by default, for the main region of a view under the page's title; deeper inside a section, a card or a panel that has a heading of its own. A product whose title must not be a heading gives it as inline content in the title slot.
- Contrast in the default system: the title is on-surface and the description and the glyph are on-surface-variant, each held to 4.5:1 on every surface tone by the token invariants, so the empty state can stand on a page, in a card or in a panel. The glyph is decorative.
- Say what to do, not only what is missing: a description and an action are what make an empty place a way forward. Do not put the only way forward in the picture.
- Text size, text spacing and reflow: EMP-11.
生成元 specs/empty-state.spec.json, tokens/sys/measure.tokens.json
- ロールも名前もない、ふつうのコンテンツです。タイトル、説明、アクションの順に、ある場所で読まれます。
liveを付けると、自身のステータス領域を通じて、1 回、控えめに読み上げられます。ページの表示後に現れたときと、タイトルまたは説明が変わったときです。割り込んで読み上げることはありません。- グリフや画像は支援技術から隠されます。
- テキストで渡したタイトルは、
levelのレベルの見出しです。titleスロットに入れたものは、ロールもレベルも保ちます。 - フォーカスが止まる位置にはならず、フォーカスを動かすこともありません。Tab は説明の中のリンク、次にアクションへ進みます。
- 文字を拡大すると、すべてが折り返されて大きくなります。幅 320 で文字が 200% のときも横スクロールは起きず、アクションは 1 行ずつに並びます。
- 強制カラーモードでは、グリフ、タイトル、説明を文字色で描きます。塗りに頼るものはありません。
- 右から左のレイアウトでは、先頭側は右端になり、最初のアクションが右に来ます。アイコンセットが反転の対象にしているグリフは左右反転し、左から右の検索語を引用したタイトルでは、検索語の中の並びが保たれます。
- 未知のサイズや配置、タイトルも説明もない空の状態、説明だけがあってタイトルのない空の状態は、デバッグビルドで報告されます。
- すべての文言をページの言語で書きます。Tanrei は言葉を同梱しません。
- ページのアウトラインに合わせて
levelを設定するか、titleスロットにプロダクト側の見出しかテキストを入れます。 liveは、何かへの応答として現れる空の状態にだけ使います。同じことを伝える別のライブリージョンのそばでは使いません。mediaスロットにコントロールを入れないでください。支援技術から隠されます。- アクションには収まるラベルを付けます。行が短ければラベルは折り返されますが、行より長い 1 語は折り返せません。