当前位置: 首页 > news >正文

【CSS】使用 CSS 自定义属性(变量)-- var()

自定义属性(有时候也被称作CSS 变量或者级联变量)是由 CSS 作者定义的,它包含的值可以在整个文档中重复使用。由自定义属性标记设定值(比如: --main-color: black;),由 var() 函数来获取值(比如: color: var(--main-color);)复杂的网站都会有大量的 CSS 代码,通常也会有许多重复的值。举个例子,同样一个颜色值可能在成千上百个地方被使用到,如果这个值发生了变化,需要全局搜索并且一个一个替换(很麻烦哎~)。自定义属性在某个地方存储一个值,然后在其他许多地方引用它。另一个好处是语义化的标识。比如,--main-text-color 会比 #00ff00 更易理解,尤其是这个颜色值在其他上下文中也被使用到。自定义属性受级联的约束,并从其父级继承其值。

基本用法

声明一个自定义属性,属性名需要以两个减号(--)开始,属性值则可以是任何有效的 CSS 值。和其他属性一样,自定义属性也是写在规则集之内的,如下:

element {--main-bg-color: brown;
}

注意,规则集所指定的选择器定义了自定义属性的可见作用域。通常的最佳实践是定义在根伪类 :root 下,这样就可以在 HTML 文档的任何地方访问到它了:

:root {--main-bg-color: brown;
}

然而这条规则不是绝对的,如果有理由去限制你的自定义属性,那么就应该限制。

**备注:**自定义属性名是大小写敏感的,--my-color--My-color 会被认为是两个不同的自定义属性。

如前所述,使用一个局部变量时用 var() 函数包裹以表示一个合法的属性值:

element {background-color: var(--main-bg-color);
}

使用自定义属性的第一步

我们从这个简单的 CSS 代码开始,它将相同的颜色应用在了不同 class 的元素上:

.one {color: white;background-color: brown;margin: 10px;width: 50px;height: 50px;display: inline-block;
}.two {color: white;background-color: black;margin: 10px;width: 150px;height: 70px;display: inline-block;
}
.three {color: white;background-color: brown;margin: 10px;width: 75px;
}
.four {color: white;background-color: brown;margin: 10px;width: 100px;
}.five {background-color: brown;
}

应用在如下 HTML 上:

<div><div class="one">1:</div><div class="two">2: Text <span class="five">5 - more text</span></div><input class="three" /><textarea class="four">4: Lorem Ipsum</textarea>
</div>

其呈现是:

在这里插入图片描述

注意到在 CSS 代码中的重复:背景色 brown 被多处设置。对于一些 CSS 声明,是可以在级联关系更高的位置设置,通过 CSS 继承自然地解决这个重复的问题。但在一般项目中,是不可能通过这样的方式去解决。通过在 :root 伪类上设置自定义属性,然后在整个文档需要的地方使用,可以减少这样的重复性:

:root {--main-bg-color: brown;
}.one {color: white;background-color: var(--main-bg-color);margin: 10px;width: 50px;height: 50px;display: inline-block;
}.two {color: white;background-color: black;margin: 10px;width: 150px;height: 70px;display: inline-block;
}
.three {color: white;background-color: var(--main-bg-color);margin: 10px;width: 75px;
}
.four {color: white;background-color: var(--main-bg-color);margin: 10px;width: 100px;
}.five {background-color: var(--main-bg-color);
}

这里呈现的结果和前面的例子是一致的,但允许对所需属性值进行一个规范的声明。

自定义属性的继承性

自定义属性会继承。这意味着如果在一个给定的元素上,没有为这个自定义属性设置值,在其父元素上的值会被使用。看这一段 HTML:

<div class="one"><div class="two"><div class="three"></div><div class="four"></div></div>
</div>

配套的 CSS:

.two {--test: 10px;
}.three {--test: 2em;
}

在这个情况下, var(--test) 的结果分别是:

  • 对于元素 class="two"10px
  • 对于元素 class="three"2em
  • 对于元素 class="four"10px (继承自父属性)
  • 对于元素 class="one"非法值,会变成自定义属性的默认值

注意,这些是自定义属性,并不是你在其他编程语言中遇到的实际的变量。这些值仅当需要的时候才会计算,而并不会按其他规则进行保存。比如,你不能为元素设置一个属性,然后让它从兄弟或旁支子孙规则上获取值。属性仅用于匹配当前选择器及其子孙,这和通常的 CSS 是一样的。

自定义属性备用值

var() 函数可以定义多个备用值(fallback value),当给定值未定义时将会用备用值替换。这对于 Custom Element 和 Shadow DOM 都很有用。

**备注:**备用值并不是用于实现浏览器兼容性的。如果浏览器不支持 CSS 自定义属性,备用值也没什么用。它仅对支持 CSS 自定义属性的浏览器提供了一个备份机制,该机制仅当给定值未定义或是无效值的时候生效。

函数的第一个参数是自定义属性的名称。如果提供了第二个参数,则表示备用值,当自定义属性值无效时生效。第二个参数可以嵌套,但是不能继续平铺展开下去了,例如:

.two {color: var(--my-var, red); /* Red if --my-var is not defined */
}.three {background-color: var(--my-var,var(--my-background, pink)); /* pink if --my-var and --my-background are not defined */
}.three {background-color: var(--my-var,--my-background,pink); /* Invalid: "--my-background, pink" */
}

第二个例子展示了如何处理一个以上的 fallback。该技术可能会导致性能问题,因为它花了更多的时间在处理这些变量上。

**备注:**像自定义属性这些 fallback 语法允许使用逗号。比如 var(--foo, red, blue) 定义了一个 red, blue 的备用值——从第一个逗号到最后的全部内容,都会被作为备用值的一部分。

有效性和值

传统的 CSS 概念里,有效性和属性是绑定的,这对自定义属性来说并不适用。当自定义属性值被解析,浏览器不知道它们什么时候会被使用,所以必须认为这些值都是有效的

不幸的是,即便这些值是有效的,但当通过 var() 函数调用时,它在特定上下文环境下也可能不会奏效。属性和自定义变量会导致无效的 CSS 语句,这引入了一个新的概念:计算时有效性

无效变量会导致什么?

当浏览器遇到无效的 var() 时,会使用继承值或初始值代替。

考虑如下代码:

HTML

<p>This paragraph is initial black.</p>

CSS

:root {--text-color: 16px;
}
p {color: blue;
}
p {color: var(--text-color);
}

毫不意外,浏览器将 --text-color 的值替换给了 var(--text-color),但是 16px 并不是 color 的合法属性值。代换之后,该属性不会产生任何作用。浏览器会执行如下两个步骤:

  1. 检查属性 color 是否为继承属性。是,但是 <p> 没有任何父元素定义了 color 属性。转到下一步。
  2. 将该值设置为它的默认初始值,比如 black。

结果

在这里插入图片描述

段落颜色并不是蓝色,因为无效代换导致了它被替换成了默认初始值的黑色。如果你直接写 color: 16px 的话,则会导致语法错误,而前面的定义则会生效(段落显示为蓝色)。

**备注:**当 CSS 属性 - 值对中存在语法错误,该行则会被忽略。然而如果自定义属性的值无效,它并不会被忽略,从而会导致该值被覆盖为默认值。

JavaScript 中的值

在 JavaScript 中获取或者修改 CSS 变量和操作普通 CSS 属性是一样的:

// 获取一个 Dom 节点上的 CSS 变量
element.style.getPropertyValue("--my-var");// 获取任意 Dom 节点上的 CSS 变量
getComputedStyle(element).getPropertyValue("--my-var");// 修改一个 Dom 节点上的 CSS 变量
element.style.setProperty("--my-var", jsVar + 4);
或者修改 CSS 变量和操作普通 CSS 属性是一样的:

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 基于python的汽车数据分析与可视化---附源码99290
  • 微信小程序详细登录流程
  • Jenkins 2.346.1完整搭建及项目部署安装
  • C语言家教记录(七)
  • 人工智能与机器学习在医学领域的应用
  • 结构型模式之外观模式
  • vue3状态管理库Pinia应用
  • C++入门基础知识28——关于【C++ 常量】
  • 论文阅读:MonoScene: Monocular 3D Semantic Scene Completion
  • Linux核心命令入门
  • 线性代数证明:把行列式的某一行(列)的k倍加到另一行(列),行列式的值不变
  • C++ TinyWebServer项目总结(7. Linux服务器程序规范)
  • ASIACRYPT 2021
  • Visual Studio VS 插件之 ReSharper
  • 网络基础-复习建议(包含红蓝对抗)
  • “大数据应用场景”之隔壁老王(连载四)
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • 【Linux系统编程】快速查找errno错误码信息
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • 【译】理解JavaScript:new 关键字
  • Android单元测试 - 几个重要问题
  • Angular 2 DI - IoC DI - 1
  • Angular 响应式表单之下拉框
  • C++类的相互关联
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • iOS | NSProxy
  • js算法-归并排序(merge_sort)
  • MYSQL 的 IF 函数
  • Node + FFmpeg 实现Canvas动画导出视频
  • PHP 7 修改了什么呢 -- 2
  • 程序员该如何有效的找工作?
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 猴子数据域名防封接口降低小说被封的风险
  • 基于Mobx的多页面小程序的全局共享状态管理实践
  • 解析带emoji和链接的聊天系统消息
  • 实习面试笔记
  • 最简单的无缝轮播
  • Java数据解析之JSON
  • raise 与 raise ... from 的区别
  • ​经​纬​恒​润​二​面​​三​七​互​娱​一​面​​元​象​二​面​
  • ​浅谈 Linux 中的 core dump 分析方法
  • # 学号 2017-2018-20172309 《程序设计与数据结构》实验三报告
  • #70结构体案例1(导师,学生,成绩)
  • #if #elif #endif
  • #if和#ifdef区别
  • (Python第六天)文件处理
  • (备份) esp32 GPIO
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (附源码)springboot 校园学生兼职系统 毕业设计 742122
  • (全注解开发)学习Spring-MVC的第三天
  • (三)Honghu Cloud云架构一定时调度平台
  • (三)uboot源码分析
  • (算法)Travel Information Center
  • (一)SvelteKit教程:hello world
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)