内容简介:CSS局部变量
CSS自定义属性也被称为CSS变量。这是非常令人兴奋的,因为我们在CSS中终于拥有真正的变量。什么意思,真正的变量?我的意思是可以动态更新和修改变量。虽然CSS处理器有了变量(Sass和PostCSS),这些变量通过编译变成了CSS,但没有动态能力更新其变量。这不是真正的CSS变量,只是用来存储和更新可用的值。
你可以通过 -- 设置CSS变量和通过 var(--varName) 访问已声明的变量。这是一个非常基本的方法,可以像下面声明一个变量和让文本的颜色为 red :
div {
--color: red;
color: var(--color);
}
CSS变量是非常令人兴奋的
让我们一起来聊聊,为什么动态的CSS为变量会比以前做得更好。
动态JavaScript+CSS
使用CSS变量,我们现在可以更容易地通过JavaScript更新它的值。这意味着,我们不需要使用内联属性样式或者更新类名。我们可以简单通过替换CSS变量的值。
可以像下面那样给 :root 传递值:
document.documentElement.style.setProperty('--varName', 'propValue')
这样直接在你的CSS文件中写入或更新 :root 的值。所以,如果我想更新一个加载条的进度比例时,可以这样做:
function calculateLoadProgress() {
let loadProgress = 0;
// codes to update loadProgress here
return loadProgress;
}
// Set width of progress bar
document.documentElement.style.setProperty('--progressBarWidth', calculateLoadProgress());
这是众多示例中的一个。 @David Khourshid 使用React做了一些非常有趣的探索和通过JS库确定值,然后传回给CSS变量。他在最近的 CSS Conf EU上做了相关的分享与讨论 。
动态属性片段
CSS变量有一个很酷的功能需要注意,那就是如何在属性值中指定CSS变量。虽然以前我们单独使用 border 来声明边框,现在我们可以使用变量更新属性的任何部分,包括缩写的 border 或者是不知道参数的阴影和渐变属性。
比如这个示例:
.button-gradient {
background: linear-gradient(var(--gradientAngle), var(--gradientStart),var(--gradientStop));
--gradientAngle: 60deg;
--gradientStart: lightpink;
--gradientStop: lightyellow;
}
.button-gradient:hover {
--gradientAngle: 0deg;
}
我们更新的是 --gradientAngle 而不是整个 background 属性。我们也可以使用JavaScript更新任何元素的这些值。是不是很不错。
干净的组件
CSS变量可以让我们写出更干净的组件,也可以更好的修改组件。下面一个是按钮的组件,让我们看看代码:
传统上,使用像BEM这样的来命名约定,我们将通过处理器,让修饰符(modifier)重写基类:
// Variables
$primaryColor: lightgreen;
$buttonBgColor: $primaryColor;
// Base Class
.button {
background: $buttonBgColor;
// other properties
}
// Modifier Class
.button--blue {
background: lightblue;
}
在上面的示例中,我们通过提高选择器权重,让后面的属性覆盖前面的属性,但文件体积增大了,我们的代码库也将会被弄乱。但使用CSS变量,我们不需要通过样式覆盖前面的样式,只需要更新CSS的变量。下面是使用CSS变量写的代码:
// Variables
:root {
--primaryColor: lightgreen;
--buttonBgColor: var(--primaryColor);
}
// Base Class
.button {
background: var(--buttonBgColor);
}
// Modifier Class
.button--blue {
--buttonBgColor: lightblue;
}
使用局部变量我们能做得更好
和上面类似,最新的 文档 、 教程 和 案例 中CSS变量都是在CSS文件中通过 :root 来声明变量和变量值。
用来设置全局变量这是一个很好的方式,但不是必需的。CSS变量不仅仅可以在 :root 中声明,它也可以在CSS文件中的任何时候声明,比如在一个CSS的代码块中指定变量。这类似于JavaScript中使用关键词 let 来声明变量,可以在 {} 中声明变量,这种方式声明的变量被称为局部变量。所以我们可以利用这种特性,更好的处理我们的组件样式。
Leveraging CSS Variable scope improves the size, specificity, & semantics of our stylesheets.
例如, --buttonBgColor 放在 :root 中作为一个全局变量,并不是我们所需要的东西(比如前面的示例)。较好的做法是在 <button> 内重命名变量 --bgColor 。这使它与它的父组件更紧密的耦合在一起,也更具有语义化。
CSS变量的使用规则: 除非你需要一个全局变量,否则尽量使用局部CSS变量 。然后在你自己需要地方使用。这样可以减少CSS变量在 :root 中的大量堆积,也使代码更加清晰。
在代码块 {} 中声明的变量,其作用域就像是JavaScript中使用 let 关键词声明的变量一样,都是属于 局部变量 。
组织和示例
在Sass中,我们可以使用 & 扩展和重写一个嵌套,也可以更清晰,更可视化的面向对象。在这里我们可以看一个完整的示例:
- 默认样式(指定属性)
- 默认值(基本变量)
- 差异化(更新变量)
代码如下:
.button {
// 1. Default Styles
background: var(--bgColor);
padding: var(--size);
line-height: var(--size);
border: var(--outline);
font-size: var(--size);
// 2. Default Values
--bgColor: lightgreen;
--outline: none;
--size: 1rem;
// 3. Variances
&--blue {
--bgColor: lightblue;
}
&--pink {
--bgColor: hotpink;
}
&--large {
--size: 1.5rem;
}
&--outlined {
--outline: 2px solid currentColor;
}
}
注:我们仍然可以使用 :root 声明全局变量,比如基本的颜色和字号重置样式,但局部变量减少权生,也从而减小大小和增加语义化。
默认值
另外一个有趣的就是可以在 :root 中声明一个默认值,以防他们不存在。 var() 有另外一个能力,可以接受两个参数,并且可以嵌套在变量中。在下面的示例中,如果没有声明 --bgColor ,那就Card就会调用 --colorPrimary 的值,也就是 red 。所以我们可以删除步骤2的中 .button 的基本样式和在修饰符中更新 --bgColor (如果我们想让默认按钮的颜色是主色)。
// 0. Set global variables here
:root {
--colorPrimary: red;
}
.button {
// 1. Default Styles
// If --bgColor is not defined, the background will be the fallback: red
background: var(--bgColor, var(--colorPrimary));
// 2. Default Values
// Since --bgColor is defined, the button remains lightgreen
// If the line below was missing, the button would be red
--bgColor: lightgreen;
// ...
}
主题换肤
如果我们有更复杂的组件,我们仍然可以使用这种技术,并且可以结合像Sass一样的CSS处理器使它更简洁。可以像下面这样的来写按钮,让Card的按钮比主题的基本按钮更大。
.button--large {
.card & {
--size: 1.7rem;
}
}
我们可以在任何地方更新 --size 的值,让Card的按钮变得略大一点。使用 & 技术编译出来的代码:
.card .button--large {
--size: 1.7rem;
}
所以我们的结构可以这样写:
<div class="card">
<button class="button button--pink button--large">
Large Pink Button
</button>
</div>
让具有红色边框的 .card 运用上面的代码。我们可以看到有一个更大的紫色按钮:
准备好了?
CSS变量得到了当今浏览器广泛的支持,尽管IE不支持,但Edge也得到了一定的支持。
如果你现在就要开始使用,有两个选择。
@supports
在CSS中,我们可以使用 @support 来检测浏览器是否支持。如果你想玩一些更现代的CSS属性,比如CSS Grid,那么 @support 是一个很好的工具。你可以像下面那样使用来检测你的浏览器是否支持CSS变量:
@supports(--color: red) {
// code here implementing variables
}
使用 @support 是一个很好的选择,但它也像CSS的变量一样还存在很多争议。所以说,提供一份备用的值,可能是一个更好的解决方案。
传递一份备用值
你可以复用CSS的宽松风格,给同一个属性发送多个值。首先像平时一样写属性值,然后第二写声明的变量:
div {
--color: red;
color: red;
color: var(--color);
}
这是多余的,但它允许你在一个现有的代码库中慢慢缓解使用一些CSS变量,一旦得到浏览器的支持,使其更容易重构。
CSS变量是超级强大的,并且局部变量使它们成为一个更加强大的工具,能让你模块更干净,更好的模块化设计系统。
扩展阅读
- Demo I Made Sending Using JS to Rewrite CSS Variables Inline
- Types of CSS Variables, CSS Tricks
- Using CSS Variables, MDN
- Why You Should Care About CSS Variables, Rob Dodson
- Theming With Custom Properties, Harry Roberts
- Time To Start Using CSS Custom Properties, Serg Hospodarets
- It’s Time To Start Using CSS Custom Properties
- CSS Custom Properties and Theming
- CSS custom properties (native variables) In-Depth
- CSS @apply rule (native CSS mixins)
- CSS Variables Are a Bad Idea
- The power of CSS variables
- Conditions for CSS Variables
- CSS Variables — No, really!
- How to Use CSS Variables for Animation
- Autoprefixing, with CSS variables!
- Individualizing CSS Properties with CSS Variables
- Making Custom Properties (CSS Variables) More Dynamic
本文根据 @Una 的《 Locally Scoped CSS Variables: What, How, and Why 》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处: https://una.im/local-css-vars 。
大漠
常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《 图解CSS3:核心技术与案例实战 》。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 全局变量,静态全局变量,局部变量,静态局部变量
- 03-Golang局部变量和全局变量
- Java并发 -- 局部变量
- golang方法返回局部变量指针
- c# – 线程安全和局部变量
- jquery-plugin中的全局变量或局部变量
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Algorithms + Data Structures = Programs
Niklaus Wirth / Prentice Hall / 1975-11-11 / GBP 84.95
It might seem completely dated with all its examples written in the now outmoded Pascal programming language (well, unless you are one of those Delphi zealot trying to resist to the Java/.NET dominanc......一起来看看 《Algorithms + Data Structures = Programs》 这本书的介绍吧!