展示
Heading - 标题
一个标题,元素和字号是两个各自独立的决定。
用法
什么时候用它
import { Heading } from '@misoto22/folio'说明
一个标题,元素和字号分开决定。
每一个只收一个数字的标题组件都会在这里搞错,而且只有两种错法:要么为了拿到一个字号把大纲掰弯(页面中间冒出一个 <h1>,只因为设计想要大字),要么为了守住大纲把字号掰弯(一个区块标题被压到 20px,只因为它排在第四级)。两种都只差一个 prop 就对了,所以这里给了两个。
level 是文档,size 是页面。默认值经由这套系统的字号阶把两者绑在一起,所以只写 level 就是对的——而一旦它们真的要分开,调用处会把这件事说出来。
和这套系统里每一个标题一样,用书刊衬线体、字重 400。它还带着 scroll-margin-top,所以一个有 id、被目录链过来的标题会停在顶栏下面,而不是被顶栏盖住。
结构
| 部件 | 说明 |
|---|---|
| 元素必填 | level,1 到 6,渲染成对应的 <h1>–<h6>。这就是文档大纲——读屏软件靠它导航——所以它跟着这个标题所开启的那一节走,绝不跟着它想要的字号走。 |
| 字号档必填 | size,取 title、lead、heading、sub、item、label 之一。默认沿着系统的阶梯从 level 推出来,所以只写 level 是对的。 |
| 锚点偏移必填 | scroll-margin-top: var(--scroll-offset),每个标题都带着,所以一个给了 id、被目录链过去的标题,会停在报头下方,而不是被报头盖住。 |
实践建议
推荐
- 除非大纲和设计真的谈不拢,否则只写 level。默认阶梯是 1→title、2→heading、3→sub、4→item、5 和 6→label——article.css 对渲染出来的 Markdown 用的是同一张对照表,正是这一点让一篇文章和一个组件页读起来像同一份出版物。
- 注意默认阶梯在 level 1 和 2 之间跳过了 lead,所以自己手写 size 时也要跳一档:--fs-lead 比 --fs-heading 是 1.14 倍,读起来像一次渲染事故,而 --fs-title 比 --fs-heading 是 1.86 倍,读起来才是层级。
- 只要有东西会链到某个标题,就给它一个 id。锚点需要的那个滚动偏移,这个组件已经带着了;页面上别的东西都没有。
避免
- 别为了把标题做大去抬 level。一个页面上两个 <h1> 会让它的大纲没法导航,而 size 就在旁边,一个属性的距离。
- 别越过 size="title"。阶梯到这里为止,因为一个页面上比它自己那些条目更大的东西,有且只有一个;再大的标题是 className 的地盘,也就是这个页面脱离这套系统的那一刻。
- size="label" 是 11px、--ink-3-aa 的等宽眉标,不是一个小号的衬线标题——它是 level 5 和 6 该有的样子,把它设在 <h2> 上,会让这一节的标题读起来像元数据。
示例
level and size
两个决定,分开做。level 是文档大纲——读屏软件靠它导航——而 size 是这一页的样子。默认会通过系统的那把梯子把两者绑在一起,而这把梯子在头两级之间跳了一档:--fs-lead 对 --fs-heading 的比是 1.14,读起来像个意外,而 --fs-title 对 --fs-heading 是 1.86,读起来才像一个层级。等宽的引题是这把梯子的第五档,这里由一个 h4 来穿,好让这一串在大纲里不跳级;最后一对是一个语义上正确、却不得不看起来像页面标题的 h3。
The White Reset
A record title
A sub-head inside it
Metadata
Third level, page-title sized
The last one is an h3. Nothing about the outline moved.
anchored headings
两个目录能链进去的标题。每一个 Heading 都带着 scroll-margin-top: var(--scroll-offset),所以给了 id 的那一个会停在顶栏下面,而不是被它盖住——页面上没有别的东西会这么做,这也是为什么一个链进手搓 h2 的锚点,落地时自己的标题正躲在那条栏后面。这个 id 属于调用方,而且必须稳定:每一个指向这一节的链接,说的都已经是它了。
Installation
One package, and one stylesheet next to it.
Upgrading
Minor versions add exports; they never move one.
a fragment that starts at h2
一块被放进一个已经有 h1 的页面里的面板。大纲决定 level——这里开的是一个 section,所以它是 h2,它的子标题是 h3——而 size 决定它看起来多大,这正是它们要做成两个属性的全部理由。为了够到更大的那一档而抬高 level,会让这一页有两个一级标题、以及一份没人能导航的大纲,换来的只是一个属性早就能给的差别。
Publish 0.4.1
What ships
Five display components, and the examples that explain them.
What it breaks
Nothing — every export in 0.4.0 is still exported here.
类型
export type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6
export type HeadingSize = 'title' | 'lead' | 'heading' | 'sub' | 'item' | 'label'无障碍
- level 渲染的是真正的标题元素,所以这份大纲是能被导航的,而不只是看得见。
- 两个决定是两个 prop,正是这一点让一个语义上正确的 h3 可以长得像页面标题,而不必把大纲掰弯。
- 带 scroll-margin-top,所以锚点跳过去的标题不会被固定的顶栏盖住(实践中的 WCAG 2.4.7)。