内容简介: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中的全局变量或局部变量
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Ruby Programming Language
David Flanagan、Yukihiro Matsumoto / O'Reilly Media, Inc. / 2008 / USD 39.99
Ruby has gained some attention through the popular Ruby on Rails web development framework, but the language alone is worthy of more consideration -- a lot more. This book offers a definition explanat......一起来看看 《The Ruby Programming Language》 这本书的介绍吧!