メインコンテンツへスキップ
menumenu tanreiexpand_morecontrasttranslate
tanreiexpand_more
はじめにWebReactSwiftUIJetpack ComposeFlutterReact Nativeプリセット自分のデザインシステムを作るAI エージェントと Tanrei を使うブランドデザイントークンデザインシステムとカスタマイズTheme Studioカラータイポグラフィアイコン形状エレベーションモーションインタラクション状態振る舞いレイアウトアクセシビリティ言葉カラートークンタイプスケールトークン形状トークンエレベーショントークンモーショントークン状態トークンスペースと寸法のトークンコンポーネントボタンメインアクションボタンセグメントボタンボタングループメニュー付きボタンツールバーコピーボタンチェックボックスラジオボタンスイッチチップメニュースライダースライダーフィールドカレンダーDateTimePickerフィールドグループラジオグループチェックボックスグループセレクトセレクトフィールドメニューバーファイルアップロードファイルピッカー 上級者向けドロップゾーンテキスト入力欄 上級者向けテキストフィールドチップフィールドフィールドコンボボックス 上級者向けコンボボックスフィールド数値入力欄 上級者向け数値フィールドカラー入力欄 上級者向けカラーフィールドワンタイムコード入力欄 上級者向けワンタイムコードフィールド埋め込みテキスト入力欄 上級者向けチャットコンポーザーカード区切り線モーダルレイヤー 上級者向けダイアログリストリスト行ボトムシートサイドシートカルーセルコードブロックテーブルポップオーバーステップアコーディオン説明リスト図アプリシェルページヘッダーツリービュータイムライン画像プレビューハンドルサイズ変更できる枠スクロールエリアバッジプログレスインジケーターメーターナンバーティッカーローディングインジケータースナックバーツールチップキーボードショートカットタグインラインコードコールアウトアバター空の状態タググループスケルトンファイル項目色見本マーキーテキストタブタブビューアプリバーナビゲーションバーナビゲーションドロワー検索リンクページネーション前後のリンクステッパーパンくずリスト目次リンクカードFAB メニューステータスTanrei の作り方コントリビューションライセンスと帰属
ホームコンポーネントスクロールエリア

スクロールエリア

内容をプラットフォーム自身のスクロールでスクロールさせる枠です。見張る端ごとに、その先にまだ内容があることを、サーフェスの色の帯、内容のフェード、線、ぼかしのいずれかで示します。大きさは変えず、内容も動かしません。

content_copyMarkdown で表示
カテゴリ
コンテインメント
トークン
comp.scroll-area
レベル
基礎

概要

Web
tanrei-scroll-area
clock_loader_40
SwiftUI
TanreiScrollArea
radio_button_unchecked
Jetpack Compose
TanreiScrollArea
radio_button_unchecked
Flutter
TanreiScrollArea
radio_button_unchecked
React Native
ScrollArea
radio_button_unchecked

生成元 docs/status/status.json, specs/scroll-area.spec.json

高さの決まった枠の中のリスト

内容が収まっているあいだ、エリアは何も描きません。スクロールしてみてください。下にまだ内容があるあいだは下端が、上に何かがスクロールして隠れると上端が示されます。

使い方

Web と React の例は現在の仕様に沿っています。SwiftUI、Compose、Flutter、React Native は予定段階で、スクロールエリアはまだ提供されていません。

<!-- 大きさはレイアウトが与えます。既定では上端と下端を示します。 -->
<tanrei-scroll-area label="メッセージ" style="block-size: 20rem">
  …
</tanrei-scroll-area>

<!-- filled のカードの上では、影をカードの色にして、リストがカードに沈み込むようにします。 -->
<tanrei-scroll-area label="検索結果" style="--tanrei-comp-scroll-area-shadow-color: var(--tanrei-comp-card-filled-container-color); block-size: 16rem">
  …
</tanrei-scroll-area>

<!-- 画像や動画の上では、内容そのものをフェードさせ、色は描きません。 -->
<tanrei-scroll-area scroll-edge="fade" label="字幕">…</tanrei-scroll-area>

<!-- 横にスクロールする列では、始端と終端を示します。 -->
<tanrei-scroll-area edges="start end" label="写真">…</tanrei-scroll-area>

