アバター
人、チーム、プロジェクトを小さな画像で表します。画像がないときはイニシャルかグリフを描きます。円か角丸の四角で、サイズは 3 つです。複数を重ねて 1 つのグループとして並べ、残りの数を示すこともできます。画像であり、操作できるコントロールではありません。
- カテゴリ
- コミュニケーション
- トークン
comp.avatar- レベル
- 基礎
- Web
tanrei-avatarschedule - SwiftUI
TanreiAvatarradio_button_unchecked - Jetpack Compose
TanreiAvatarradio_button_unchecked - Flutter
TanreiAvatarradio_button_unchecked - React Native
Avatarradio_button_unchecked
生成元 docs/status/status.json, specs/avatar.spec.json
イニシャル、グリフ、四角、グループ
アバターは、それが誰のものかを示します。記事の著者、会話の参加者、タスクの担当者などです。画像を描き、画像がないときも必ず何かを描きます。ポインター、キー、フォーカスのいずれにも反応しません。
Web では <tanrei-avatar> で、複数をまとめるものは <tanrei-avatar-group> です。ほかのプラットフォームはまだ実装していません。
<!-- 単独で置く:ラベルが名前になります。 -->
<tanrei-avatar label="山田 花子" initials="山田" src="/people/hanako.jpg"></tanrei-avatar>
<!-- 同じ名前のテキストの隣に置く:decorative を付け、名前が 1 度だけ読まれるようにします。 -->
<p>
<tanrei-avatar decorative size="small" initials="山田" src="/people/hanako.jpg"></tanrei-avatar>
山田 花子
</p>
<!-- 個人ではないもの:四角にし、プロダクト側のグリフを入れます。 -->
<tanrei-avatar label="ビルドサービス" shape="square"><span slot="icon">smart_toy</span></tanrei-avatar>
<!-- メンバー 6 人、ボックスは最大 4 つ:メンバー 3 人と「+3」になります。 -->
<tanrei-avatar-group label="レビュアー" max="4" overflow-label="ほか {count} 人">
<tanrei-avatar label="山田 花子" initials="山田"></tanrei-avatar>
<tanrei-avatar label="佐藤 健" initials="佐藤"></tanrei-avatar>
<!-- … -->
</tanrei-avatar-group>
<!-- スクリプトが届くまで、このスタイルシートが各アバターの場所を保ちます。 -->
<link rel="stylesheet" href="@tanrei/web/avatar.css" />
<script type="module">
import '@tanrei/web/components/avatar';
</script>import { Avatar, AvatarGroup } from '@tanrei/react';
<Avatar label={person.name} initials={person.initials} src={person.picture} />
<AvatarGroup label="レビュアー" max={4} total={reviewerCount} overflowLabel="ほか {count} 人">
{reviewers.slice(0, 3).map((person) => (
<Avatar key={person.id} label={person.name} initials={person.initials} src={person.picture} />
))}
</AvatarGroup>3 つのサイズと 2 つの形
構成要素
| パーツ | 説明 |
|---|---|
1 container | The square box of the avatar's size, clipped to a circle or to a rounded square, with a quiet fill that shows behind the initials, the glyph, a picture that is still loading and the transparent parts of a picture. It carries no state: nothing about it answers a pointer, a press or focus. |
2 image · 任意 | The picture the product names by its address, filling the box and clipped to its shape. Drawn once it has loaded. |
3 label · 任意 | The initials the product gives, drawn at the centre of the box where there is no picture to show. A picture of a name, not text to be read: the name is the avatar's label. |
4 icon · 任意 | The fallback glyph, at the centre of the box, where there is neither a picture nor initials: the glyph the product names, or the system's own (a person for a circle, a neutral mark for a square). |
5 group · 任意 | Several avatars drawn as one row in which each lies a little over the one before it, with a gap around each so that two pictures are read as two. The group gives its avatars their size and shape. |
6 overflow · 任意 | The last box of a group that does not draw all its members: an avatar-sized box in the fallback's colors holding a plus sign and the number of members not drawn. |
プロパティ
| プロパティ | 型 | 既定値 | 説明 |
|---|---|---|---|
src | string | "" | The address of the picture. Empty, or a picture that has not loaded or cannot be loaded, draws the fallback: initials where the product gave some, otherwise a glyph. |
label | string | "" | The name of the person or the thing the avatar stands for, in full ("Ada Lovelace", "Design team"). Not drawn: it is the avatar's accessible name while decorative is false. In the group form it is the group's name ("Reviewers"). |
initials | string | "" | The one or two characters drawn where there is no picture ("AL", "山"). The product makes them: which characters stand for a name depends on its writing system and its order, which the avatar cannot know. Never read by assistive technology. |
decorative | boolean | false | True hides the avatar from assistive technology, for an avatar that stands beside the same name in visible text (a byline, a list row, a comment's header), so the name is read once. False, for an avatar that stands alone, exposes it as an image named by label. Ignored for the members of a group. |
size | small | medium | large | "medium" | Small (24) stands beside one line of text: a byline, a table cell, a mention. Medium (40) is a list row's or a comment's avatar. Large (56) heads a person's own page or card. A group gives its size to every member. A design system may add values. |
shape | circle | square | "circle" | Circle is a person. Square, a rounded square, is something that is not one person: a team, a project, an organisation, a bot. A group gives its shape to every member. A design system may add values. |
max | number | 0 | Group form only. The most boxes the group draws, the overflow box included; 0 draws every member. A whole number of 2 or more: with more members than this, the group draws one fewer member than max and then the overflow box. |
total | number | null | Group form only. How many members there are, where the product gives the group fewer than exist (the first five of a team of two hundred). Null counts the members given. |
overflowLabel | string | "" | Group form only. What assistive technology reads for the overflow box: the whole sentence in the product's language, with one place, {count}, which the group fills with the number of members not drawn ("{count} more", "ほか{count}人"). Written once as the product's words, it serves every group. A sentence that is right for every number, or a prop set per count where the language needs another form for one. Empty reads the product's words; with neither, the drawn text ("+12"). |
スロット
| スロット | 説明 |
|---|---|
icon | The fallback glyph: a glyph of the system's icon set, by name, drawn through the platform's icon helper where there is neither a picture nor initials. Empty draws the system's own fallback glyph. |
アイテム
このコンポーネントが繰り返すアイテムの種類です。フィクスチャはアイテムを順に並べ、各プラットフォームはそれぞれの流儀で種類ごとに名前を付けます。
member
One avatar of a group: an avatar with its own picture, name, initials and glyph, drawn at the group's size and shape.
| プロパティ | 型 | 既定値 | 説明 |
|---|---|---|---|
src | string | "" | The address of the member's picture. |
label | string | "" | The member's name. Always exposed in a group: the names are what the group says. |
initials | string | "" | The member's initials, drawn where there is no picture. |
| 仕様 | Web | SwiftUI | Jetpack Compose | Flutter | React Native |
|---|---|---|---|---|---|
| アイテム | tanrei-avatar | TanreiAvatar | TanreiAvatar | TanreiAvatar | Avatar |
src · プロパティ | src | url | model | image | source |
label · プロパティ | label | name | name | name | name |
initials · プロパティ | initials | initials | initials | initials | initials |
| 備考 | A <tanrei-avatar> child of <tanrei-avatar-group>, with all of an avatar's own attributes and its icon slot. The group sets the member's size and shape and makes it named. | A TanreiAvatar in the group's builder. | A TanreiAvatar call in the group's content. | A TanreiAvatar in the group's children. | An <Avatar> child of <AvatarGroup>. |
状態
振る舞い
EARS 記法による要件です。各プラットフォームの実装は、この ID に対応するテストで検証されます。要件の原文は仕様ファイルのものをそのまま掲載しています。
| ID | 要件 |
|---|---|
AVT-1 | THE avatar SHALL draw a square box whose side is the container size of its size (comp.avatar.container.size.small for small, comp.avatar.container.size.medium for medium, comp.avatar.container.size.large for large), with the corners of its shape (comp.avatar.container.shape.circle for circle, comp.avatar.container.shape.square for square), never larger than half the box's side (a circle where the value is sys.shape.corner.full) and eased by sys.shape.corner-smoothing, filled with comp.avatar.container.color, and SHALL clip everything it draws to that shape. THE avatar SHALL lay itself out inline with the text or the row it is placed in, as one unbreakable box that the layout neither stretches nor shrinks, and SHALL draw no edge and no elevation. |
AVT-2 | THE avatar SHALL draw exactly one of three things at the centre of its box (and two only for the cross-fade in which its picture arrives, AVT-4), the first of these that it has: the picture src names, once that picture has loaded (AVT-3, AVT-4); else initials, where initials is not empty (AVT-5); else a glyph (AVT-6). THE avatar SHALL never draw an empty box, a broken-picture mark or the picture's address, and SHALL NOT make initials out of label. |
AVT-3 | WHILE the picture of src has loaded THE avatar SHALL draw it over the whole box, scaled so that it covers the box with its proportions kept and its centre on the box's centre, clipped to the box's shape, over comp.avatar.container.color (which shows through the picture's transparent parts), and SHALL draw neither initials nor a glyph. THE avatar SHALL NOT mirror, tint or otherwise change the picture in any layout direction or scheme. |
AVT-4 | WHILE src is not empty and its picture has not yet loaded THE avatar SHALL draw its fallback (AVT-2) in the box, at the avatar's full size, so that nothing changes place when the picture arrives; WHEN the picture has loaded THE avatar SHALL fade it in over the fallback while the fallback fades out beneath it, one cross-fade of opacity over comp.avatar.motion.picture-duration on comp.avatar.motion.picture-easing (sys.motion.role.state.default and sys.motion.easing.state), in which nothing changes place or size; reduced motion keeps it, as a change of opacity is not motion (MOT-6). WHERE the picture loads while the avatar draws its first frames (MOT-3), or the platform already holds it when the avatar asks for it (in its memory of the pictures it has loaded), THE avatar SHALL draw it at once, in the fallback's place. IF the picture cannot be loaded THE avatar SHALL keep the fallback, SHALL NOT ask for the picture again by itself, and in debug builds SHALL report the address that failed. WHEN src changes THE avatar SHALL draw the fallback at once, until the new picture has loaded and fades in. WHILE src is empty THE avatar SHALL ask for nothing. |
AVT-5 | WHERE the avatar draws initials THE avatar SHALL set them on one line at the centre of the box, in the text style of its size (comp.avatar.label.typescale.small for small, comp.avatar.label.typescale.medium for medium, comp.avatar.label.typescale.large for large) and in comp.avatar.label.color, as the product wrote them: it SHALL NOT change their case, and SHALL draw no more than the first two characters as a reader counts them (grapheme clusters), reporting in debug builds a value that is longer. THE avatar SHALL lay the initials out as text of their own direction, isolated from the text around the avatar, and SHALL keep them from assistive technology. |
AVT-6 | WHERE the avatar draws a glyph THE avatar SHALL draw the glyph of its icon slot, or, where the slot is empty, the system's fallback glyph for its shape (person for circle, category for square), in a box of the icon size of its size (comp.avatar.icon.size.small for small, comp.avatar.icon.size.medium for medium, comp.avatar.icon.size.large for large) at the centre of the avatar, in comp.avatar.icon.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 keep it from assistive technology. |
AVT-7 | THE avatar 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, draws no state layer, no ripple and no focus indicator, and emits no event. |
AVT-8 | WHERE the avatar is placed inside an element that takes input (a link, a Button, a list item, a chip, a card that is pressed as a whole) THE avatar SHALL let input over it reach that element, SHALL stay as it is drawn while that element is hovered, focused or pressed (the state and the focus indicator are drawn by that element, on its own container), and SHALL NOT become a second target inside it; WHILE decorative is false THE avatar SHALL add its label to that element's content in reading order, so that a link or a Button that holds an avatar and nothing else is named by the avatar's label. An avatar that leads somewhere or opens something is that composition: the avatar has no destination and no action of its own. |
AVT-9 | WHILE decorative is false and label is not empty THE avatar SHALL be exposed to assistive technology as one image named by label, whether it draws a picture, initials or a glyph, and SHALL expose nothing else: not the initials, not the glyph's name, not the picture's address, and not its size or shape. WHILE decorative is true THE avatar SHALL expose nothing. IF decorative is false, label is empty and the product gives it no name (AVT-24) THE avatar SHALL expose nothing and in debug builds report that an avatar has no name. |
AVT-10 | WHEN label, initials, the icon slot's glyph, size or shape changes THE avatar SHALL draw and expose the new value at once, without a motion, and SHALL NOT announce the change by itself. |
AVT-11 | WHILE the text size is enlarged THE avatar SHALL keep its box at the container size of its size and its glyph at the size of AVT-6, and SHALL let its initials, and a group's count (AVT-17), follow their text style as it grows, no larger than the glyph's box of the same size (comp.avatar.icon.size.small for small, comp.avatar.icon.size.medium for medium, comp.avatar.icon.size.large for large), so that they still stand whole inside the box: an avatar is a picture and is enlarged with the page, not with the text, as a glyph's box is, while the letters it holds grow as far as the box leaves room for them. |
AVT-12 | WHERE the avatar is the anchor of a badge THE avatar SHALL be drawn exactly as it is without one: its square box is the anchor's bounds, the badge is placed by that box's top-end corner and drawn outside the avatar's clip (BDG-1, BDG-3, BDG-7), and the badge's label is added to the avatar's description after its name (BDG-8). THE avatar SHALL have no dot, count or status of its own. |
AVT-13 | 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 avatar SHALL draw an edge sys.border.hairline wide in the platform's text color inside its box, following its shape, and its initials or its glyph in that text color, so that a fallback whose fill the mode removes is still a bounded mark; THE avatar SHALL leave a picture's own colors as they are. |
AVT-14 | THE avatar 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 avatar is shown THE avatar SHALL draw itself for the new direction at once, without a motion of its own, keeping what it shows. A single avatar is the same in both directions but for its glyph (AVT-15): its picture is never mirrored and its initials keep their own order (AVT-5). |
AVT-15 | WHERE the layout direction is right-to-left THE avatar 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 nor its size, color and fill. THE avatar SHALL NOT mirror a glyph itself, and SHALL NOT mirror its picture or its initials. |
AVT-16 | WHERE the avatar is given members THE avatar SHALL be a group: it SHALL draw its members in one row that does not wrap, in the order they are given from the start edge, each as an avatar of the group's size and shape with that member's own picture, initials or glyph (AVT-2 to AVT-6), and SHALL ignore its own src, initials, icon slot and decorative. Each box after the first SHALL lie over the end of the one before it by the overlap of the group's size (comp.avatar.group.overlap.small for small, comp.avatar.group.overlap.medium for medium, comp.avatar.group.overlap.large for large) and be drawn above it, and every box SHALL be surrounded, outside its own edge and following its shape, by a gap comp.avatar.group.outline.width wide in comp.avatar.group.outline.color that takes no room in the layout. THE group SHALL be as wide as its boxes less their overlaps, and as high as one box. |
AVT-17 | WHILE the group has more members than max and max is 2 or more THE group SHALL draw the first max less one members and then, as its last box, an overflow box: a box of the group's size and shape filled with comp.avatar.container.color, placed and surrounded as a member is (AVT-16), holding on one line, in the label style of the group's size (AVT-5) and comp.avatar.label.color, a plus sign followed by the number of members not drawn. WHILE max is 0, or the group has no more members than max, THE group SHALL draw every member and no overflow box, unless total says more exist (AVT-18). THE overflow box SHALL take no input and SHALL NOT be a control: showing the members it counts is the product's, beside the group. |
AVT-18 | WHILE total is greater than the number of members the group is given THE group SHALL count as not drawn every member up to total, and SHALL draw the overflow box with that number after the members it draws: where the members given fit within max less one, or max is 0, all of them are drawn before it. THE group SHALL write the number in the current locale's digits with no grouping separator, SHALL draw 99 followed by a plus sign in place of a number above 99, at every size, so that the box never holds more than three characters (the exact number stays in overflowLabel, AVT-19), and SHALL lay the sign and the number out as one left-to-right run isolated from the text around it, so that the plus sign stays before the digits in a right-to-left layout. |
AVT-19 | THE group SHALL be exposed to assistive technology as one group named by its label, holding in order one image for each member it draws, each named by that member's label whatever decorative says, and then, where it draws an overflow box, one text: overflowLabel — from the instance's prop or, WHILE that is empty, from the product's words of the key avatarGroupOverflowLabel — with its place {count} filled by the number of members not drawn, in the current locale's digits with no grouping separator and never cut at 99 as the drawn text is (AVT-18); else the drawn text. Another text between braces, and a brace that opens or closes nothing, SHALL be read as written and reported in debug builds; a sentence without {count} SHALL be read as written and reported in debug builds, because it does not say how many. THE gaps SHALL be kept from assistive technology. IF the group's label is empty THE group SHALL expose its members without a group's name and in debug builds report that a group has no name; IF a member's label is empty THE group SHALL expose nothing for that member and in debug builds report it. |
AVT-20 | WHERE the layout direction is right-to-left THE group SHALL lay its row out from the right: the first member is at the right, each following box lies over the left end of the one before it and above it, and the overflow box is the leftmost; the order assistive technology reads SHALL stay the order given. |
AVT-21 | WHEN the group's members, max, total, size or shape change THE group SHALL draw and expose the new row at once, without a motion, and SHALL NOT announce the change by itself. |
AVT-22 | WHEN size or shape names a value that the active design system does not have THE avatar SHALL render with the default value's tokens, and in debug builds report the unknown value. IF max is 1, negative or not a whole number THE group SHALL draw as for 0 and in debug builds report it; IF total is not null and is less than the number of members given, negative or not a whole number THE group SHALL count the members given and in debug builds report it. |
AVT-23 | IF the avatar is a group and every member has been removed THE group SHALL draw nothing, take no space and expose nothing. IF max, total or overflowLabel is set on an avatar that has no members THE avatar SHALL ignore it and in debug builds report it. |
AVT-24 | WHERE the platform has ARIA attributes (the web), an avatar's host and a group's host carries its role (AVT-9, AVT-19) itself, so what the product writes on it is not moved, but for a name: WHILE label is not empty THE avatar SHALL hold the product's aria-label and aria-labelledby on that host as their data-aria- twins, so that label is its whole name although the platform gives aria-labelledby the precedence, and WHEN label is emptied SHALL give them back as they were written; WHILE label is empty a name the product gives so — aria-label, or aria-labelledby naming an element — SHALL be its name and SHALL NOT be reported as having none in debug builds (AVT-9, AVT-19). WHILE an avatar's label is empty and decorative is false (or it is a member of a group) a name the product gives so SHALL make it one image named by that name, as AVT-9 says of its label: an image the product names is a named image. WHILE an avatar is decorative and not a member, or a group has no members (AVT-23), it exposes nothing, and THE avatar SHALL hold them as well, giving them back when it is exposed again. WHEN the product removes one, or its data-aria- twin, or sets the ARIA property that reflects it (ariaLabel, ariaLabelledByElements) to null, THE avatar SHALL take it away. |
プラットフォーム別の名前対応
パリティは API が同一であることを意味しません。同じ契約を、各プラットフォームの流儀で表現します。
| 仕様 | Web | SwiftUI | Jetpack Compose | Flutter | React Native |
|---|---|---|---|---|---|
| コンポーネント | tanrei-avatar | TanreiAvatar | TanreiAvatar | TanreiAvatar | Avatar |
src · プロパティ | src | url | model | image | source |
label · プロパティ | label | name | name | name | name |
initials · プロパティ | initials | initials | initials | initials | initials |
decorative · プロパティ | decorative | isDecorative | decorative | decorative | decorative |
size · プロパティ | size | size | size | size | size |
shape · プロパティ | shape | shape | shape | shape | shape |
max · プロパティ | max | max | max | max | max |
total · プロパティ | total | total | total | total | total |
overflowLabel · プロパティ | overflowLabel | overflowLabel | overflowDescription | overflowSemanticLabel | overflowAccessibilityLabel |
| 備考 | Two elements: <tanrei-avatar src label initials size shape decorative> with the fallback glyph in its icon slot, and the group form as <tanrei-avatar-group label max total overflow-label size shape> whose light-DOM children are the <tanrei-avatar> members (the spec's group props are the group element's attributes; overflowLabel is reflected as overflow-label). The avatar's host is display: inline-block, flex: none, vertical-align: middle, with role="img" and aria-label while it is named and aria-hidden="true" while decorative, set through ElementInternals where axe can see it and as attributes otherwise; no tabindex, no listeners, and pointer-events left as they are, so a press over an avatar inside a link or a Button reaches that element (AVT-8). The picture is an <img alt="" decoding="async"> in the shadow root with object-fit: cover, kept hidden until its load (and its decode), then faded in while the fallback fades out — at once where the picture was complete as soon as its address was set, the browser's list of available images — and removed on error (AVT-4); loading, referrerpolicy and crossorigin are forwarded to it and mean nothing off the web. Initials are one dir="auto" run cut to two grapheme clusters with Intl.Segmenter (AVT-5). **Before the element is defined** the stylesheet of @tanrei/web gives tanrei-avatar:not(:defined) the box of its size and shape attributes in the container color and hides its children, so a page of avatars does not move when the script arrives; no picture, initials or name show until then, which is why a byline writes the name as text beside a decorative avatar. tanrei-avatar-group:not(:defined) is an inline flex row of those boxes. The group is role="group" with aria-label; it sets size, shape and the named state on its members, hides the members past the limit with hidden (they stay in the document), and draws the overflow box in its own shadow root as aria-hidden text beside a visually hidden run that carries overflow-label (AVT-19). The gap of AVT-16 is an outline (or a box-shadow spread) in --tanrei-comp-avatar-group-outline-color, never a border, so it takes no room; later members are above earlier ones by document order, which needs no z-index. Under forced-colors: active the box takes a CanvasText border and the <img> keeps forced-color-adjust: none (AVT-13). A badge on an avatar is <tanrei-badge label="3 unread"><tanrei-avatar …></tanrei-avatar></tanrei-badge>; a link is <tanrei-link href="…"><tanrei-avatar label="Ada Lovelace" …></tanrei-avatar></tanrei-link> or a plain anchor. | TanreiAvatar(_ name: String, url: URL?, initials:, icon:, size:, shape:, isDecorative:), the fallback glyph given by name through icon:; the picture through AsyncImage, whose placeholder and failure phases both draw the fallback. The group form is TanreiAvatarGroup(_ name: String, max:, total:, overflowLabel:, size:, shape:) { TanreiAvatar(…) … }, which carries the spec's group props. Not a Button; allowsHitTesting(false) so a press reaches a Link, a Button or a row that holds it. One accessibility element with the image trait and the name as its label, or hidden while decorative; the group is accessibilityElement(children: .contain) with the group's label. | TanreiAvatar(name, model, initials, icon, size, shape, decorative), the fallback glyph given by name through icon. The package keeps no image-loading dependency: model is handed to a painter the app provides through a composition local, and a painter that reports loading or failure draws the fallback (the same arrangement the chip's avatar needs; the platform's agent settles it). The group form is TanreiAvatarGroup(name, max, total, overflowDescription, size, shape) { TanreiAvatar(…) … }. No clickable and no focusable modifier; semantics are Role.Image with the name as contentDescription, cleared while decorative; the group is a semantics node with the group's name that contains its members. | TanreiAvatar(name: …, image: ImageProvider?, initials:, icon:, size:, shape:, decorative:), the fallback glyph given by name through icon; the picture through Image(image:, frameBuilder:, errorBuilder:), both builders drawing the fallback. The group form is TanreiAvatarGroup(name: …, max:, total:, overflowSemanticLabel:, size:, shape:, children: [TanreiAvatar(…), …]). Wrapped in IgnorePointer, with no Focus. Semantics(image: true, label: name) over the drawn parts, which are excluded, or ExcludeSemantics while decorative; the group is Semantics(container: true, label: name). | <Avatar name="Ada Lovelace" source={{ uri }} initials="AL" />; the fallback glyph is the icon prop (a glyph name). The picture is an Image whose onLoad shows it and whose onError keeps the fallback. The group form is <AvatarGroup name="Reviewers" max={4} total={…} overflowAccessibilityLabel="…"> with <Avatar> children. pointerEvents="none" and not focusable. One accessible element with accessibilityRole="image" and the name as accessibilityLabel, or accessible={false} with importantForAccessibility="no-hide-descendants" while decorative. Follows the app's direction where an ancestor's is not known. |
トークン
| トークン | 参照先 | 解決値(ライト) |
|---|---|---|
--tanrei-comp-avatar-container-color | sys.color.surface-container-highest | |
--tanrei-comp-avatar-container-shape-circle | sys.shape.corner.full | 9999px |
--tanrei-comp-avatar-container-shape-square | sys.shape.corner.small | 6px |
--tanrei-comp-avatar-container-size-large | — | 56px |
--tanrei-comp-avatar-container-size-medium | — | 40px |
--tanrei-comp-avatar-container-size-small | — | 24px |
--tanrei-comp-avatar-group-outline-color | sys.color.surface | |
--tanrei-comp-avatar-group-outline-width | sys.border.thick | 2px |
--tanrei-comp-avatar-group-overlap-large | sys.space.space100 | 8px |
--tanrei-comp-avatar-group-overlap-medium | sys.space.space50 | 4px |
--tanrei-comp-avatar-group-overlap-small | sys.space.space25 | 2px |
--tanrei-comp-avatar-icon-color | sys.color.on-surface-variant | |
--tanrei-comp-avatar-icon-size-large | sys.icon.large | 32px |
--tanrei-comp-avatar-icon-size-medium | sys.icon.medium | 24px |
--tanrei-comp-avatar-icon-size-small | sys.icon.extra-small | 16px |
--tanrei-comp-avatar-label-color | sys.color.on-surface-variant | |
--tanrei-comp-avatar-motion-picture-duration | sys.motion.role.state.default | 250ms |
--tanrei-comp-avatar-motion-picture-easing | sys.motion.easing.state | cubic-bezier(0.2, 0, 0, 1) |
--tanrei-comp-avatar-label-typescale-large | sys.typescale.heading-3 | 500 20px/1.4 |
--tanrei-comp-avatar-label-typescale-medium | sys.typescale.label | 500 14px/1.4286 |
--tanrei-comp-avatar-label-typescale-small | sys.typescale.caption | 500 11px/1.4545 |
フィクスチャ
基準となる描画パターンです。全プラットフォームが同じ ID でスナップショットを撮り、結果を比較できるようにしています。
size: small (5)
initials-small
label: Ada Lovelace initials: AL size: small glyph-small
label: Someone without a picture size: small square-small
label: Design team initials: DT size: small shape: square decorative
label: Ada Lovelace initials: AL decorative: true size: small group-small
label: Authors size: small items: 2 size: medium (17)
initials
label: Ada Lovelace initials: AL initials-cjk
label: 山田 花子 initials: 山 glyph
label: Someone without a picture icon
label: Build service slots: icon square
label: Design team initials: DT shape: square square-glyph
label: A project shape: square image
src: fixtures/avatar.png label: Ada Lovelace initials: AL image-square
src: fixtures/avatar.png label: Design team initials: DT shape: square image-failed
src: fixtures/missing.png label: Ada Lovelace initials: AL icon-rtl
label: خدمة المساعدة direction: rtl slots: icon initials-rtl
label: ليلى حسن initials: لح direction: rtl group
label: Authors items: 3 group-max
label: Reviewers max: 4 overflowLabel: {count} more items: 6 group-total
label: Members max: 4 total: 240 overflowLabel: {count} more items: 3 group-square
label: Teams shape: square items: 3 group-image
label: Authors items: 3 group-max-rtl
label: المراجعون max: 4 overflowLabel: و{count} آخرون direction: rtl items: 6 size: large (4)
initials-large
label: Ada Lovelace initials: AL size: large glyph-large
label: Someone without a picture size: large square-large
label: Design team initials: DT size: large shape: square group-large
label: Authors size: large max: 3 overflowLabel: {count} more items: 4 生成元 specs/avatar.spec.json, tokens/comp/avatar.tokens.json, design/tokens/
名前だけよりも小さな画像のほうが、それが誰のもの、何のものかを早く伝えられる場所で使います。記事の著者名、コメント、人の一覧の行、プロフィールの先頭などです。アバターは画像であり、それ以上のものではありません。ホバーも、フォーカスも、押下も、イベントもありません。
| 必要なもの | 使うもの |
|---|---|
| 人に付けるドットや数(「未読 3 件」) | アバターを囲むバッジ。 |
| プロフィールへ移動するアバター | アバターを入れたリンク。 |
| メニューを開くアバター | アバターを入れたボタン。 |
| 選んだり取り除いたりできる人 | チップ。 |
| 在席の状態(オンライン、離席中) | 名前の隣の言葉。印が必要な場所ではタグを添えます。 |
アバターは、次のうち最初にあるものを描きます。
srcの画像。読み込みが終わってから描きます。- 指定した
initials。 iconスロットのグリフ。- システムのグリフ。円なら人、四角なら中立的な印です。
ボックスは最初の描画から同じ大きさです。画像を読み込んでいる間は、その場所に代わりのものを描き、画像が届くと、代わりのものが薄れるのと同時に画像が浮かび上がります。ブラウザーがすでに持っている画像は、すぐに描きます。アバターの周りは何も動きません。読み込めなかった画像の場所には、代わりのものが残ります。壊れた画像の印は表示せず、画像を再び要求することもありません。
アバターは、名前からイニシャルを作りません。どの文字が名前を表すかは、文字体系や、姓と名のどちらが先に来るかによって変わります。それを知っているのはプロダクトです。initials で指定します。
| 名前 | initials |
|---|---|
| Ada Lovelace | AL |
| 山田 花子 | 山 または 山田 |
| 王小明 | 王 |
| ليلى حسن | لح |
| किरण राव | किरा |
描くのは 2 文字までです。文字は読む人が数えるとおりに数えるので、記号の付いた文字や結合した音節が途中で切れることはありません。文字は書かれたとおりに描き、大文字と小文字を変えません。
さまざまな文字体系のイニシャル
size |
辺の長さ | 用途 |
|---|---|---|
small |
24 | 1 行のテキストの隣。記事の著者名、表のセル、メンションなど。 |
medium(既定) |
40 | リストの行、コメント。 |
large |
56 | その人自身のページやカードの先頭。 |
shape |
用途 |
|---|---|
circle(既定) |
人。 |
square |
個人ではないもの。チーム、プロジェクト、組織、ボットなど。 |
画像の代わりに描くものは、どれも同じ控えめな塗りです。人ごとの色はありません。意味を持たない色は、このシステムにはありません。
- 正方形で、アバターの辺の 2 倍以上の大きさの画像を指定します。画素密度の高い画面でも鮮明に表示されます。縦横比の異なる画像は、中央を中心に切り抜かれます。
loading="lazy"を付けると、アバターがウィンドウに近づくまで画像を要求しません。長い一覧で使います。referrerpolicyとcrossoriginは、書かれたとおりに画像へ渡します。アバターはどちらも選びません。画像のホストにページの何を伝えるかは、利用者側で決めます。
グループは、メンバーを 1 行に並べます。それぞれが前のアバターに少しだけ(サイズにより 2、4、8)重なるので、並んだ 2 文字のイニシャルも欠けず、読み違えられません。周りにはサーフェスの色の隙間が入ります。
渡されていないメンバーも数えるグループ
maxは、グループが描くボックスの最大数です。残りの数を示すボックスも含みます。メンバーが 6 人でmax="4"なら、メンバー 3 人と「+3」になります。「+1」を描くことはありません。1 人を隠すためにボックスを 1 つ使うことになるからです。totalは、実際の人数です。グループに渡すメンバーが実際より少ないときに指定します。メンバー 3 人、max="4"、total="240"なら、メンバー 3 人と「99+」になります。99 を超えると、どのサイズでも「99+」と描くので、ボックスに入るのは 3 文字までです。正確な人数は、読み上げに使われるoverflow-labelに書いてください。- グループの
sizeとshapeが、すべてのメンバーに適用されます。 - ページとは別のサーフェスの上に置くときは、
--tanrei-comp-avatar-group-outline-colorにそのサーフェスの色を指定します。 - 残りの数を示すボックスはテキストであり、コントロールではありません。ほかに誰がいるかを見せる必要がある場所では、グループの隣にリンクかボタンを置きます。
<tanrei-avatar> はシャドウルートの中に描くので、サーバーで描画したページでは、スクリプトが実行されるまでその場所に何も表示されません。@tanrei/web/avatar.css を読み込むと、各アバターがサイズと形に合ったボックスを保ち、ページが動きません。画像、イニシャル、名前は、それまで表示されません。スクリプトなしで読める必要があるページでは、装飾のアバターの隣に名前をテキストで書きます。
max を指定したグループは、スクリプトが数えるまで、渡されたメンバーをすべて表示します。それでページが動いては困る場合は、描くメンバーだけをグループに渡し、残りは total で伝えます。
- 単独で置くアバターには、必ず
labelを指定します。省略しない名前です。 - 同じ名前のテキストの隣に置くアバターには、
decorativeを付けます。 - どの人にも
initialsを指定します。画像がないときや遅いときにも、誰であるかが分かります。 - プロダクト全体で、1 種類のものには 1 つの形を使います。
- アバターにハンドラーを付けない。リンクかボタンの中に入れます。状態とフォーカスインジケーターを持つのはそちらです。
- ラベルに「〜の写真」と書かない。ラベルは名前です。
- 状態を示すために、プロダクト側で色、リング、ドットを足さない。数はバッジで、在席の状態は言葉で伝えます。
- 飾りの画像や見出しのロゴにアバターを使わない。アバターは、人、または人がその名前で行動するものを表します。
- ロール
img- ラベル付け
- An avatar that stands alone is an image named by label, the full name of the person or the thing, whatever it draws; the initials, the glyph and the picture's address are never read. An avatar beside the same name in visible text is decorative and hidden. A group is a group named by its label, holding one named image for each member it draws and, last, the overflow's text (overflowLabel, or the drawn count). Inside a link or a Button, the avatar's label is part of that element's name.
- 最小ターゲット
- 見た目のサイズが小さくても、ヒット領域は最小ターゲットサイズを満たします。 minimum 32px · pointer 44px · spacing 8px · touch 48px
キーボード操作
| キー | 動作 |
|---|
備考
- Not interactive: the avatar takes no input and no focus (AVT-7), so there is no target to size and minimumTarget holds trivially. An avatar that is pressed is inside a link or a Button, and that element meets the minimum target by its own spec; a small (24) avatar alone in a link needs the link's target, not its own box, to be large enough.
- Decorative or named is the product's decision and cannot be seen from the avatar: beside "Ada Lovelace" in text a named avatar would be read as "Ada Lovelace, image, Ada Lovelace". The rule the docs page gives: if deleting the avatar loses a name, it is named; otherwise it is decorative.
- The name is the name, not a description of the picture: "Ada Lovelace", never "Photo of Ada Lovelace" and never the initials.
- Contrast in the default system: the initials, the count and the glyph are on-surface-variant on surface-container-highest, a pair the token invariants hold to 4.5:1 for secondary content on every surface tone. The fill against the surface around it is not held to a ratio: the avatar is not a control, and what it says is its name.
- A picture brings its own colors, which the avatar does not check. A picture with a pale edge on a pale surface loses its outline; the avatar draws no ring around a picture, so a product whose pictures are often pale chooses the square or gives the surface behind them a tone.
- A badge on an avatar (AVT-12) says that something is waiting, in the badge's one color and with the badge's label in words. Presence (online, away, busy) is a status that a color alone would carry; say it in words beside the name, with a tag where it needs a mark.
- Forced colors (AVT-13): every fallback gains an edge in the text color; pictures are left alone.
- A group's overflow box is text, not a control. Where the people it counts matter (who else can see this), the product lists them: a link or a Button beside the group that opens the full list.
生成元 specs/avatar.spec.json, tokens/sys/measure.tokens.json
- 単独では、
labelを名前とする 1 つの画像です。画像、イニシャル、グリフのどれを描いていても変わりません。イニシャル、グリフの名前、画像のアドレスは読まれません。 decorativeを付けると、支援技術からは隠されます。- リンクやボタンの中では、ラベルがその要素の名前になり、アバターの上での押下はその要素に届きます。
- アバターを囲むバッジは、アバターの名前の後に自分のラベルを加えます。
- グループは、
labelを名前とする 1 つのグループです。描いているメンバーごとに名前の付いた画像を、渡された順に持ち、最後に残りの数のテキストが続きます。描いていないメンバーは、支援技術に伝わりません。 - 入力もフォーカスも受けないので、フォーカスが止まる位置を増やしません。
- 文字を拡大しても、アイコンと同じように、ボックスの大きさを保ちます。イニシャルは文字に合わせて大きくなり、そのサイズのグリフの箱いっぱいで止まるので、ボックスの中で欠けません。
- 強制カラーモードでは、画像の代わりに描くものすべてに文字色の縁が付きます。画像は自身の色のままです。
- 右から左のレイアウトでは、グループは右から始まります。画像とイニシャルは左右反転せず、「+3」のプラス記号は数字の前のままです。
- 名前のないアバター、2 文字を超えるイニシャル、読み込めなかった画像、未知のサイズや形は、デバッグビルドで報告します。
- アバターごとに、名前を持たせるか装飾にするかを決めます。決め方はこうです。アバターを消すと名前が失われるなら、名前が必要です。そうでなければ装飾です。
overflowLabelは、数の入る場所{count}を含めてページの言語で 1 回書きます(「ほか {count} 人」)。グループごとに渡すか、setWords({ avatarGroupOverflowLabel })で製品全体に渡します。グループは描いていない人数を入れます。99+ と描くときも、本当の数を入れます。どの数でも正しい文にするか、言語が数ごとに形を変えるときは数ごとに差し替えます。指定しないと、描かれている「+3」がそのまま読まれます。- リンクの中の小さなアバターには、押すのに十分な広さを確保します。アバターの幅は 24 です。最小ターゲットを満たすのはリンクの役目です。
- 画像は自身の色を持っています。縁の淡い画像が多い場所では、その背後のサーフェスにトーンを付けます。