/* Kole UI Mobile · Switch 样式 — 对齐移动端规格 §29 开关:轨道 + 滑块,开态用「滑块位移 + 品牌底色」双通道表达(不靠颜色单独表意); 整行(开关 + 文字)是热区,行高不小于 44px —— 开关本体视觉只有 48×28,单点本体手指点不中; 控件是原生 button + role="switch" + aria-checked(读屏播报「开关」,不是「复选框」)。 */ .kole-m-switch { /* 组件级变量:业务侧可在容器上覆盖 */ --kole-m-switch-track-w: 48px; /* 轨道宽 */ --kole-m-switch-track-h: 28px; /* 轨道高 */ --kole-m-switch-knob: 24px; /* 滑块直径(轨道高 − 2×2px 内边距) */ --kole-m-switch-duration: 150ms; /* 滑块位移与底色过渡时长 */ box-sizing: border-box; display: flex; align-items: center; gap: var(--kole-space-12); width: 100%; min-height: var(--kole-m-touch-target); padding: var(--kole-space-8) var(--kole-m-gutter); border: 0; background: var(--kole-color-card-bg); color: var(--kole-color-text-body); font-family: inherit; font-size: var(--kole-m-font-size-body); line-height: 1.4; text-align: start; cursor: pointer; touch-action: manipulation; } /* 变体 labelPlacement=left:文字在左、开关在右(整行右对齐的值区风格) */ .kole-m-switch--left { flex-direction: row-reverse; } /* 变体 labelPlacement=left 时文字占满,开关贴右 */ .kole-m-switch--left .kole-m-switch__text { text-align: end; } .kole-m-switch__track { position: relative; flex: 0 0 auto; display: inline-block; box-sizing: border-box; width: var(--kole-m-switch-track-w); height: var(--kole-m-switch-track-h); border-radius: 999px; /* 关态轨道用「未选中图标」色(3.23:1):开关状态承载信息,需满足 WCAG 1.4.11 的 3:1 */ background: var(--kole-color-icon-inactive); transition: background var(--kole-m-switch-duration) var(--kole-ease-standard); } .kole-m-switch__knob { position: absolute; top: 2px; left: 2px; box-sizing: border-box; width: var(--kole-m-switch-knob); height: var(--kole-m-switch-knob); border-radius: 50%; background: var(--kole-color-card-bg); box-shadow: var(--kole-shadow-low); transition: transform var(--kole-m-switch-duration) var(--kole-ease-standard); } .kole-m-switch__text { flex: 1 1 auto; min-width: 0; } /* 状态 on:滑块右移 + 轨道变品牌色(与 aria-checked="true" 同步写) */ .kole-m-switch.is-on .kole-m-switch__track { background: var(--kole-color-brand); } .kole-m-switch.is-on .kole-m-switch__knob { transform: translateX(calc(var(--kole-m-switch-track-w) - var(--kole-m-switch-knob) - 4px)); } /* 变体 size=small:紧凑表单用(轨道 40×22) */ .kole-m-switch--small { --kole-m-switch-track-w: 40px; --kole-m-switch-track-h: 22px; --kole-m-switch-knob: 18px; } /* 状态 disabled:置灰且不响应 */ .kole-m-switch.is-disabled { color: var(--kole-color-text-disabled); cursor: not-allowed; } .kole-m-switch.is-disabled:active { background: var(--kole-color-card-bg); } .kole-m-switch:active:not(.is-disabled) { background: var(--kole-color-table-header-bg); } .kole-m-switch:focus-visible { outline: 2px solid var(--kole-color-focus-ring); outline-offset: -2px; } /* 减少动态偏好:滑块瞬时到位,不做过场动画 */ @media (prefers-reduced-motion: reduce) { .kole-m-switch__track, .kole-m-switch__knob { transition: none; } }