<script type="module">
  import '@tanrei/web/components/scroll-area';
</script>
import { ScrollArea } from '@tanrei/react';

<ScrollArea label="メッセージ" style={{ blockSize: '20rem' }}>
  {messages}
</ScrollArea>

{/* filled のカードの上では、影をカードの色にします。 */}
<ScrollArea
  label="検索結果"
  style={{ '--tanrei-comp-scroll-area-shadow-color': 'var(--tanrei-comp-card-filled-container-color)', blockSize: '16rem' } as React.CSSProperties}
>
  {results}
</ScrollArea>

<ScrollArea scrollEdge="fade" label="字幕">{captions}</ScrollArea>
<ScrollArea edges={['start', 'end']} label="写真">{photos}</ScrollArea>

仕様

スクロールエッジ:shadow(既定のシステムの選択)、fade、line、blur、none

影。エリアが置かれたサーフェスの色の帯で、端でいちばん濃く、端から 24 の位置で消えます。スクロールすると上端にも表示されます。内容がサーフェスに沈み込むように見えます。

フェード。内容そのものが端に向かって薄れ、色は描かれないので、エリアの背後にあるものが透けて見えます。スクロールすると上端にも表示されます。

線。先に内容があるあいだ、端に沿って区切り線の色の細い線が引かれます。スクロールすると上端にも線が現れ、下端の線は消えます。

ぼかし。深さ 48 の帯の中で内容がぼけます。端でいちばん強く、帯の内側の端ではぼけません。スクロールすると上端にも表示されます。

なし。端には何も描かれず、内容が続くことを伝えるのはプラットフォームのスクロールバーだけです。スクロールして、ほかと比べてみてください。

構成要素

パーツ 説明
1 container The scroll box: as large as its layout gives it, scrolling the content up and down, sideways or both where it does not fit, with the platform's own scrolling and scroll bars. It has no fill, edge or corner of its own.
2 content Whatever the product puts in it: a list, a column of cards, a form, a row of pictures. The area lays nothing out and styles nothing inside it.
3 scroll-edge · 任意 The mark at one edge of the box while content lies beyond that edge: a band in the color of the surface the box stands on, full at the edge and none at its inner end; a fade of the content itself toward the edge; a line along it; or a band in which the content is blurred, most at the edge. Drawn over the content (the fade, on it), taking no input.
4 focus-ring · 任意 The system's focus indicator inside the box's edge, while the box itself has keyboard focus.

プロパティ

プロパティ 型 既定値 説明
scrollEdge auto | shadow | fade | line | blur | none "auto" How an edge shows that content lies beyond it. shadow: a band in the color of the surface the area stands on, so that the content sinks into the surface. fade: the content itself fades out toward the edge and no color is drawn, for a transparent surface, a picture or a video behind the area. line: a hairline along the edge. blur: the content blurred in a band along the edge, most at the edge. none: nothing. auto takes comp.scroll-area.scroll-edge, the design system's answer, which follows sys.behavior.scroll-edge (shadow in the default system).
edges strings top,bottom Which edges show the scroll edge: any of top, bottom, start and end. start is the left in a left-to-right layout and the right in a right-to-left one.
label string "" The name of the scroll box, for the moments it is a focus stop of its own (SCA-10): what it holds ("Messages", "Results"). Never drawn.

スロット

スロット 説明
default The content the area scrolls. A fixture's string is drawn as plain text in it.

状態

振る舞い

EARS 記法による要件です。各プラットフォームの実装は、この ID に対応するテストで検証されます。要件の原文は仕様ファイルのものをそのまま掲載しています。

