input[type="range"]{/* style setting variables */--track-height:.5ex;--track-fill:0%;--thumb-size:3ex;--thumb-offset:-1.25ex;--thumb-highlight-size:0px;appearance:none;/* clear styles, make way for mine */display:block;inline-size:100%;/* fill container */
margin:1ex0;/* ensure thumb isn't colliding with sibling content */background:transparent;/* bg is in the track */outline-offset:5px;/* focus styles have space */
input[type="range"]::-webkit-slider-runnable-track{appearance:none;/* clear styles, make way for mine */block-size:var(--track-height);border-radius:5ex;background:/* hard stop gradient: - half transparent (where colorful fill we be) - half dark track fill - 1st background image is on toplinear-gradient(toright,transparentvar(--track-fill),var(--surface1)0%/* colorful fill effect, behind track surface fill */var(--brand-bg-gradient)fixed;
/* grab sliders on page */constsliders=document.querySelectorAll('input[type="range"]')/* take a slider element, return a percentage string for use in CSS */constrangeToPercent=slider=>{constmax=slider.getAttribute('max')||10;constpercent=slider.value/max*100;return`${parseInt(percent)}%`;/* on page load, set the fill amount */sliders.forEach(slider=>{slider.style.setProperty('--track-fill',rangeToPercent(slider));/* when a slider changes, update the fill prop */slider.addEventListener('input',e=>{e.target.style.setProperty('--track-fill',rangeToPercent(e.target));
input[type="range"]::-webkit-slider-thumb{appearance:none;/* clear styles, make way for mine */cursor:ew-resize;/* cursor style to support drag direction */border:3pxsolidvar(--surface3);block-size:var(--thumb-size);inline-size:var(--thumb-size);margin-top:var(--thumb-offset);border-radius:50%;background:var(--brand-bg-gradient)fixed;
@custom-media--motionOK(prefers-reduced-motion:no-preference);::-webkit-slider-thumb{/* shadow spread is initally 0 */box-shadow:000var(--thumb-highlight-size)var(--thumb-highlight-color);/* if motion is OK, transition the box-shadow change */@media(--motionOK){transition:box-shadow.1sease;/* on hover/active state of parent, increase size prop */@nestinput[type="range"]:is(:hover,:active) & {
--thumb-highlight-size:10px;
input[type="checkbox"]{inline-size:var(--space-sm);/* increase width */block-size:var(--space-sm);/* increase height */outline-offset:5px;/* focus style enhancement */accent-color:var(--brand);/* tint the input */position:relative;/* prepare for an absolute pseudo element */transform-style:preserve-3d;/* create a 3d z-space stacking context */margin:0;cursor:pointer;
transform-style 和 position 样式为我们稍后介绍的用于设置精彩集锦样式的伪元素做准备。除此之外,我提出的大部分建议都是一些个人风格方面的小建议。我希望将光标设为指针,我喜欢轮廓偏移,默认复选框太小,如果支持accent-color,请将这些复选框纳入品牌配色方案。
<label for="text-notifications">
<h3>Text Messages</h3>
<small>Get notified about all text messages sent to your device</small>
</label>
在标签上,添加一个 for 属性,指向 ID 为 <label for="text-notifications"> 的复选框。在复选框中,请为名称和 ID 添加相同的值,以确保用户可以使用各种工具和技术(例如鼠标或屏幕阅读器)找到该复选框:<input type="checkbox" id="text-notifications" name="text-notifications">。建立关联后,您可以免费使用 :hover、:active 等功能,从而增加与表单互动的方式。
@custom-media--motionOK(prefers-reduced-motion:no-preference);input[type="checkbox"]::before{--thumb-scale:.01;/* initial scale of highlight */--thumb-highlight-size:var(--space-xl);content:"";inline-size:var(--thumb-highlight-size);block-size:var(--thumb-highlight-size);clip-path:circle(50%);/* circle shape */position:absolute;/* this is why position relative on parent */top:50%;/* pop and plop technique (https://web.dev/centering-in-css#5-pop-and-plop) */left:50%;background:var(--thumb-highlight-color);transform-origin:centercenter;/* goal is a centered scaling circle */transform:/* order here matters!! */translateX(-50%)/* counter balances left: 50% */translateY(-50%)/* counter balances top: 50% */translateZ(-1px)/* PUTS IT BEHIND THE CHECKBOX */scale(var(--thumb-scale))/* value we toggle for animation */will-change:transform;@media(--motionOK){/* transition only if motion is OK */transition:transform.2sease;/* on hover, set scale custom property to "in" state */input[type="checkbox"]:hover::before{--thumb-scale:1;
创建圆形伪元素是一件简单的工作,但将其放置在所附加元素后面却比较困难。下面是问题解决前后的对比图:
这绝对是一个微互动,但对我来说,保持视觉一致性非常重要。动画缩放技术与我们在其他地方使用的方法相同。我们将自定义属性设为新值,并让 CSS 根据动作偏好设置对其进行转换。其中的关键功能是 translateZ(-1px)。父元素创建了一个 3D 空间,而此伪元素子元素通过将自己稍微向后放置在 z 空间中来访问该空间。