<p>纯 CSS 实现 iOS 风格开关需用 checkbox:checked + label 触发,滑块位移用 transform: translateX() 和 calc(100% - 28px) 确保精准,transition 仅作用于 transform 和 opacity,轨道高 34px、圆角 17px,滑块 28px 圆角 14px,label 点击区 ≥44×44px。</p>
纯 CSS 实现 iOS 风格开关(toggle switch),核心不是靠 JS 控制 class,而是用 input[type="checkbox"] 的 :checked 状态 + transition 控制滑块位移。动画必须只作用于 transform 和 opacity,否则会卡顿或跳变。
不能用 button 或 div 模拟开关——:checked 伪类只对真实表单控件生效,且仅支持 checkbox 和 radio。常见错误是把 input 放在 label 外、或漏掉 id/for 关联,导致点击无响应。
input 必须有 id,label 必须用 for 属性指向它;或者直接把 input 写在 label 标签内部(更稳妥)label 加 onclick 或监听事件——它只是触发器,状态由 input 承载input 本身要隐藏,但不能用 display: none(会失去可访问性和状态监听),推荐 position: absolute; opacity: 0; pointer-events: none;
iOS 开关的“滑动”感本质是滑块(thumb)在轨道(track)内左右平移。不能用 left/right 做 transition,否则触发布局重排(reflow),移动端尤其卡顿。必须用 transform: translateX(),它只触发合成层绘制(compositor),性能稳定。
transform: translateX(0)
input:checked + .switch-track .switch-thumb 中设 transform: translateX(24px)(假设轨道宽 52px,滑块宽 28px,位移 = 轨道宽 − 滑块宽)transform 0.2s cubic-bezier(0.4, 0, 0.2, 1)(iOS 默认缓动曲线)iOS 开关的视觉特征是轨道两端半圆 + 滑块完全居中、无边框、轻微阴影。尺寸不匹配会导致滑块悬空、错位或边缘露白。
立即学习“前端免费学习笔记(深入)”;
.switch-track)高度建议 34px,圆角 17px(即 height / 2).switch-thumb)宽高统一为 28px,圆角 14px,背景用 linear-gradient 模拟高光margin-left: 2px 微调起始位置,确保未选中时左边缘对齐轨道左内边calc(100% - 28px) 更可靠,尤其在响应式场景下iOS 人机接口指南强制要求最小触控区域为 44pt × 44pt(约 44px × 44px)。如果只给 .switch-thumb 设尺寸,手指点不准就会失效。
label 的 padding 设为至少 12px(上下各 12px → 总高 34px + 24px = 58px),再加 min-width: 44px
label 是块级或 inline-block,且没有 overflow: hidden 截断点击热区label 上设置 user-select: none,某些旧版 Safari 会因此禁用点击真正难的是让滑块位移值在不同缩放、DPR、字体设置下都精确贴合轨道两端——别硬编码像素值,优先用 calc() 和百分比;另外,:checked + .switch-track .switch-thumb 这类选择器层级一旦嵌套过深或结构松散,就容易在 Safari 中失效,建议把开关封装成独立 div.switch 容器,所有子元素都相对它定位。