ID 要件
SCA-1 THE scroll area SHALL be as large as its layout gives it, SHALL lay its content out at its own width, and WHERE the content does not fit SHALL scroll it with the platform's own scrolling — wheel, trackpad, touch, scroll bars, keyboard and assistive technology — in each direction it does not fit; it SHALL draw no fill, edge, corner or elevation of its own, and SHALL NOT replace the platform's scroll bars.
SCA-2 WHILE content lies beyond an edge that edges names — the content is scrolled away from that edge, so that some of it is out of view past it — THE scroll area SHALL draw the scroll edge of that edge in the form its scroll edge (SCA-7) names; WHILE nothing lies beyond it, or the edge is not named, THE scroll area SHALL draw none there. Each edge SHALL be drawn and faded by itself: content beyond the top and none beyond the bottom draws the top edge only.
SCA-3 WHILE the scroll edge is shadow THE scroll area SHALL draw over the content, along the whole length of the edge and inside the box, a band comp.scroll-area.shadow.extent deep in comp.scroll-area.shadow.color — the color of the surface the area stands on, not a color of its own — full at the edge and falling smoothly to none at the band's inner end, and SHALL draw no line.
SCA-4 WHILE the scroll edge is fade THE scroll area SHALL fade the content itself along the edge, none of it shown at the edge rising smoothly to all of it at comp.scroll-area.fade.extent in from it, SHALL draw no color and no line, so that whatever lies behind the area — a transparent surface, a picture, a video — shows through where the content fades.
SCA-5 WHILE the scroll edge is line THE scroll area SHALL draw it as a line comp.scroll-area.line.width thick in comp.scroll-area.line.color along the whole length of the edge, inside the box.
SCA-6 WHILE the scroll edge is blur THE scroll area SHALL blur the content lying in a band comp.scroll-area.blur.extent deep along the edge, by comp.scroll-area.blur.radius at the edge falling to none at the band's inner end, in comp.scroll-area.blur.layers layers of evenly stepped radius, each masked to its part of the band so that no step is seen, and SHALL draw no line and no tint: the scroll area has no fill of its own to tint with.
SCA-7 THE scroll area SHALL take its scroll edge from scrollEdge: WHILE scrollEdge is auto, as comp.scroll-area.scroll-edge names, which follows sys.behavior.scroll-edge unless a design system sets the scroll area apart; WHILE it is shadow, fade, line, blur or none, as that value names, whatever the tokens say. WHEN scrollEdge, or the token it follows, changes THE scroll area SHALL draw the other form at once, keeping the scroll position and focus.
SCA-8 WHEN content starts or stops lying beyond an edge THE scroll area SHALL fade that edge's scroll edge in or out over comp.scroll-area.motion.duration with comp.scroll-area.motion.easing, and at once where motion is reduced; it SHALL NOT change its size, move the content, or change anything else it draws because of the scroll edge. It SHALL learn whether content lies beyond an edge from what the platform already knows of the scroll — its notice that a mark at that end of the content has entered or left the box, or the scroll's own extents — and SHALL NOT measure the content's layout in a frame of a scroll.
SCA-9 WHERE the platform cannot blur what lies behind a band (a browser without backdrop filters, Android before version 12, a platform where the product gave no blur view) THE scroll area SHALL draw shadow (SCA-3), the system's first form, in place of a blur; WHERE the platform draws with a person's own forced colors THE scroll area SHALL draw the line of SCA-5 in the platform's text color in place of a shadow, a fade or a blur.
SCA-10 WHILE the content does not fit and nothing inside the box takes keyboard focus THE scroll area SHALL make the box itself one stop in the focus order, exposed as a region named by label, so that a keyboard can scroll it (WCAG 2.1.1); WHILE something inside takes focus, or the content fits, THE scroll area SHALL NOT be a focus stop and SHALL expose no role of its own. WHILE it is a focus stop and label is empty it SHALL still be focusable, and in debug builds report that the region has no accessible name.
SCA-11 WHILE the box has keyboard focus THE scroll area SHALL show it as sys.behavior.focus-style names (ring or glow), drawn wholly inside its edge so that nothing around the box covers it, over every scroll edge and never faded by one, without animation, and never for focus gained by pointer or touch; a platform that cannot draw a choice SHALL fall back to the first value and state that in its README.
SCA-12 THE scroll area SHALL draw every scroll edge over the content (the fade, on the content itself), hidden from assistive technology, and SHALL let every press, hover and scroll over it reach the content under it.
SCA-13 WHERE the layout direction is right-to-left THE scroll area SHALL take start as its right edge and end as its left edge, SHALL begin a sideways scroll at the right, and SHALL mirror no scroll edge otherwise: each form is drawn the same toward whichever edge it stands at.
SCA-14 THE scroll area 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 area is shown THE scroll area SHALL draw itself for the new direction at once, keeping its scroll position from the start edge.
SCA-15 IF scrollEdge names a value the component does not define THE scroll area SHALL treat it as auto, IF edges names a value other than top, bottom, start and end THE scroll area SHALL ignore it, and in debug builds report the unknown value.
SCA-16 WHILE the text size is enlarged THE scroll area SHALL keep its scroll edges at their sizes and lay out the larger content, which scrolls further: a scroll edge is a mark of the box, not of its text.
SCA-17 THE scroll area SHALL have no words of its own and SHALL read none of the product's words: label names this one region.
SCA-18 WHERE the platform has ARIA attributes (the web), WHEN the product sets an aria- attribute on the host, by the attribute or by the ARIA property that reflects it, THE scroll area SHALL move it to the data-aria- attribute of the same name, so that the host is no second node with its name, description or state, and SHALL expose it on its box — an id reference by the elements it names in the host's tree or a tree around it, a description after its own — but a name only while the box is a focus stop and a region (SCA-10): then label is its name over a name given so, and while label is empty a name given so is its name and SHALL NOT be reported as having none in debug builds. WHILE the box is not a focus stop it has no role a name could stand on: THE scroll area SHALL expose no name the product gives on the host, and SHALL report it in debug builds. WHEN the product removes the aria- attribute or its data-aria- twin, or sets the ARIA property that reflects it (ariaLabel, ariaDescribedByElements…) to null, THE scroll area SHALL take it off the box.

