Scroll Area
カスタムスクロール領域です。fandhe-frontend-headless-ui の scroll_area mod は Root / Viewport / Content / Scrollbar / Thumb / Corner の 6 anatomy パーツを提供し、viewport にはキーボードスクロール操作のための tabindex="0" を固定出力します。Themes 版と異なりスクロールバーの見た目(overflow の CSS 表現)を持たず、構造とフォーカス制御属性のみを担います。
スタイル済みの表示例は Scroll Area を参照してください。
アクセシビリティ・参考サイトとの対応
- anatomy は ark-ui/Zag.js(root/viewport/content/scrollbar/thumb/corner の 6 パーツ)と完全一致します。Radix Primitives は
contentを持ちませんが、ark-ui/chakra-ui との一致を優先し維持しています。 - ark-ui/Zag.js が持つ
data-overflow-x/data-overflow-y/data-at-*/data-hover/data-scrolling/data-dragging、Radix Primitives のdata-state="visible"|"hidden"はいずれも DOM 計測・ポインタ操作由来の実行時状態であり、SSR の静的マークアップでは真の値を決定できないため採用していません。 - Zag.js が付与する
role="presentation"は追加していません。viewportはtabindex="0"を固定付与しフォーカス可能であるため、WAI-ARIA 1.2 の Presentational Roles Conflict Resolution によりブラウザから無視される値であり、Radix Primitives(role非付与)とも整合します。 viewportのtabindex="0"固定は維持しています。SSR ではoverflowの有無を判定できないため、WCAG 2.1.1(スクロール領域のキーボード到達性)に対して安全側に倒す設計です。scrollbar/cornerのaria-hidden="true"は両参照サイトにはない本実装独自の付与ですが、ネイティブスクロールバーとの意味重複を明示する目的で付与しています。- キーボード操作は独自のキーハンドラを持たず、矢印キー/PageUp・PageDown/Home・End/Space などはブラウザのネイティブスクロール挙動に委ねます(Radix Primitives docs も同方針を明記)。
- 自前 CSS で組み立てる最小例はこのページ下部の Examples 節(「自前 CSS の最小例」)を参照してください。
関連 API: fandhe-frontend-headless-ui API
Demo
枠線・余白は docs サイト側のデモ枠であり、fandhe-frontend-headless-ui 自体はスタイルを持ちません。
- Tag 1
- Tag 2
- Tag 3
- Tag 4
- Tag 5
- Tag 6
- Tag 7
- Tag 8
- Tag 9
- Tag 10
- Tag 11
- Tag 12
Features
- Root / Viewport / Content / Scrollbar / Thumb / Corner の 6 anatomy パーツを提供し、CSS overflow を主体とするスクロール領域を表現する(scroll_area.rs:1-10)。ark-ui/Zag.js の anatomy(6 パーツ)と完全一致(イシュー #1662 突合)。
- viewport は WAI 慣行(矢印キー/Page キーでフォーカス済み要素をスクロールできる)に従い tabindex="0" を固定出力する(scroll_area.rs:139-146)。SSR では overflow の有無を判定できないため常時付与する安全側の設計(WCAG 2.1.1)。
- scrollbar/corner はネイティブスクロールバーと意味が重複する装飾要素のため aria-hidden="true" を固定出力する(scroll_area.rs:157-183)。
- 呼び出し側 attrs による固定属性(tabindex/aria-hidden/data-orientation)のなりすまし・重複出力を drop_reserved で除去する(scroll_area.rs:116-127、イシュー #1662)。
- ark-ui/Zag.js・Radix Primitives・chakra-ui・Radix Themes の 4 参照サイトと突合済み(イシュー #1662)。anatomy は増減なし。参照側の data-overflow-*/data-at-*/data-hover/data-scrolling/data-dragging・Radix の data-state(いずれも DOM 計測・ポインタ操作由来)は SSR で真の値を決定できないため意図的に非採用(
docs/policy/intentional-non-adoption.md§3.25 規則 2)。Zag.js の role="presentation" も、viewport が tabindex="0" でフォーカス可能なため WAI-ARIA 1.2 §5.4 により無視される値として非採用。
Anatomy
root
viewport
content
scrollbar
thumb
cornerAPI Reference
Arguments
| Name | Type | Default | Description |
|---|---|---|---|
scrollbar/thumb: orientation | Orientation | — | data-orientation 属性値(scroll_area.rs:157-176)。値語彙は vertical/horizontal の 2 値のみ。 |
viewport: attrs, children | Vec<(&str, &str)>, Vec<Node> | vec![], vec![] | tabindex="0" は固定出力のため呼び出し側から指定する引数ではない(drop_reserved が除去、scroll_area.rs:139-146)。読み上げ名が必要な場合は aria-label/aria-labelledby を attrs へ付与することを推奨する。 |
Data Attributes
| Part | Attribute | Observed Values |
|---|---|---|
scrollbar | data-orientation | horizontal, vertical |
thumb | data-orientation | horizontal, vertical |
Examples
Horizontal scroll area
水平方向のスクロールバー配置例です(Demo は垂直・水平の両軸 + corner)。
Wide scrollable content…
自前 CSS の最小例
data-scope/data-part/data-orientation 属性セレクタでスクロールバー表現を当てる例です。
利用者が data-scope/data-part 属性セレクタでネイティブスクロールバーを装飾する最小例です(scrollbar/thumb/corner パーツは静的マークアップのため非表示のまま維持します)。headless-ui 自体はスタイルを持ちません。
- Item 1
- Item 2
- Item 3
- Item 4
- Item 5
- Item 6
CSS
[data-scope="scroll-area"][data-part="root"] {
position: relative;
}
[data-scope="scroll-area"][data-part="viewport"] {
overflow: auto;
height: 8rem;
scrollbar-width: thin;
scrollbar-color: #9ca3af transparent;
}
[data-scope="scroll-area"][data-part="viewport"]::-webkit-scrollbar {
width: 0.5rem;
height: 0.5rem;
}
[data-scope="scroll-area"][data-part="viewport"]::-webkit-scrollbar-track {
background: transparent;
}
[data-scope="scroll-area"][data-part="viewport"]::-webkit-scrollbar-thumb {
background: #9ca3af;
border-radius: 9999px;
}
[data-scope="scroll-area"][data-part="scrollbar"],
[data-scope="scroll-area"][data-part="thumb"],
[data-scope="scroll-area"][data-part="corner"] {
display: none;
}
Accessibility
Keyboard Interactions
| Key | Description |
|---|---|
| Tab | viewport は tabindex="0" を固定出力するため通常の Tab 順序に含まれる(scroll_area.rs:139-146)。 |
| ↑ / ↓ / ← / → | フォーカス済み viewport 上でのネイティブスクロール(本モジュールは独自のキーイベントリスナを持たず、ブラウザ既定動作に委ねる。Radix Primitives docs も同じ方針を明記、イシュー #1662 突合)。 |
| PageUp / PageDown / Home / End | ネイティブスクロールのページ単位・端への移動(ブラウザ既定動作、独自リスナなし)。 |
| Space / Shift+Space | ネイティブスクロールの前方/後方ページ送り(ブラウザ既定動作、独自リスナなし)。 |
WAI-ARIA
| Attribute | Description |
|---|---|
| aria-hidden="true" | scrollbar/corner に固定出力する(scroll_area.rs:157-183)。ネイティブスクロールバーとの意味重複を明示する目的(両参照サイトにはない本実装独自の付与、イシュー #1662)。 |
| (該当なし) | root/viewport/content は role/aria-* を出力しない。Zag.js の role="presentation" は、viewport が tabindex="0" でフォーカス可能なため WAI-ARIA 1.2 §5.4 により UA に無視される値であり、Radix Primitives(role 非付与)に整合する形で追加していない(イシュー #1662 突合)。 |