容器
ScrollArea - 滚动区域
一个会滚动的盒子,滚动条在哪都长一样。
用法
什么时候用它
import { ScrollArea } from '@misoto22/folio'说明
一个会滚动的盒子,滚动条在每个平台上长得一样。
选它而不选 overflow-auto 的理由不是那根滚动条——而是 Radix 让视口可聚焦、让滚动条可操作,光秃秃的 overflow 容器做不到。一个内容本身不可聚焦的滚动区域,键盘是够不着的:没有东西可以 Tab 过去,于是没有鼠标时,折线以下的一切都不存在。
页面级或正文的滚动用 scroll-slim 工具类更轻,也不需要组件。这个是给有边界的面板用的:很长的选项列表、一段日志、一条长过自己那一栏的侧栏。
除非调用方另有说明,两个方向都能滚。以前那个“只竖向”的默认,看上去是在说画哪一根滚动条,实际上是在说内容的哪一半存在:Radix 是按已挂载的滚动条来设视口 overflow 的,所以没有滚动条的那个方向是 hidden,越过那条边的一切都够不着了——悄无声息,而且内容明明渲染得好好的。
结构
| 部件 | 说明 |
|---|---|
| 根节点必填 | 那个有边界的盒子,className 也落在它上面。它是 overflow-hidden,自己没有尺寸,所以你在这里给的高度,是决定到底有没有东西会滚的唯一因素。 |
| 视口必填 | 真正在滚的那个元素,也是带着 role="region"、tabIndex 0 和 label 的那个。Radix 在它上面把平台的滚动条藏起来,并把没有配滚动条的那个轴设成 overflow: hidden。它是定位过的,所以绝对定位的后代会跟着内容一起走,而不是一动不动地悬在上面。 |
| 滚动条 | 每个方向一根:8px 的轨道,--rule-2 的胶囊滑块,touch-none——手指滚的是内容,不是这根条。只有指针在区域里时才画出来,停止滚动约 600ms 后淡出。 |
| 直角 | 两根滚动条交汇处那个小方块,只有 orientation="both" 时才存在——而那正是默认值。 |
实践建议
推荐
- 要给它一个高度。不给,根节点就和内容一样高,永远不会溢出,这个组件给页面添的就只有一个键盘停靠点。
- 只有在“裁掉另一个轴”正是你的本意时,才去收窄 orientation。两个轴默认都会滚,因为没有配滚动条的那个轴被设成了 overflow: hidden——越过那条边的东西不只是没有标记,是任何按键、任何手势都够不到,而内容明明好端端地渲染着。
- 内容正好齐着边界收尾时要传 type="always":平台的滚动条被藏了,我们这根又要等指针进来才画,所以静止时屏幕上没有任何东西说这个盒子会滚。
避免
- 不要在它上面再造一套拖动滚动的交互——滑块是刻意设成 touch-none 的,视口是一个真正的溢出容器,所以触摸拖动、惯性和滚轮本来就归平台管,行为也正是读者预期的那样。
- 不要在同一个轴上把一个套进另一个里:内层视口会一直吃掉滚轮事件,直到自己滚到头,所以想滚外层列表的读者,滚动的是内层那个。
示例
a bounded log
根节点上的那个高度,才是让这一切发生的东西:没有它,盒子和内容一样高、什么都不会溢出,而这个组件给页面添加的全部,就是一个键盘停靠点。那个停靠点也正是拿它而不是拿一个光秃秃的 overflow-auto 的理由——Radix 让视口保持可聚焦、让滚动条可操作,于是首屏之外的一切不用鼠标也够得着。label 之所以必填,也是同一个理由:一个没名字的键盘停靠点,播报出来只有一个「group」,别的什么都没有。页面级或正文的滚动,用 scroll-slim 这个工具类更轻,连组件都不需要。
both axes
orientation 默认就是 both,这里把它写出来,是因为那个没有滚动条的轴会被设成 overflow: hidden——所以一旦把它收窄成 vertical,比盒子更宽的内容就不只是没有标记,而是被裁掉了,没有任何按键、任何手势够得到。只有当某个轴确实不可能溢出时,才去收窄它。只有两个轴都在时,才会有那个角上的方块。也别把它们在同一个轴上互相嵌套:内层视口会一直吃掉滚轮,直到它自己到底,所以一个对着外层列表的读者,动的会是里面那个。
a permanent bar
type="always" 无论指针在不在里面都把两条滚动条画出来。默认是 hover,而平台自己的滚动条是藏起来的,所以静止时屏幕上没有任何东西说明这个盒子会滚——当最后一行明显被切掉一半时,这没问题;而当内容碰巧正好在边界处结束时,这就是个陷阱,而这份列表差不多就是如此。别在它上面再搭一套拖拽滚动:那个滑块刻意是 touch-none 的,而视口是一个真正的溢出容器,所以触摸拖动、惯性和滚轮已经是平台的了,而且表现符合读者的预期。
键盘操作
| 按键 | 作用 |
|---|---|
| Tab | 把焦点移进这个区域——没有鼠标时,这一步才让它能滚。 |
| ↑↓Page UpPage Down | 滚动它。 |
无障碍
- 视口保持可聚焦。一个内容本身不可聚焦的滚动区域没有 Tab 停靠点,折线之外的一切对没有鼠标的人等于不存在。
- label 必填,因为一个没有名字的键盘停靠点只会播报“group”。
- 除非调用方去收窄 orientation,否则两个轴都会滚,所以比盒子宽的内容仍然够得到,而不是在没有滚动条的情况下被裁掉。