在原生CSS中使用变量
本文首发于我的博客
一直以来,CSS作为一种申明式的样式标记语言,很难像如javascript等命令式编程语言一样通过定义和使用变量的方式来维护和追踪某些状态。后来随着scss,less等CSS预处理器的出现,我们可以像优秀的开源框架bootstrap那样,通过维护一个_variables.scss变量文件的方式来维护一个庞大的项目。但预处理需要编译,并非CSS原生支持。而现在,我们可以在原生CSS中使用变量了!
先来两个在线demo感受一下:
定义
CSS变量,也称为CSS自定义属性。通过以
--开头的自定义属性来设置变量名,存储一些特定值,在需要的地方使用var()来访问。如:
p {
--primary-color: #6bc30d;
color: var(--primary-color);
}
如何申明变量
可以像定义任何css属性一样来申明变量,不同的是,变量名必须以--开头。如 --primary-color: #6bc30d
如何使用变量
而要使用一个变量的值,需要使用 var() 函数,并将变量的名称作为参数传入。 如 color: var(--primary-color);
var()函数
var()函数可以代替元素中任何属性中的值的任何部分。
var() 函数接受两个参数,参数一是要替换的自定义属性的名称,参数二是可选的,作为参数一无效时候的回退值(如果第一个参数引用的自定义属性无效,则该函数将使用第二个值)。
var( <custom-property-name> [, <declaration-value> ]? )
/*<custom-property-name> 自定义属性名*/
/*<declaration-value> 声明值(回退值)*/
使用变量的意义
- 无需多次定义,同样的属性可以重复使用
- 让CSS文件可读易维护(如主题样式,只需修改一个变量即可,而不再是枯燥的查找替换),灵活性更高
注意点
- 变量名称必须以
--开头 - 变量只能存储一个属性的值,而不能用来存储一个属性,如下例子是错误的:
/*这样是错误的*/
p {
--primary-color: color;
var(--primary-color) : #6bc30d
}
- 变量中无法使用加减等数学方法,如果需要使用计算,则可以使用
calc函数:
/*这样是错误的*/
p {
--font-size : 20px * 2;
font-size: var(--font-size);
}
/*这样是正确的*/
p {
--font-size : calc(20px * 2);
font-size: var(--font-size); /*40px*/
}
/*这样拼接也是无效的*/
p {
--font-size: 20;
font-size: var(--font-size)px; /*无效*/
}
/*这样是有效的:*/
p {
--font-size: 20;
font-size: calc(var(--font-size) * 1px); /*20px*/
}
- CSS变量是区分大小写的
/*这是两个不同的变量*/
:root {
--color: blue;
--COLOR: red;
}
与scss等CSS预处理中变量的区别
- CSS变量是浏览器原生支持的,不需要经过编译就可以使用
- CSS变量是DOM的一部分,可以使用JS直接修改
作用域
虽然可以在css的任何地方定义变量,但是css变量也是有作用域的。CSS的变量作用域分为全局作用域和局部作用域。因此在申明一个变量之前,首先要确定这个变量要用在哪里?
全局变量
通过在:root中申明变量,就可以申明一个全局变量,可以在整个文档结构中使用这个变量,因为CSS变量是可继承的。
:root{
--primay-color: #6bc30d;
}
/* 在任何地方都可以使用`:root`中定义的全局变量 */
p, div , a {
color : var(--primay-color);
}
#myDiv, .myDiv {
color : var(--primay-color);
}
局部变量
可以在除:root外的任何地方申明局部变量。但是局部变量只能够在被申明的元素及其子元素中使用。局部变量更多的应用在值覆盖上。
.modal {
--modal-padding-top: 30px;
}
/*当前元素及其子元素中使用*/
.modal,
.modal-content {
padding-top: var(--modal-padding-top); /*30px*/;
}
/*在其他元素上无效*/
body {
padding-top: var(--modal-padding-top); /*无效设置,使用默认值*/
}
变量的继承
与其他CSS属性一样,CSS中的变量也是可以继承的。
:root{
--color: red;
}
P {
--pColor: green;
color: var(--color); /*red*/
}
p > span{
color : var(-pColor); /*green*/
}
多个申明中变量的优先级
同名变量可以重复申明,这样变量就会有了优先级的问题,如下例子:
:root {
--color: red;
}
div {
--color: green;
}
#myDiv {
--color: yellow;
--color: blue;
}
* {
color: var(--color);
}
<p>我正常显示红色</p>
<div>我显示绿色</div>
<div id="myDiv">
我显示蓝色
<p>那么我呢?</p>
</div>
如图,div中的局部变量覆盖了:root中设置的值,而特定ID的div元素#myDiv又覆盖了div中的值,最后作为#myDiv的子元素p继承了其父级的值,而不是使用root中申明的值
无效变量
对于变量来讲,CSS属性的有效性并不适用。对于变量这种自定义属性,即便在上下文环境中这个值是无意义的,但是都能够通过var()函数调用。无意义的变量值会导致无效的CSS申明。通过var()函数调用后会被解析为初始值。
:root {
--color: 20px;
}
p {
--font-size: green;
background-color: var(--color);
/* background-color: 20px; 无效,将回退为transparent */
}
在html属性中使用css变量
就像其他CSS属性一样,在html中可以通过内联变量来设置变量的值,并且也能够正常工作
<style>
p {
color: var(--color);
}
</style>
<body>
<p style="--color:red; --font-size: 50px; font-size:var(--font-size);">
我使用内联变量值得方式来设置样式
<!-- 将显示为字号50px,颜色红色 -->
</p>
</body>
在媒体查询中使用css变量
可以根据屏幕宽度的变化来改变变量的值,从而更容易的实现响应式布局。
:root {
--font-size: 30px;
--color: red;
}
html{
color: var(--color);
font-size: var(--font-size);
}
@media screen and (min-width: 480px) {
:root {
--font-size: 50px;
--color: green;
}
}
@media screen and (min-width: 760px) {
:root {
--font-size: 100px;
--color: blue;
}
}
在js中使用css变量
css变量是DOM的一部分,这意味着我们可以通过javascript来访问/修改css变量的值,这是scss等css预处理器所做不到的。
要用JavaScript来更新CSS变量,需要调用已声明变量元素上的style对象上的 setProperty 方法。
setProperty()
//语法
element.style.setProperty(propertyName, value, priority);
//propertyName 是一个 DOMString 被更改的CSS属性.
//value <可选> 是一个 DOMString 新的属性值. 如果没有指定, 则当作空字符.不能包含 "!important"
//priority <可选> 是一个 DOMString。允许 "important" CSS 优先被设置. 如果没有指定, 则当作空字符.
//在根元素(html)上更新变量值
document.documentElement.style.setProperty(propertyName, value)
示例
:root {
--font-size: 20px;
--background: red;
}
body {
font-size: var(--font-size);
background-color: var(--background);
color: #fff;
}
<h1>使用JavaScript来改变背景色</h1>
<button data-value="red">红色</button>
<button data-value="green">绿色</button>
<button data-value="blue">蓝色</button>
<button data-value="yellow">黄色</button>
<script>
let $buttons = document.querySelectorAll('button')
$buttons.forEach(button => {
button.addEventListener('click', () => {
let value = button.dataset.value
document.documentElement.style.setProperty('--background', value)
})
})
</script>
参考文档
- Using CSS custom properties (variables)
- CSS Variables overview
- Everything you need to know about CSS Variables
本文首发于我的博客
在原生CSS中使用变量的更多相关文章
- 原生css 中变量的使用
前两天看到阮大神的一篇在css中使用变量的文章,整理了一下. 这个重要的 CSS 新功能,所有主要浏览器已经都支持了.本文全面介绍如何使用它,你会发现原生 CSS 从此变得异常强大. 一.变量的声明 ...
- 如何在CSS中使用变量
前言 CSS变量(官方称为自定义属性)是用户定义的值,它可以在你的代码库中设置一次并多次使用.它们使管理颜色.字体.大小和动画值变得更加容易,并确保整个web应用的一致性. 举个例子,你可以将品牌颜色 ...
- css中定义变量
css中定义变量 定义变量可分多种情况: 1.定义全局变量 :root { --borderColor: #ccc;} 2.定义某元素下的变量 .look{ --borderColor: #ccc;} ...
- css中使用变量
2017年3月,微软宣布 Edge 浏览器将支持 CSS 变量.这个重要的 CSS 新功能,所有主要浏览器已经都支持了. 声明css变量的时候,变量名前面要加两根连词线(--).变量名大小写敏感,-- ...
- CSS中的变量使用,var()语法
参考博客:https://blog.csdn.net/qq_34206361/article/details/53690414
- 关于原生js中函数的三种角色和jQuery源码解析
原生js中的函数有三种角色: 分两大种: 1.函数(最主要的角色)2.普通对象(辅助角色):函数也可以像对象一样设置属于本身的私有属性和方法,这些东西和实例或者私有变量没有关系两种角色直接没有必然的关 ...
- 原生 CSS 网格布局学习笔记
下是来自Oliver Williams的帖子. Oliver已经学习了相当长时间的原生CSS网格,可以说是在CSS网格方面有一定的发言权.在这篇文章中,他将以非同寻常的思路分析自己的CSS网格布局学习 ...
- 使用CSS中的meta实现web定时刷新或跳转的方法
这篇文章主要介绍了使用CSS中的meta实现web定时刷新或跳转的方法,比使用JavaScript脚本实现起来更加简单一些,需要的朋友可以参考下 meta源信息功能之页面定时跳转与刷新 几乎所有的网页 ...
- 1:CSS中一些@规则的用法小结 2: @media用法详解
第一篇文章:@用法小结 第二篇文章:@media用法 第一篇文章:@用法小结 这篇文章主要介绍了CSS中一些@规则的用法小结,是CSS入门学习中的基础知识,需要的朋友可以参考下 at-rule ...
随机推荐
- idea教程--Maven 骨架介绍
简单的说,Archetype是Maven工程的模板工具包.一个Archetype定义了要做的相同类型事情的初始样式或模型.这个名称给我们提供来了一个一致的生成Maven工程的方式.Archetype会 ...
- Excel:如何为某一列写相同的数而不是累加的数
按住CTRL,双击单元格右下角的加号,则该行以下的行都是这个单元格的值 不按CTRL,双击单元格右下角的加号,该行以下的行都是每次加一的数
- MyBatis 使用(XML版本)
一.MyBatis相关概念 对象 / 关系数据库映射(ORM) ORM全称Object/Relation Mapping:表示对象-关系映射的缩写 ORM完成⾯向对象的编程语⾔到关系数据库的映射.当O ...
- JZ-017-树的子结构
树的子结构 题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 题目链接: 树的子结构 代码 /** * 标题:树的子结构 * 题目描述 * 输入两棵 ...
- springCould注解和配置以及pom依赖
SpringCloud注解和配置以及pom依赖说明 在本文中说明了pom依赖可以支持什么功能,以及支持什么注解,引入该依赖可以在application.properties中添加什么配置. 1.Spr ...
- ARP攻击的发现、攻击原理、攻击方式、防护,竟然这么简单?!
ARP协议概述 ARP协议(address resolution protocol)地址解析协议. 一台主机和另一台主机通信,要知道目标的IP地址,但是在局域网中传输数据的网卡却不能直接识别IP地址, ...
- Thinkphp3.2数据库字段自动转小写,字段大小写自动转换,以及thinkphp3一些bug
公司在使用thinkphp框架,版本也有些老,被一些bug坑了,记录一下 自动转小写解决办法,最简单的就是在配置文件加上 'DB_PARAMS' => [\PDO::ATTR_CASE => ...
- ubuntu 16.04和18.04 忘记登录密码的解决办法
1:开机按Shift键,出现如下界面.(手速要快,Shift键要按时间久一点)选择第二项 2:按回车键进入如下界面,然后选中有recovery mode的选项(第三项) 3:按e进入如下界面,并找到图 ...
- idea创建web项目以及配置Tomcat
废话不多说,直接上干活: 1.在project中现创建好module,也就是java web项目 2.把路径名写清楚就行了 3.创建在WEB-INF上右击创建classes和lib以存储class编译 ...
- leedcode算法分类