プラットフォーム別の名前対応

パリティは API が同一であることを意味しません。同じ契約を、各プラットフォームの流儀で表現します。

仕様 Web SwiftUI Jetpack Compose Flutter React Native
コンポーネント tanrei-scroll-area TanreiScrollArea TanreiScrollArea TanreiScrollArea ScrollArea
scrollEdge · プロパティ scrollEdge scrollEdge scrollEdge scrollEdge scrollEdge
edges · プロパティ edges edges edges edges edges
label · プロパティ label label label label label
備考 <tanrei-scroll-area scroll-edge edges="top bottom" label>; edges is a space-separated attribute and an array property. Whether content lies beyond an edge is read from one IntersectionObserver on four thin sentinels at the ends of the content (SCA-8): no scroll listener, no layout read while scrolling. Not CSS scroll-driven animations: they are not in every engine, and they tie the mark to the distance scrolled rather than fading it over the state motion. shadow is a gradient band per edge in --tanrei-comp-scroll-area-shadow-color; set that custom property on the element, or on an ancestor, to the surface it stands on. fade is a mask-image on the scroll box, one gradient per axis, moved by mask-position and mask-size (no registered custom property), so the browser's scroll bar fades with the content at a faded edge. blur is blur.layers layers inside each band, each with backdrop-filter: blur(r × i / n) and a mask-image gradient; @supports not (backdrop-filter: blur(1px)) draws shadow (SCA-9). Every mark is pointer-events: none and aria-hidden. A fixture fills the slot with enough lines (or a row wide enough) to scroll, in a box of a fixed size, scrolled to the middle. A ScrollView. onScrollGeometryChange tells whether content lies beyond an edge. shadow is a LinearGradient overlay from the surface color; fade a mask of a gradient; on iOS 26 and macOS 26 blur is the system's scrollEdgeEffectStyle(.soft, for:) and line .hard with the line drawn by Tanrei, before them blur is a Material band under a gradient mask. A verticalScroll/horizontalScroll box (or the product's lazy list through a ScrollState/LazyListState parameter); canScrollBackward/canScrollForward tell the edges. shadow is a drawWithContent gradient in the surface color; fade a BlendMode.DstIn gradient on an offscreen layer; blur draws the band's content again under graphicsLayer { renderEffect = BlurEffect(…) } with a gradient mask on API 31 and later, and shadow below it. A SingleChildScrollView (or the product's scrollable via its ScrollController); ScrollMetrics.extentBefore/extentAfter, read in a NotificationListener<ScrollMetricsNotification>, tell the edges. shadow is a DecoratedBox gradient in the surface color; fade a ShaderMask with BlendMode.dstIn; blur BackdropFilter bands under ShaderMask. A ScrollView; onScroll with scrollEventThrottle and the content size tell the edges, and the edge state is set only when it changes. shadow is a gradient view in the surface color where the product passes a gradient component, else a stack of translucent strips; fade needs a masked view the product passes, and is drawn as shadow without it. React Native has no blur of its own: blur is drawn only where the product passes a blur view component; otherwise shadow (SCA-9).

トークン

トークン 参照先 解決値(ライト)
--tanrei-comp-scroll-area-blur-extent sys.scroll-edge.blur.extent 48px
--tanrei-comp-scroll-area-blur-layers sys.scroll-edge.blur.layers 4
--tanrei-comp-scroll-area-blur-radius sys.scroll-edge.blur.radius 8px
--tanrei-comp-scroll-area-fade-extent sys.scroll-edge.extent 24px
--tanrei-comp-scroll-area-line-color sys.color.outline-variant #000000 · 8%
--tanrei-comp-scroll-area-line-width sys.border.hairline 1px
--tanrei-comp-scroll-area-motion-duration sys.motion.role.state.default 250ms
--tanrei-comp-scroll-area-motion-easing sys.motion.easing.state cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-scroll-area-scroll-edge sys.behavior.scroll-edge 0
--tanrei-comp-scroll-area-shadow-color sys.color.surface #ffffff
--tanrei-comp-scroll-area-shadow-extent sys.scroll-edge.extent 24px

フィクスチャ

基準となる描画パターンです。全プラットフォームが同じ ID でスナップショットを撮り、結果を比較できるようにしています。

生成元 specs/scroll-area.spec.json, tokens/comp/scroll-area.tokens.json, design/tokens/

ガイドライン

使う場面

レイアウトが画面の一部に決まった大きさを与え、その内容がそれより長くなりうる場所で使います。会話の横のメッセージの一覧、検索フィールドの下の検索結果、ペインの中の長いフォーム、横にスクロールする画像の列などです。エリアは内容を置いた場所に保ち、見張る端ごとに、その先にまだ内容があることを示します。

テーブル、ダイアログの内容、シートのように自分でスクロールするコンポーネントの周りには要りません。ページの周りにも要りません。ページ自身のスクロールには、示すべき端がないからです。ダイアログ、シート、ポップオーバー、アプリバーは、固定された部分とスクロールする内容が接する場所に、自分で線を描きます。

スクロールエッジの選び方

形 用途
shadow 不透明なサーフェス。内容がサーフェスに沈み込みます。帯は、独自のグレーではなく、エリアが置かれたサーフェスの色で描かれます。既定のシステムの選択です。
fade 背後が透明なサーフェス、画像、動画の場合。内容そのものが薄れ、色は描かれないので、背後にあるものが透けて見えます。
line 端を線で示すプロダクトや、帯が内容を覆いすぎる密度の高いレイアウト。線は区切り線の色の細い線です。
blur バーや端が半透明のプロダクト。内容が端でやわらかくぼけます。描画のコストがいちばん高い形です(後述)。
none スクロールバーが常に表示されていてそれで足りる場合のように、端をそのままにしておける枠。

端はそれぞれ別に、その先に内容があるあいだだけ描かれます。リストの先頭では、示されるのは下端だけです。状態が変わると端の表示はフェードで現れたり消えたりし、動きを減らす設定のときはすぐに切り替わります。表示がエリアの大きさを変えたり、内容を動かしたりすることはありません。

見張る端は edges で指定します。既定は top と bottom で、横にスクロールする列には start と end を使います。start は、左から右のレイアウトでは左、右から左のレイアウトでは右です。

影はサーフェスの色をとる

影は、サーフェス自身の色の帯を、端でいちばん濃くして内容の上に重ねたものです。その色が指すサーフェスの上では、継ぎ目なくサーフェスになじみます。ほかのサーフェスの上では、違う色のにじみに見えます。comp.scroll-area.shadow.color の既定値は、基本のサーフェス(sys.color.surface)です。カード、シート、コンテナの色など、別のサーフェスにエリアを置くときは、その値をそのサーフェスの色にします。そこに置くすべてのスクロールエリアならレイヤで、1 つだけならそのインスタンスで設定します。Web では、要素かその祖先に設定する --tanrei-comp-scroll-area-shadow-color カスタムプロパティです。

半透明のパネル、画像、動画のように、エリアの背後に不透明なものがない場合は、どの色も正しくありません。そこでは fade を選びます。

ぼかしは描画のコストが高い

ぼかしは、スクロールのフレームごとに、帯の中の内容をぼかしてもう一度描きます。半径を段階的に変えた comp.scroll-area.blur.layers 枚のレイヤです(既定のシステムでは 4 枚、端での半径は最大 8、帯の深さは 48)。プロダクトの見た目が求める場所で使い、ぼかした端は 1 つの画面に 2 つまでにします。すべてのペインではなく、1 つのリストの上端と下端です。プラットフォームが帯の背後をぼかせない場合(背景フィルターのないブラウザー、Android 12 より前、プロダクトがぼかしのビューを渡していない React Native)、エリアは代わりに shadow を描きます。ぼかしを選ぶ場合でも、影の色を設定しておきます。

システム全体で 1 つの選択

スクロールする枠の端を何で示すかは、プロダクトとして一度だけ決める種類の選択です。リスト、フォーム、ペインがそれぞれ違う方法で端を示すべきではありません。

tanrei.sys.behavior.scroll-edge

What marks an edge of a box that scrolls while content lies beyond it, scrolled out of view past that edge. shadow: a band sys.scroll-edge.extent deep in the color of the surface the box stands on, full at the edge and none at the band's inner end, so that the content sinks into the surface. fade: the content itself fades out over the same depth toward the edge, so that whatever lies behind it — a transparent surface, a picture, a video — shows through. line: a hairline along the edge. blur: the content blurred in a band sys.scroll-edge.blur.extent deep, most at the edge. A platform that cannot blur what lies behind draws shadow, the first value; with a person's own forced colors every choice is drawn as the line. Read by the scroll area through its own component token, so that a design system can set it apart; an instance can set its own.

— 既定値。その選択を描けないプラットフォームのフォールバックでもあります

生成元 tokens/sys/behavior.tokens.json

スクロールエリアはこれを自身のトークン comp.scroll-area.scroll-edge を通して読むので、デザインシステムはスクロールエリアだけをシステムの選択と変えられます。1 つのインスタンスは scrollEdge(Web では scroll-edge)で独自に設定します。既定値の auto はトークンに従います。既定のシステムは shadow を描きます。m3-like は line、cupertino は blur を描き、それぞれの元のデザインがスクロールする端を示す方法に合わせています。

デザインシステム scroll-edge
tanrei shadow
cupertino blur
m3-expressive-like line
m3-like line

生成元 tokens/systems/*.system.json, design/tokens/<system>/tanrei.light.tokens.json

スクロールエッジと区切り線の表示

システムの選択のうち、スクロールにかかわるものは 2 つあり、答える問いが違います。

  • sys.behavior.divider-visibility は、固定された領域の線をいつ引くかを決めます。アプリバーの端、ダイアログのヘッダーとアクション、シートのヘッダーなど、内容がその下をスクロールするあいだ動かない部分の線です。常に引くか、その先に何かがスクロールしているあいだだけ引くかを選びます。
  • sys.behavior.scroll-edge は、スクロールする枠の端を何で示すかを決めます。その端の先に内容があるあいだ、影、フェード、線、ぼかしのどれで示すかです。

2 つは別々に設定できます。ヘッダーの線がスクロールに従うダイアログの横に、サーフェスに沈み込むリストを置くこともできます。

プラットフォームのスクロールをそのまま使う

スクロールエリアは、プラットフォーム自身のスクロールする枠に、端の表示を重ねて描いたものです。ホイール、トラックパッド、タッチ、キーボード、支援技術、プラットフォームのスクロールバーは、ほかの枠と同じように動き、スクロールバーの見た目もプラットフォームのままです。エリアは独自のスクロール、スナップ、スクロールバーを加えません。中のレイアウトもせず、塗り、縁、角も持ちません。内容は、ほかの場所と同じようにスタイルを付けます。

推奨

  • エリアの大きさはレイアウトで与えます。高さ、グリッドの割り当て、ヘッダーとフッターが残す余白などです。エリアは与えられた大きさをとります。
  • エリアが基本のサーフェスでない場所に置かれるときは、影の色をそのサーフェスの色にします。
  • 何が入っているかを表すラベルを付けます。「メッセージ」「検索結果」「写真」などです。

非推奨

  • スクロールする端に、自前の区切り線、縁、グラデーションを描かない。スクロールエッジを選べば、端の先に内容があるあいだだけ現れ、プロダクトのほかの場所ともそろいます。
  • 画像、動画、半透明のサーフェスの上で影を使わない。フェードを使います。
  • 1 つの画面に、ぼかした端を 3 つ以上置かない。
  • 同じ方向にスクロールするスクロールエリアを入れ子にしない。スワイプでどちらが動くのか、利用者には分かりません。
  • 表示のための場所を空けようとして、プラットフォームのスクロールバーを隠さない。表示は続きがあることを伝え、スクロールバーはそれがどれだけあるかを伝えます。スクロールバーはそれ自体が操作部品でもあります。

アクセシビリティ

ロール
region, only while the box is a focus stop of its own (SCA-10); otherwise none
ラベル付け
While the box is a focus stop it is a region named by label. The scroll edges are hidden.
最小ターゲット
見た目のサイズが小さくても、ヒット領域は最小ターゲットサイズを満たします。 minimum 32px · pointer 44px · spacing 8px · touch 48px

キーボード操作

キー 動作
Tab Moves focus into the content, or to the box itself while nothing inside takes focus and the content does not fit.
Arrow keys, Page Up, Page Down, Home, End, Space Scroll the box while it has focus, as the platform scrolls any scroll box.

備考

  • Not interactive except as a scroll box: it has no target of its own, and its focus stop exists only so that a keyboard can scroll content that has nothing focusable (WCAG 2.1.1).
  • Animation from interactions (WCAG 2.3.3): the scroll edge's fade is a change of opacity, not motion, and is still made at once where motion is reduced.
  • A shadow or a fade lowers the contrast of the content it lies over, by design, only within its band and only while that content is scrolled toward the edge; the content is read at full contrast once it is scrolled into view.

生成元 specs/scroll-area.spec.json, tokens/sys/measure.tokens.json

コンポーネントが担うこと

  • 内容が収まらず、中にキーボードフォーカスを受け取るものがないあいだは、枠そのものがフォーカス順の 1 つの停止位置になり、label を名前とするリージョンとして公開されます。キーボードでスクロールできるようにするためです(WCAG 2.1.1)。矢印キー、Page Up、Page Down、Home、End、Space で、プラットフォームがほかの枠をスクロールするのと同じようにスクロールします。
  • 中の何かがフォーカスを受け取るあいだや、内容が収まっているあいだは、枠はフォーカスの停止位置にならず、ロールも公開しません。キーボードは内容にたどり着き、内容はフォーカスされるとスクロールして表示されます。
  • フォーカスインジケーターは枠の内側に、どの端の表示よりも上に描かれ、表示に薄められることはありません。キーボードによるフォーカスのときだけ表示されます。
  • 端の表示は支援技術から隠され、その上での押下、ホバー、スクロールは、すべて下の内容に届きます。
  • 端の表示は短い時間でフェードして現れ、消えます。これは動きではなく不透明度の変化ですが、動きを減らす設定のときはすぐに現れます。
  • 強制カラーモードでは、どの形もテキストの色の線として描かれます。
  • 自分の言葉を持ちません。枠がフォーカスの停止位置になっているときの空のラベル、未知の scrollEdge や edges の値は、デバッグビルドで報告されます。

利用者側で行うこと

  • 何が入っているかを表す label を付けます。Tab キーで枠に来た人には、その名前が聞こえます。名前がなければ、リージョンがあることしか伝わりません。
  • 帯の下の内容は、その場所でではなく、スクロールして表示されたときに読まれるものと考えます。影やフェードは、意図して、下にある内容のコントラストを下げます。ただしそれは帯の中だけで、その内容が端に向かってスクロールされているあいだだけです。スクロールして表示されれば、内容は本来のコントラストに戻ります。
  • 自然に変わる内容(ライブで更新される一覧、新しいメッセージ)は、ほかの場所と同じ方法で知らせます。エリアは、スクロールして現れたものを読み上げません。