Skip to content
fandhe-frontendcore v0.4.3
GitHub

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
  corner

API Reference

Arguments

NameTypeDefaultDescription
scrollbar/thumb: orientationOrientation—data-orientation 属性値(scroll_area.rs:157-176)。値語彙は vertical/horizontal の 2 値のみ。
viewport: attrs, childrenVec<(&str, &str)>, Vec<Node>vec![], vec![]tabindex="0" は固定出力のため呼び出し側から指定する引数ではない(drop_reserved が除去、scroll_area.rs:139-146)。読み上げ名が必要な場合は aria-label/aria-labelledby を attrs へ付与することを推奨する。

Data Attributes

PartAttributeObserved Values
scrollbardata-orientationhorizontal, vertical
thumbdata-orientationhorizontal, 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

KeyDescription
Tabviewport は tabindex="0" を固定出力するため通常の Tab 順序に含まれる(scroll_area.rs:139-146)。
↑ / ↓ / ← / →フォーカス済み viewport 上でのネイティブスクロール(本モジュールは独自のキーイベントリスナを持たず、ブラウザ既定動作に委ねる。Radix Primitives docs も同じ方針を明記、イシュー #1662 突合)。
PageUp / PageDown / Home / Endネイティブスクロールのページ単位・端への移動(ブラウザ既定動作、独自リスナなし)。
Space / Shift+Spaceネイティブスクロールの前方/後方ページ送り(ブラウザ既定動作、独自リスナなし)。

WAI-ARIA

AttributeDescription
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 突合)。