ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

30 seconds of code 之 CSS 变量(Custom Properties)完全指南:语法、主题化与实战技巧

30 seconds of code 之 CSS 变量(Custom Properties)完全指南:语法、主题化与实战技巧 教程文档【免费下载链接】30-seconds-of-codeCoding articles to level up your development skills项目地址https://gitcode.com/gh_mirrors/30/30-seconds-of-code点击查看免费下载CSS 变量官方名称为 CSS 自定义属性Custom Properties是现代 CSS 中最基础也最强大的特性之一它让开发者可以在样式表中定义具名变量并复用从而显著提升样式的可维护性与扩展性。本文以 variables.md 为核心骨架结合仓库中缓动变量、鼠标跟随渐变、卡片悬停、嵌套圆角、排版比例、交错动画等多个实战片段系统讲解 CSS 变量的语法、级联与继承机制、主题化与暗色模式方案、共享样式技巧以及 fallback、calc()组合等进阶用法帮助你掌握一套可立即落地的设计令牌Design Token工作流。什么是 CSS 变量CSS 变量官方名称CSS 自定义属性的行为方式与其他编程语言中的变量非常相似你可以定义带有名称的变量为其赋一个具体的值然后在整份 CSS 文档中复用这些值。这使它们成为在不同元素和组件之间共享样式的绝佳工具典型应用包括垂直节奏vertical rhythm、排版变量与颜色调色板等。与 Sass、Less 等预处理器变量不同CSS 变量是运行在浏览器层的原生能力具有两个关键特性参与级联变量值会沿着 DOM 树从父元素继承到子元素可被覆盖任意作用域内都可以重新声明同名变量覆盖继承而来的值。正是这两个特性构成了后续主题化、组件定制等所有高级用法的基础。语法基础双横线前缀与 var() 函数按照自定义属性的记法规范CSS 变量必须以两个短横线--作为前缀例如--my-color。要读取变量的值则使用var()函数例如var(--my-color)。下面是一个最小可用的示例展示了定义变量与使用变量两个环节/* 定义变量 */ :root { --my-color: #f0c1a8; } /* 使用变量 */ body { color: var(--my-color); }需要留意的是var()函数在解析时是按需取值的——只有当某条声明真正使用了var()浏览器才会去查找对应的自定义属性值。这意味着变量可以在任意规则块中声明也可以引用其他变量甚至可以出现在media查询、:hover状态等任意上下文中。级联与继承变量如何沿 DOM 树流动CSS 变量遵循标准 CSS 的级联规则元素会从父级继承变量值。把全局变量放在:root元素中是所有元素html及其后代都能访问这些变量的最简做法而在某个具体元素上重新声明同名变量则会在该元素及其子树范围内覆盖全局值。下面这个示例演示了全局变量定义在:root、子元素从父元素继承变量、以及局部覆盖继承值的完整链路/* 全局变量定义在 :root 元素中。 */ :root { --bg-color: #fff; --main-color: #000; --secondary-color: #222; } /* 元素会从父元素继承变量。 */ body { background-color: var(--bg-color); color: var(--main-color); } small { color: var(--secondary-color); } /* 元素可以定义自己的值和变量从而覆盖继承值。*/ body.dark { --bg-color: #080808; --main-color: #fff; --secondary-color: #ccc; }从仓库的其他片段可以印证这一机制在真实场景中的价值。例如 nested-border-radius.md 中通过:root之外的选择器作用域配合calc()推导派生值.outer { --outer-radius: 24px; --padding: 8px; --inner-radius: calc(var(--outer-radius) - var(--padding)); border-radius: var(--outer-radius); padding: var(--padding); } .inner { border-radius: var(--inner-radius); }这里--inner-radius在.outer作用域内由calc()计算得出并被其子元素.inner继承使用是级联 继承 计算三者协同的典型示范。实战一主题化与暗色模式CSS 变量最常见的应用场景之一是主题化与暗色模式dark mode。核心思路是用变量建立全站共享的调色板然后通过在公共祖先元素如body上切换类名一次性替换整套配色。/* 全局变量定义在 :root 元素中。 */ :root { --bg-color: #fff; --main-color: #000; --secondary-color: #222; } /* 元素会从父元素继承变量。 */ body { background-color: var(--bg-color); color: var(--main-color); } small { color: var(--secondary-color); } /* 元素可以定义自己的值和变量从而覆盖继承值。*/ body.dark { --bg-color: #080808; --main-color: #fff; --secondary-color: #ccc; }当切换body上的.dark类时body及其所有后代如small使用的颜色会自动更新——无需逐条改写任何规则。这种单点切换、全局生效的方案是暗色模式实现中最简洁、最易维护的做法之一。实战二组件共享样式与变体定制另一个实用场景是为元素的特定变体定义共享的自定义样式。通过在选择器作用域内声明变量可以定制整棵组件树而无需重复书写样式。下面的示例来自 variables.md 原文其级联演示比前一个示例更进一步同时引入了不同元素间共享样式的思想.btn { --bg-color: #002299; --text-color: #fff; --highlight-color: #669900; background-color: var(--bg-color); color: var(--text-color); } /* --highlight-color 同样对其子元素 .btn .highlight 可见 */ .btn .highlight { color: var(--highlight-color); } /* .btn.danger .highlight 将使用 .btn-danger 中定义的 --highlight-color */ .btn-danger { --bg-color: #dd4a68; --text-color: #000; --highlight-color: #990055; }这里的关键点在于.btn-danger只需要覆盖三个变量的值其内部.highlight子元素的样式规则完全不需要重复书写。当你需要维护多个变体danger、primary、success…时这种变量即组件接口的模式能极大减少重复代码。实战三与 JavaScript 协作的动态交互CSS 变量可以被 JavaScript 通过CSSStyleDeclaration.setProperty()动态更新从而在不依赖框架的情况下实现高性能的交互效果。仓库中有多个片段展示了这一模式。鼠标光标渐变跟随mouse-cursor-gradient-tracking.md 使用--x、--y两个变量记录鼠标在按钮内的位置用--size控制渐变的尺寸.mouse-cursor-gradient-tracking { position: relative; background: #7983ff; overflow: hidden; } .mouse-cursor-gradient-tracking::before { --size: 0; content: ; position: absolute; left: var(--x); top: var(--y); width: var(--size); height: var(--size); background: radial-gradient(circle closest-side, pink, transparent); transform: translate(-50%, -50%); transition: width 0.2s ease, height 0.2s ease; } .mouse-cursor-gradient-tracking:hover::before { --size: 200px; }const btn document.querySelector(.mouse-cursor-gradient-tracking); btn.addEventListener(mousemove, e { const rect e.target.getBoundingClientRect(); const x e.clientX - rect.left; const y e.clientY - rect.top; btn.style.setProperty(--x, x px); btn.style.setProperty(--y, y px); });每一次mousemove触发时脚本通过getBoundingClientRect()获取按钮位置、计算光标相对坐标再写入--x、--y浏览器只更新这两个自定义属性的值渐变就会随之移动形成跟随效果。卡片位移悬停card-hover-effects.md 中的 Shifting card 效果利用--dx、--dy记录光标相对卡片中心的偏移并将其作为transform的乘数.shifting-card { transition: transform 0.2s ease-out; transform: rotateX(calc(10deg * var(--dx, 0))) rotateY(calc(10deg * var(--dy, 0))); }const card document.querySelector(.shifting-card); const { x, y, width, height } card.getBoundingClientRect(); const cx x width / 2; const cy y height / 2; const handleMove e { const { pageX, pageY } e; const dx (cx - pageX) / (width / 2); const dy (cy - pageY) / (height / 2); e.target.style.setProperty(--dx, dx); e.target.style.setProperty(--dy, dy); }; card.addEventListener(mousemove, handleMove);注意这里var(--dx, 0)中的0就是 fallback 值——在变量尚未被 JS 写入例如页面刚加载、鼠标未移动时位移退化为 0页面不会出现异常跳变。交错列表动画staggered-animation.md 展示了如何用内联自定义属性--i实现列表逐项延迟出现的交错动画ul classstagger-menu li style--i: 0Home/li li style--i: 1Pricing/li li style--i: 2Account/li li style--i: 3Support/li li style--i: 4About/li /ul.stagger-menu li { opacity: 0; transform: translateX(100%); transition-property: opacity, transform; transition-duration: 0.3s; transition-timing-function: cubic-bezier(0.750, -0.015, 0.565, 1.055); } .menu-toggler:checked ~ .stagger-menu li { opacity: 1; transform: translateX(0); transition-delay: calc(0.055s * var(--i)); }transition-delay: calc(0.055s * var(--i))让每个列表项根据其序号获得递进的延迟形成一个接一个滑入的视觉效果。这里同时用到了内联变量HTMLstyle属性直接声明--i、calc()与变量组合计算两个技巧。实战四用变量承载设计系统除了交互效果CSS 变量还非常适合承载设计系统中的基础数值。排版比例Typography Scaletypographic-scale-basics.md 将字体、字号、行高、字重全部定义为变量并用黄金比例1.618生成整张排版刻度:root { --font-family: Roboto, sans-serif; --font-size: 18px; --font-weight: 300; --line-height: 1.618; } * { font-family: var(--font-family); font-size: var(--font-size); font-weight: var(--font-weight); line-height: var(--line-height); } .sub-heading { --font-size: 1.618rem; --font-weight: 600; } .heading { --font-size: 2.618rem; --font-weight: 400; } .large-heading { --font-size: 4.236rem; --font-weight: 500; } .footnote { --font-size: 0.618rem; --font-weight: 500; }每个层级只覆盖--font-size与--font-weight而font-family、line-height等公共属性由*选择器统一读取变量改动基础值时整站排版同步更新。缓动变量Easing Variableseasing-variables.md 则把整套cubic-bezier()缓动函数存进变量让动画曲线具备语义化名称:root { /* ease-in 对应 cubic-bezier(0.42, 0, 1.0, 1.0) */ --ease-in-quad: cubic-bezier(0.55, 0.085, 0.68, 0.53); --ease-in-cubic: cubic-bezier(0.55, 0.055, 0.675, 0.19); --ease-in-quart: cubic-bezier(0.895, 0.03, 0.685, 0.22); --ease-in-quint: cubic-bezier(0.755, 0.05, 0.855, 0.06); --ease-in-expo: cubic-bezier(0.95, 0.05, 0.795, 0.035); --ease-in-circ: cubic-bezier(0.6, 0.04, 0.98, 0.335); /* ease-out 对应 cubic-bezier(0, 0, 0.58, 1.0) */ --ease-out-quad: cubic-bezier(0.25, 0.46, 0.45, 0.94); --ease-out-cubic: cubic-bezier(0.215, 0.61, 0.355, 1); --ease-out-quart: cubic-bezier(0.165, 0.84, 0.44, 1); --ease-out-quint: cubic-bezier(0.23, 1, 0.32, 1); --ease-out-expo: cubic-bezier(0.19, 1, 0.22, 1); --ease-out-circ: cubic-bezier(0.075, 0.82, 0.165, 1); /* ease-in-out 对应 cubic-bezier(0.42, 0, 0.58, 1.0) */ --ease-in-out-quad: cubic-bezier(0.455, 0.03, 0.515, 0.955); --ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1); --ease-in-out-quart: cubic-bezier(0.77, 0, 0.175, 1); --ease-in-out-quint: cubic-bezier(0.86, 0, 0.07, 1); --ease-in-out-expo: cubic-bezier(1, 0, 0, 1); --ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.15, 0.86); }使用时直接写transition: transform 0.3s var(--ease-out-expo)即可既避免了手写贝塞尔参数的记忆负担也让动画风格在全站保持一致。进阶技巧与注意事项最后牢记以下使用 CSS 变量时的高频技巧定义 fallback 值var()函数接受第二个参数作为兜底例如var(--text-color, black)在--text-color未定义时默认使用black。大小写敏感CSS 变量是区分大小写的--text-color与--Text-color是两个不同的变量务必注意命名的一致性。支持内联声明与普通样式一样变量可以直接写在 HTML 的style属性中例如div style--text-color: red这非常适合组件化传参。组合与嵌套var()调用可以嵌套例如var(--main-color, var(--other-color))即先尝试--main-color再退回到--other-color变量可以作为参数传给其他函数如calc(var(--spacing) * 2)变量也可以相互赋值例如--text-color: var(--main-color)。结合仓库中的实现还可以补充两条工程建议为变量提供合理的 fallback正如 card-hover-effects.md 中var(--dx, 0)的做法对可能尚未赋值的变量始终给出安全默认值可避免初始化时序导致的布局抖动。用calc()推导派生值nested-border-radius.md 中--inner-radius: calc(var(--outer-radius) - var(--padding))的思路说明与其在多处手工同步数值不如让派生值由源变量计算而来保证改一处、全局联动。该文也提醒当存在多个padding/margin时公式需要按实际场景调整。小结CSS 变量自定义属性是原生 CSS 中连接可维护性与动态性的关键特性。以 variables.md 为起点你可以用:rootvar()建立全站设计令牌覆盖颜色、排版、间距与缓动曲线利用级联与继承实现主题化、暗色模式与组件变体定制通过 JS 写入自定义属性实现鼠标跟随、交错动画等动态效果善用 fallback、calc()组合与内联声明让代码更健壮、更灵活。仓库中的 easing-variables.md、typographic-scale-basics.md、mouse-cursor-gradient-tracking.md、card-hover-effects.md、staggered-animation.md 与 nested-border-radius.md 等片段均可在 css 合集 下继续阅读帮助你把这些技巧组合成完整的现代 CSS 工作流。赞分享教程文档【免费下载链接】30-seconds-of-codeCoding articles to level up your development skills项目地址https://gitcode.com/gh_mirrors/30/30-seconds-of-code点击查看免费下载相关推荐30-seconds-of-css变量使用利用CSS变量实现主题定制与样式复用30 seconds of css变量使用利用CSS变量实现主题定制与样式复用 你是否还在为网站主题切换时大量重复的CSS代码而烦恼是否希望用更简洁的方式实前端cuda-samples 之 simpleCUBLAS用 CUBLAS 库在 GPU 上完成 GEMM 矩阵乘法全流程实战cuda samples 之 simpleCUBLAS用 CUBLAS 库在 GPU 上完成 GEMM 矩阵乘法全流程实战 导读 本篇文章以 NVIDIA c教程文档Tachometer 多浏览器测试Chrome、Firefox、Safari 和 Edge 的完整支持指南Tachometer 多浏览器测试Chrome、Firefox、Safari 和 Edge 的完整支持指南 想要确保你的Web应用在所有主流浏览器上都能提供最上一篇深夜赶简历的救场方案在线AI简历编辑器 Magic Resume 本地部署与使用实录下一篇Flipper Zero金属探测器DIY从零制作电磁感应线圈的终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表