accordion · 折叠面板

用于把长表单或长内容分成几段。默认只开一个(同一个问题的不同答案), 加 accordion--multi 可同时开多个(各自独立的信息块)。

单开(默认)

公司名称、证券代码、行业分类、上市日期与所属交易所。

这些字段决定后面所有指标怎么算,缺任何一项都会让勾稽校验失败。

打开第二项时,第一项会自动收起。

多开

数据源:交易所公开文件、公司定期报告、第三方行情镜像。

抓取频率:日频(收盘后)与季频(财报期),失败自动重试三次。

最后成功:今天 18:24 · 下一轮:明日 09:10

口径以最新年报为准;年报未披露的用最近一期季报并标注。

跨期变动超过 5% 需人工复核,勾稽关系 E1–E22 全部通过才入库。

加了 data-accordion-multi:各段独立,不互相影响。

为什么这里写了好几行字: 原来每段只有一句「网络」「计算」类的话(11–16 字符), 视觉上就是个空壳 —— 真机实测后判定为 「感觉非常廉价」「像是没多写、东西被吃掉了」。 ⇒ 面板只有一行字时,用户无法判断这个组件在真实场景里长什么样。 demo 要展示的就是真实信息密度。

禁用的分段

面板里怎么排:分列 / 表格 / 标题下的一句话

这一块同时演示四个"藏在面板里"的类,所以四个都展开(多开模式):
· .accordion--flush 去掉外框,融进已有卡片或侧栏
· accordion__hint 在标题下写"展开后有什么",减少无谓展开
· cols-2 / cols-3 / cols-auto 给面板内容分列(≥720px 才分列)
· .acc-table 面板里的表格:窄屏横向滚动,不挤压换行

营业总收入:含主营业务与其他业务收入,不含投资收益。

营业成本:与收入同口径,不含期间费用。

期间费用:销售、管理、研发、财务四项之和。

归母净利润:扣除少数股东损益后的净利润。

2024
收入 1,284,300 万元

2025
收入 1,402,110 万元

2026
收入 1,536,880 万元

字段:证券代码

字段:行业分类

字段:上市日期

字段:交易所

字段:审计机构

营业总收入与同比(单位:万元)
期间 营业总收入 同比
2024 年度 1,284,300 —
2025 年度 1,402,110 +9.17%
2026 年度 1,536,880 +9.61%

结构要求(APG 原文)

heading 包住 button,不是 button 套 heading:

<h3><button aria-expanded="true">标题</button></h3>

APG 原文:"place the heading tag around the button, not inside it, as this would prevent some screen readers (such as VoiceOver and TalkBack) from reading it." 写反了 VoiceOver / TalkBack 读不出标题。

键盘(APG 原文)

Enter / Space 切换 —— 但本组件没有写 keydown 监听

因为原生 <button> 本身就响应这两个键并触发 click —— 写了反而双触发(keydown 切一次、click 又切一次)。 这是「用原生控件」的又一处收益:无障碍行为免费且必然正确。

⚠️ 本组件故意没有方向键 / Home / End。 APG 明确写:"arrow / Home / End key navigation is no longer part of the APG Accordion keyboard interaction." 那是 tabs 的契约(roving tabindex)—— 照抄给 accordion 是把两个模式混了。

role="region" 的数量上限

APG 警告:超过约 6 个可同时展开的面板时,给每个 panel 加 role="region" 会造成 "landmark region proliferation"(地标泛滥)—— 读屏用户的地标列表会被几十个「分区」淹没。 ⇒ 面板数 > 6 时不要加,本组件用 accordion--many 关闭它。

对照:两处最容易写错的地方

❌ 用 div 当 trigger

数据源与口径

<div class="accordion__trigger"> 键盘上 Tab 不到、 也不响应 Enter/Space —— 它一个 button 都不是。 APG 要求 header 里是 role="button" 的元素, 用原生 <button> 最省事也最可靠。

✅ heading 包住原生 button

同一个外观,一个按钮元素。Enter / Space 由浏览器负责 —— 本组件的 JS 一行 keydown 都没写,写了反而会双触发。

❌ 折叠时只用 max-height: 0

这一整段文字,读屏此刻仍然念得出来。

里面的这个链接,Tab 也仍然进得去

这一栏看起来和右边一样空 —— 差别不在视觉上,在第 1 次按 Tab 之后。 这块的高度被压成了 0,你看不见它, 但按一下 Tab,焦点会停在里面的链接上;读屏也会把那句"仍然念得出来"念完。 内容在无障碍树里仍然活着,只是视觉上消失。

✅ hidden / display:none

(这一栏故意是空的:内容被 hidden 之后连占位都不留,这正是重点。)

同样看不见,但内容真的离开了无障碍树: Tab 到不了、读屏也不念。折叠面板收起时必须这样。