极简设计系统必须用自定义元素,因其天然具备语义、无障碍、封装性与可索引性;class和框架组件无法保障样式隔离、属性合规与dom原生识别,而等自定义标签直接承载语义、强制封装、支持无障碍工具和搜索引擎校验。

极简设计系统不是靠删样式实现的,而是靠自定义元素把“语义”和“约束”直接写进 DOM —— ds-card 就是卡片,ds-heading 就是标题,没有 class、没有 BEM、没有 CSS-in-JS 抽象层,浏览器原生认得它,无障碍工具原生读得懂它。
为什么极简设计系统必须用自定义元素,而不是 class 或框架组件
用 class="ds-button" 写按钮,样式可能被 body * { font-size: 12px } 穿透覆盖;用 React 的 <button></button>,Lighthouse 扫不出它的 role 和 aria 属性;而 <ds-button></ds-button> 是真实 HTMLElement 实例,自带语义、可索引、可克隆、事件冒泡路径清晰。更重要的是:它天然强制封装——你没法在外部随便改它的 padding 或 color,除非你显式暴露 CSS custom property。
- 设计师说“所有标题行高统一为 1.5”,你只需在
ds-heading的 shadowRoot 里写line-height: 1.5,全局生效,无 grep 风险 - 想禁用某处按钮?直接写
<ds-button disabled></ds-button>,不用记is-disabled还是state="disabled" - 搜索引擎和 axe 工具能直接识别
<ds-form></ds-form>并校验其role="form"是否合规
如何让自定义元素真正“极简”,不破功
极简主义对自定义元素的容忍度比对普通 HTML 更高——因为它是你主动选择的封装层,一旦加了冗余,就是双重污染。关键动作是:只注入最小必要样式、禁用所有装饰性属性、放弃一切“看起来更精致”的妥协。
- Shadow DOM 内部的
<style></style>只允许出现:font-family(限系统字体链)、line-height(1.5 或 1.6)、margin-block(控制节奏)、color(仅 #000 / #333 / #666 三级灰)、font-weight(400 / 600) - 绝对禁止:
box-shadow、border(包括border-bottom)、background-color(除body外)、text-transform、letter-spacing - 图标必须退化为文字:用
[PDF]替代下载图标,用→替代箭头,不引入 inline SVG 或 Web Font - 所有间距靠
margin-block控制,不用<div class="spacer"> 或空 <code><p></p>attributeChangedCallback 怎么用才不踩坑
极简设计系统里,属性即 API。但
attributeChangedCallback不会响应初始 HTML 属性值——<ds-input value="hello"></ds-input>渲染时,value不会触发该回调,导致 shadow 内容为空。这是最常被忽略的断裂点。- 必须配合
static get observedAttributes()显式声明要监听的属性名,如['value', 'disabled'] - 在
connectedCallback中手动同步初始值:this.render(this.getAttribute('value')) - 不要在
constructor里读属性或操作 DOM,此时this.getAttribute返回 null,this.attachShadow可能报错 - 若需支持布尔属性(如
disabled),检查用this.hasAttribute('disabled'),而非getAttribute
注册时机与幂等性为什么决定成败
customElements.define()必须在首个<ds-xxx></ds-xxx>出现在 DOM 前完成,否则降级为HTMLUnknownElement,所有样式、行为、生命周期钩子全部失效——页面看起来“有”,实则只是个空壳。- 推荐在模块顶层立即执行注册,不要包裹在
DOMContentLoaded或函数里 - 使用
if (!customElements.get('ds-button'))做幂等保护,避免重复定义抛NotSupportedError - 标签名必须含连字符:
ds-button✅,dsbutton❌,ds_button❌ - 如果项目用多个包引入同一组件,注册逻辑必须收敛到单一入口,否则业务方无法感知冲突
真正难的不是写出一个
ds-button,而是让整个团队不再写<button class="btn btn--primary"></button>;不是禁用 border,而是让 border 这个概念在设计系统里根本不存在。极简设计系统的边界,是由自定义元素的命名、属性契约和 Shadow DOM 的物理隔离共同划出来的——越早接受这个边界,越少后期返工。 - 必须配合











