第十一章 · 11.5 节
表单控件样式
2.4 节已经学过 :required、:invalid、:checked 这些表单相关的伪类,用来"根据状态选中元素"。这一节补上另一半:如何真正改变复选框、单选框、下拉框这些原生控件的外观。
appearance:接管原生外观
复选框、单选框、下拉框默认由操作系统绘制,样式无法直接用普通属性覆盖。appearance: none 可以去掉这层系统默认外观,把控件变成一个"空白画布",之后就能像 div 一样自由设置 border、background 等属性:
input[type="checkbox"] { appearance: none; width: 18px; height: 18px; border: 2px solid #999; border-radius: 4px; display: inline-grid; place-content: center; } input[type="checkbox"]::before { content: ""; width: 10px; height: 10px; background: teal; clip-path: polygon(...); /* 用裁剪路径画一个对勾 */ transform: scale(0); transition: transform .1s; } input[type="checkbox"]:checked::before { transform: scale(1); /* 8.2 节学过的过渡,配合 :checked 状态切换 */ }
提醒
appearance: none 之后,浏览器不再提供任何默认的选中状态视觉反馈,务必自己补上 :checked、:focus-visible 样式,否则会造成可访问性倒退。accent-color:低成本改配色
如果只是想让复选框、单选框、进度条、range 滑块跟随品牌色,不需要动用 appearance: none 这种"推倒重来"的方式——accent-color 一行属性就能让浏览器用你指定的颜色重新绘制原生控件,同时保留系统的可访问性行为:
:root { accent-color: teal; }
DEMO · accent-color 覆盖前后对比
::placeholder 伪元素
输入框的占位文字可以通过 ::placeholder 伪元素单独设置颜色、字重,但要注意它能设置的属性有限(主要是文字相关属性,不支持 background 等布局属性):
input::placeholder { color: #aaa; font-style: italic; }
结合表单伪类使用
控件外观应该和 2.4 节的表单伪类联动,让用户能一眼看出当前状态,这比单纯"好看"更重要:
input:focus-visible { outline: 2px solid teal; outline-offset: 2px; } input:invalid:not(:placeholder-shown) { border-color: crimson; /* 只在用户已经输入内容后才提示错误,而非一进页面就标红 */ } input:disabled { background: #f2f2f2; cursor: not-allowed; }