ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CSS 自定义属性(CSS 变量)完全指南:声明、作用域与深浅主题实战(The Odin Project 课程精讲)

CSS 自定义属性(CSS 变量)完全指南:声明、作用域与深浅主题实战(The Odin Project 课程精讲) CSS 自定义属性CSS 变量完全指南声明、作用域与深浅主题实战The Odin Project 课程精讲【免费下载链接】curriculumThe open curriculum for learning web development项目地址: https://gitcode.com/GitHub_Trending/cu/curriculum导读CSS 自定义属性Custom Properties又称 CSS 变量是编写大型样式表时最值得掌握的利器之一它允许你在文件中任意次数地引用同一个 CSS 值修改时只需改动定义处一处即可让所有引用同步生效。本篇文章以 The Odin Project 前端课程中intermediate_html_css/intermediate_css_concepts/custom_properties.md一课为主体系统讲解自定义属性的声明语法、var()访问方式、后备值fallback机制、选择器作用域与:root全局作用域并深入演示如何用它实现“深浅主题切换”与prefers-color-scheme系统主题跟随。学完本篇你将能够用自定义属性统一项目配色、集中维护重复值并独立实现网站明暗主题方案。为什么需要自定义属性在日常编写 CSS 时我们常常会遇到这样的窘境某一种颜色、间距或字号在多处重复出现例如一个浅红色同时被七个选择器引用。当需要微调这个颜色时就不得不在每个使用它的选择器里逐一修改既繁琐又容易遗漏还会让样式表越来越难以维护。自定义属性正是为解决这个问题而生。它允许我们把一个 CSS 值命名并存储起来然后在任意位置通过变量引用。以课程中的原话来说与其更新同一数值的所有实例不如只更新一处——即自定义属性本身。除此之外自定义属性还能帮助我们在整个项目中保持颜色、尺寸等设计令牌design token的一致性这一点在项目规模变大后尤其有价值。更进一步自定义属性可以在不同上下文不同的选择器、不同的媒体查询条件中被重新定义。这一特性使其成为实现网站深色/浅色主题切换的天然方案——这正是如今众多网站标配的能力。本课在 The Odin Project 课程体系中的位置处于中间层 HTML/CSS 的进阶 CSS 概念部分与 CSS 函数、CSS 单位、进阶选择器 等课程并列是衔接基础 CSS 与响应式、主题化实践的关键一课。自定义属性的声明与使用自定义属性的声明与访问语法上与我们熟悉的普通规则声明非常接近。先看课程中的核心示例.error-modal { --color-error-text: red; --modal-border: 1px solid black; --modal-font-size: calc(2rem 5vw); color: var(--color-error-text); border: var(--modal-border); font-size: var(--modal-font-size); }这段代码包含两个关键动作声明Declaration以双连字符--开头命名属性后跟属性名与值。命名规则为属性名区分大小写color-error-text与Color-Error-Text不是同一个属性使用连字符分隔单词Kebab case因为空格不合法--color error text无法工作属性名可以自由定义值可以是任何合法的 CSS 值颜色值、简写值shorthand甚至是更复杂的函数例如calc(2rem 5vw)。访问Access将var()函数作为某个 CSS 属性的值并把自定义属性连同开头的双连字符放进括号内浏览器便会解析并替换为对应的值。值得指出的是自定义属性的值与calc()函数的组合在课程中是被反复强调的组合拳。在同目录的 CSS 函数一课 中就给出了一个在:root上声明变量并交给calc()计算的典型用法:root { --header: 3rem; --footer: 40px; --main: calc(100vh - calc(var(--header) var(--footer))); }即main 100vh - (header footer)calc()负责混合不同单位vh、rem、px的数学运算。可见变量存储值 calc()动态计算的组合能够显著减少重复 CSS 规则——这正是自定义属性价值的直接体现。后备值Fallback Valuesvar()的第二个参数var()函数实际上接受两个参数第一个参数要引用的自定义属性必填第二个参数可选的后备值fallback。当自定义属性尚未被声明或取值无效时后备值会生效。后备值本身还可以是另一个自定义属性而那个自定义属性还可以拥有它自己的后备值形成链式兜底。课程中的示例.fallback { --color-text: white; background-color: var(--undeclared-property, black); color: var(--undeclared-again, var(--color-text, yellow)); }解析结果background-color由于--undeclared-property未声明使用后备值blackcolor由于--undeclared-again未声明回退到嵌套的var(--color-text, yellow)而--color-text在.fallback作用域内已声明为white所以最终生效值为white假如--color-text也不存在或无效则继续落到最内层后备值yellow。这一机制让自定义属性在变量缺失时依然能保持稳健的降级表现是构建健壮样式系统的重要基础。自定义属性的作用域Scope在上面第一个示例中你可能已经注意到我们是在同一个声明块内完成自定义属性的声明与访问的。这是因为自定义属性的作用域由选择器决定。这个作用域包含该选择器自身以及它的所有后代descendants。如果你熟悉 JavaScript 中的作用域会发现两者的行为有几分相似——子作用域可以读取父作用域中定义的变量反之则不行。课程给出的对比示例div classcool-div p classcool-paragraphCheck out my cool, red background!/p /div p classboring-paragraphIm not in scope so Im not cool./p.cool-div { --main-bg: red; } .cool-paragraph { background-color: var(--main-bg); } .boring-paragraph { background-color: var(--main-bg); }运行结果只有cool-paragraph会获得红色背景因为它是声明了--main-bg的.cool-div的后代处于作用域之内而boring-paragraph是独立于.cool-div之外的兄弟元素不在作用域内其var(--main-bg)无法解析背景色保持默认。:root选择器把作用域扩展到全局虽然有时我们确实希望把变量限制在局部作用域内例如某个组件内部但更多时候我们希望一组变量能被互不相关的多个选择器共用。一个笨办法是在每个选择器上都重复声明同样的自定义属性——但这恰恰违背了使用自定义属性的初衷无法一处修改、处处生效。更好的解决方案是把变量声明在:root选择器上。:root本质上等价于html选择器区别在于:root的优先级specificity更高。p classcool-paragraphLorem ipsum dolor sit amet./p p classexciting-paragraphLorem ipsum dolor sit amet./p:root { --main-color: red; } .cool-paragraph { color: var(--main-color); } .exciting-paragraph { background-color: var(--main-color); }由于页面中任何其他选择器都是:root的后代所以在:root上声明的--main-color可以被文件中任意合法选择器访问。这也是现代 CSS 工程中设计令牌集中管理的标准做法。用自定义属性实现主题Themes除了提供全局访问能力之外:root还为主题化提供了一条清晰路径。课程用两个可交互的 CodePen 示例演示了两种主题方案。方案一类名驱动的主题切换Theme Toggle第一种思路在根元素上通过类名class切换主题作用域。由于 CodePen 的 HTML 面板无法直接操作根元素示例先在设置中给根元素加上默认的dark类然后在 CSS 中基于根元素的dark/light类分别建立两套自定义属性作用域:root.dark { --bg-color: #121212; --text-color: #f5f5f5; /* 其他深色主题变量 */ } :root.light { --bg-color: #ffffff; --text-color: #222222; /* 其他浅色主题变量 */ }页面中其他选择器一律只引用变量、不写死颜色body { background-color: var(--bg-color); color: var(--text-color); }这样当根元素的类在dark与light之间切换时整站的配色会同步跟随——因为所有颜色都来自同一组被重新定义的变量。这一模式非常适合配合 JavaScript 实现一键切换主题的交互按钮也是课程中第一个 CodePenTheme Toggle | CSS Custom Properties演示的核心机制。方案二prefers-color-scheme媒体查询跟随系统主题给用户手动切换主题的开关固然好但还有另一种你在不少网站或应用上见过的方案自动跟随用户操作系统或浏览器user agent的主题偏好。这可以通过prefers-color-scheme媒体查询实现——它允许我们根据用户的设备或设置屏幕尺寸、明暗主题偏好等应用不同样式。prefers-color-scheme会检查用户是否在操作系统或浏览器中选择了主题偏好。课程的第二个 CodePenTheme Query | CSS Custom Properties展示了完整写法其要点是两层结构先写默认主题在媒体查询之外于:root上声明一组默认的自定义属性。这保证在用户没有设置偏好、或浏览器不支持该媒体查询时页面仍有一套可用的主题示例中以浅色主题作为默认。再写跟随系统的主题在prefers-color-scheme: dark媒体查询内重新定义同名变量覆盖为深色值。:root { --bg-color: #ffffff; --text-color: #222222; } media (prefers-color-scheme: dark) { :root { --bg-color: #121212; --text-color: #f5f5f5; } } body { background-color: var(--bg-color); color: var(--text-color); }由于自定义属性的作用域覆盖后代媒体查询内对:root变量的重定义会自然渗透到body等所有引用处无需在每个选择器里重复写媒体查询。媒体查询的基础语法如media (max-width: 600px) { ... }在本课程的 媒体查询一课 中有系统讲解那里详细介绍了max-width/min-width/max-height/min-height等条件写法读者可先行或交叉阅读。使用prefers-color-scheme需要注意的三点课程特别提醒使用该媒体查询时有三个事实需要心中有数只有dark和light两个合法取值因此无法用它实现这两种基本主题之外的更多主题如强调色主题、高对比主题等light取值不仅代表用户明确选择了浅色还覆盖用户未设置任何偏好的情况——也就是说未设置偏好的用户默认命中的是light分支它不允许用户自行切换主题。对于希望使用与系统偏好相反主题的用户例如系统设为深色、但用户在某网站上想用浅色仅靠这一媒体查询是不够的通常需要配合方案一的类名切换并提供跟随系统 / 浅色 / 深色三态选择来兼顾两种需求。实战练习建议Assignment课程在本节末尾布置了以下动手任务以巩固自定义属性的理解观看关于 CSS 自定义属性的入门视频建立整体认知阅读 MDN 的Using CSS custom properties页面重点从Inheritance of custom properties自定义属性的继承一节开始——这一节与本文讲的作用域机制直接相关能帮助你更精确地理解变量的继承与覆盖规则观看 Kevin Powell 的Using CSS custom properties视频学习自定义属性的实用技巧与工程化用法打开 The Odin Project 网站用开发者工具inspector检查页面样式观察官网实际如何使用自定义属性组织样式——这是把理论与真实项目结合的最直观方式。建议在完成上述任务时动手把本站或自己项目的配色抽离到:root变量中再分别实现类名切换与prefers-color-scheme跟随系统两套主题体会两者各自的适用场景。知识检查Knowledge Check以下是本课的关键回顾问题用于自测掌握程度如何声明一个名为text-color的自定义属性使用双连字符与连字符命名法--text-color: value;注意区分大小写、不能含空格。如何访问一个名为background-color的自定义属性通过var()函数var(--background-color)括号内必须包含开头的双连字符。为了让自定义属性的作用域为全局、可被所有其他选择器访问应该在哪里声明在:root选择器上声明。:root等价于html且优先级更高页面中所有其他元素都是其后代因此都能访问。为了让用户的操作系统或浏览器主题设置生效被考虑进来应该在哪里声明自定义属性结合prefers-color-scheme媒体查询在:root上声明媒体查询外放默认值、查询内放系统主题覆盖值从而让主题自动跟随用户系统偏好。总结CSS 自定义属性是一套简单但威力强大的机制双连字符声明、var()读取、支持链式后备值、作用域由选择器决定、:root实现全局化。在此基础上你可以用根元素类名 变量重定义实现用户可控的主题切换也可以用prefers-color-scheme媒体查询让主题自动跟随操作系统甚至两者结合实现最完善的明暗主题体验。掌握这套知识后你的样式表将拥有更集中的可维护性、更一致的设计语言以及真正可扩展的主题能力——这正是从会写 CSS走向会设计 CSS 系统的关键一步。【免费下载链接】curriculumThe open curriculum for learning web development项目地址: https://gitcode.com/GitHub_Trending/cu/curriculum创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表