真正可靠的方式是用 details[open] summary::before 和 details summary::before 配合 list-style: none 实现加减号切换,Chrome中 summary::marker 无效且无法响应状态变化。
浏览器对 summary 的样式支持非常有限,::marker 在部分浏览器(如Firefox)里能改符号,但Chrome/Edge默认忽略它,且无法区分展开/收起状态。真正可靠的方式是用 ::before 配合 details[open] 选择器做状态判断。
summary::marker —— 它在Chrome中完全不生效,且无法响应 open 状态变化details[open] summary::before 和 details summary::before 两个规则分别定义收起/展开时的符号list-style: none 清除默认 marker以下代码兼容 Chrome、Firefox、Safari(≥17.4),无需JS:
details summary {list-style: none;position: relative;padding-left: 24px;}details summary::before {content: "+";position: absolute;left: 0;top: 50%;transform: translateY(-50%);}details[open] summary::before {content: "−";}
position: relative 和 absolute 是为了精确定位符号,避免影响文本流top: 50%; transform: translateY(-50%) 实现垂直居中,比 line-height 更稳定"−"(U+2212,不是短横 -)视觉更协调;也可换成 "−" 或 Unicode ✕/✓,但需注意字体支持常见现象是加号点击没反应,或符号和文字错位——本质是 summary 的默认 display 值和盒模型导致的。
summary 没被设成 display: inline,否则 position: absolute 失效;推荐显式声明 display: list-item 或保持默认 display: block
overflow: hidden,或 summary 上设置了过小的 height/line-height
summary 加 padding(比如 padding: 8px 12px),不要只依赖图标区域CSS transition 对 content 属性无效,所以不能直接给 ::before 的 content 加动画。但可以间接实现旋转/缩放类动效。
transform: rotate(45deg) + scale(1.2) 模拟“+”,再通过 details[open] summary::before 切换回 rotate(0)
details 上设 transition,因为 open 属性本身不触发 CSS 过渡;只能对 summary 内部可动画属性(如 color、background、transform)做过渡details 的即时反馈预期[open] 或忘了清 list-style 就会白忙活。