设置复选框样式

使用语义化、无障碍的 HTML,将每个复选框与其标签相关联,方法是将 <input> 嵌套在 <label> 中,或将标签的 for 属性与输入的 id 属性相匹配。

现代 CSS 提供了两种设置复选框样式的方法:使用 accent-color 自定义原生外观,或在 <input type="checkbox"> 元素上使用 appearance: none 替换默认呈现方式。

使用 accent-color 进行原生自定义

如需实现简单、品牌一致的样式,同时保留原生渲染、键盘行为、验证和操作系统焦点指示器,请使用 accent-color。

.checkbox-native {
  accent-color: #1a73e8;

  /* Sizing is controlled via relative units */
  inline-size: 1.25em;
  aspect-ratio: 1;
  margin: 0;
  cursor: pointer;
}

使用 appearance: none 进行完全自定义的样式设置

如果设计需要控制复选框的形状、大小、状态或指示器,请使用 appearance: none。这会移除原生视觉样式,同时保留 <input> 作为互动目标。

为 --checkbox-size 和 --checkbox-icon-size 设置明确的相对大小,因为 appearance: none 会移除浏览器的默认尺寸。图标应小于复选框,以便为其边框和视觉内边距留出空间。

/* Reusable SVG assets */
:root {
  --icon-check: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'></polyline></svg>");
  --icon-dash: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='4.5' stroke-linecap='round' stroke-linejoin='round'><line x1='5' y1='12' x2='19' y2='12'></line></svg>");
}

/* Custom checkbox */
.checkbox-custom {
  --checkbox-size: 1.25em;
  --checkbox-icon-size: 0.7em;

  appearance: none;
  display: inline-grid;
  place-content: center;
  inline-size: var(--checkbox-size);
  aspect-ratio: 1;
  margin: 0;
  border: 2px solid currentColor;
  cursor: pointer;

  &::before {
    content: "";
    inline-size: var(--checkbox-icon-size);
    aspect-ratio: 1;
    background-color: currentColor;
    mask: var(--checkbox-icon) no-repeat center / contain;
    scale: 0;

    @media (prefers-reduced-motion: no-preference) {
      transition: scale 150ms ease;
    }

    @media (forced-colors: active) {
      background-color: CanvasText;
    }
  }

  &:checked {
    --checkbox-icon: var(--icon-check);
  }

  &:indeterminate {
    --checkbox-icon: var(--icon-dash);
  }

  &:is(:checked, :indeterminate)::before {
    scale: 1;
  }

  &:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 2px;
  }

  &:disabled {
    cursor: not-allowed;
    opacity: 0.5;
  }
}

不确定状态

不确定状态无法通过 HTML 属性设置;请在 JavaScript 中设置 indeterminate DOM 属性 (checkbox.indeterminate = true),并确保 :indeterminate 伪类在视觉上与 :checked 和未选中状态有所区别:

  • 原生 (accent-color):由浏览器使用元素的 accent-color 自动设置样式(无需额外的 :indeterminate CSS 规则)。
  • 自定义 (appearance: none):如上所示,在 .checkbox-custom:indeterminate 将 --checkbox-icon 换成 var(--icon-dash)。
const selectAll = document.querySelector("#select-all");
selectAll.indeterminate = true;

无障碍功能和互动

  • 务必使用 :focus-visible 而非 :focus 来设置自定义复选框上的焦点指示器样式,以便在键盘导航时显示明显的轮廓,而在指针点击时不显示。
  • 请勿使用 outline: none 或隐藏复选框上的焦点指示器。
  • 务必确保复选框或其封装 <label> 提供至少 44px x 44px 的互动点击目标,同时以相对单位设置视觉复选框的大小:

    label {
      display: inline-flex;
      align-items: center;
      gap: 0.65rem;
      min-block-size: 44px;
      cursor: pointer;
    }
    
  • 务必提供 :disabled 样式变体,以降低不透明度并设置 cursor: not-allowed,从而清晰传达非活跃状态。

使用 accent-color 时需要注意的问题

accent-color 的浏览器呈现方式各不相同。 对于通常绘制在强调色背景上的指示器(例如复选框标记和单选按钮圆点),浏览器可能会采用不同的处理方式:

  • Chromium 和 Firefox 通常会选择对比鲜明的指示器颜色。
  • Safari 可能会在浅色模式下保留白色指示器,或在深色模式下保留黑色指示器,同时修改其背后的强调色。这种调整并不总是能为每种提供的颜色提供足够的对比度,因此请在 Safari 中测试重要的组合,包括浅色和深色配色方案。不要假设 Safari 会自动选择对比度最佳的指示器颜色。

后备策略

accent-color 的回退和浏览器支持

accent-color 属性是渐进增强。 不支持此属性的浏览器会忽略它,并使用其默认界面颜色。

CSS 遮罩