CSS Handbook · 现代进阶特性

第十一章 / 11.5 表单控件样式

第十一章 · 11.5 节

表单控件样式


2.4 节已经学过 :required:invalid:checked 这些表单相关的伪类,用来"根据状态选中元素"。这一节补上另一半:如何真正改变复选框、单选框、下拉框这些原生控件的外观。

appearance:接管原生外观

复选框、单选框、下拉框默认由操作系统绘制,样式无法直接用普通属性覆盖。appearance: none 可以去掉这层系统默认外观,把控件变成一个"空白画布",之后就能像 div 一样自由设置 borderbackground 等属性:

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;
}