转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。


Sass和Less这样的预处理器,让我们的CSS代码保持良好的结构和可维护性。像变量、混合(mixins)、循环控制等特性,增强了动态编写CSS的能力,从而减少重复代码,也加快了我们开发速度。

近年来,一些动态特性开始作为规范的一部分,出现在CSS语言中。CSS变量(CSS variables),或者用它的官方称谓,叫作自定义属性(custom properties),已经可用,并且有非常棒的浏览器支持,而CSS mixins也正在取得进展。

在本文,你将学会如何使用CSS变量,并把它集成到你的CSS开发流程中,让你的样式表更好维护,且减少重复。

让我们现在就开始吧!

什么是CSS变量?

如果你曾使用过某种编程语言,那么你已经很熟悉变量这个概念了。变量用于存储和更新你的程序所需要的值,以便使它运行。

例如,考虑下面的JavaScript代码

    let number1 = 2;let number2 = 3;let total = number1 + number2;console.log(total); // 5number1 = 4;               total = number1 + number2;console.log(total); // 7

nubmer1和 number2是两个变量,分别存储着数字2和3。

total同样是变量,存储着number1与number2之和。在这里它的值就是5。你可以动态地修改变量里的值,并在程序中使用它们。在上面的代码中,我把number1的值更新为4,然后再进行求和。使用相同的变量,这个时候total里存储的值就是5,而不再是7了。

使用变量的妙处在于,它可以让你在一个地方存储值,并且让你在后面能以各种理由去更新它。在程序中,你不需要为不同的值再添加额外的字符表示:任何值的更新都发生在同一个地方。正如,在你定义的变量上。

CSS在很大程度上是一种声明式的语言,而缺少动态能力。你也许会认为,让CSS拥有变量,几乎让上面的说法自相矛盾。如果前端开发仅仅是关于文字游戏,那可以这么说。幸运的是,Web的编程语言很像生活中的语言,它们会随着周围环境和实践需要而不断进化与适应。CSS也同样如此。

简单的说,变量已经成为CSS世界中激动人心的事实,并且你即将亲自看到,对于这个厉害的新技术,学习和使用起来都非常直观。

使用CSS变量有什么好处?

使用CSS变量的好处,跟在其他编程语言中使用变量的好处没什么大的区别。

W3C 规范是这样描述这一点的

使用CSS变量,给看似随机的值加上富有信息的名字,从而使得大文件更容易阅读和编辑,更少出错。因为,你只需要在自定义属性中改变一次值,所有应用了这个变量的地方都会自动跟着一起改变。

换句话说,通过给变量起一个对你来说在项目中有意义的名字,你能更容易的管理和维护你的代码。例如,当你为项目中的主色调设置一个变量名--primary-color,那么你后面再修改这个主色调时,只需要改动一处,而不需要在不同位置的多个CSS文件中去手动修改多次值。

CSS变量和预处理器中的变量有什么不同?

你可能已经在CSS预处理器中尝试过使用变量而带来的好处了,比如Sass和Less。

预处理器让你能设置变量,以及在函数、循环、数学计算等等地方中使用它们。这是否意味着CSS变量已经无关紧要了呢?

那可未必,主要是因为,CSS变量与预处理器中的变量其实是不同的东西。

这些不同基于一个事实:CSS变量是浏览器中直接可用的CSS属性,而预处理中的变量是用于编译成常规的CSS代码,浏览器其实对它们一无所知。

这意味着,你可以在样式表中,在内联样式中,在SVG的标签中直接更新CSS变量,甚至可以在运行时用JavaScript直接修改它。而你是无法对预处理器中的变量做上面这些操作的。CSS变量开启了一个充满可能性的新世界大门。

不是说你必须要在两者间做出选择:没有什么东西限制你,你可以同时使用CSS变量和预处理变量,并享有它们各自带来的巨大好处。

CSS变量:语法

虽然本文为了简洁,我使用了CSS变量(CSS variables)这个称呼,但官方的规范把它们称作作为级联变量的CSS自定义属性(CSS custom properties for cascading variables)。CSS自定义属性(CSS custom property)的部分看起来像这样:

    --my-cool-background: #73a4f4;

在自定义属性前添加双横线前缀,然后像给普通CSS设值一样,给自定义属性设值。在上面的代码中,我给一个叫做--my-cool-backgroud的自定义属性设置了一个颜色值。

级联变量(cascading variable) 的部分,由通过val()来使用你的自定义属性组成,开起来像这样:

var(--my-cool-background);

自定义属性作用于CSS选择器中,val()可被当成一个真正的CSS属性一样使用。

    :root {--my-cool-background: #73a4f4;}/* CSS文件的其他部分 */#foo {background-color: var(--my-cool-background);}

上面的代码片段把--my-cool-background这个自定义属性的作用域定义在:root这个伪类中,这让该自定义属性能被全局访问到(即在<html>标签内部的任何地方)。然后,使用val()函数把ID为foo的容器的background-color设置为自定义属性的值,这时该容器就有了浅蓝的背景色。

这还没完。你可以用同样的浅蓝色,给多个HTML标签的多种可以设置颜色值的地方设值,比如设置它们的color和border-color。方法很简单,就是通过var(--my-cool-background)拿到自定义属性的值,然后给合适的CSS属性设置上去。(当然,在事情变得复杂之前,我建议思考一下你的CSS变量命名规范):

    p {color: var(--my-cool-background);}

示例1代码,可点击查看。

你还可以从通过利用CSS变量获得另一个CSS变量的值。例如:

    --top-color: orange;--bottom-color: yellow;--my-gradient: linear-gradient(var(--top-color), var(--bottom-color));

上面的代码创建了一个--my-gradient变量,是一个渐变样式,它的值被设为--top-color的值和--bottom-color的值组合的结果。现在,你可以在任何时候修改你的渐变样式,仅仅是修改变量的值就可以了,而不再需要在样式表里满文件地去找用到这个渐变样式地方。

示例2代码。

最后,你可以在CSS变量中加入一个或多个备用值(fallback value/s),例如:

    var(--main-color, #333);   

上面的代码中,#333是一个备用值。当自定义属性值无效或未指定(unset)时,如果这时也没有指定备用值,那么被继承的(inherited)属性值将会被使用。

CSS变量是区分大小写的

与普通CSS属性不同,CSS变量是区分大小写的。

例如,var(--foo)和var(--FOO)是在求两个不同的自定义属性值,分别是--foo和--FOO的。

CSS变量受级联关系影响

和普通CSS属性一样,CSS变量是可继承的。例如,我们定义了一个属性,值为blue:  

    :root {--main-color: blue;}

当你给任意在<html>标签里的元素指定--main-color变量时,它们都会继承到blue这个值。

当你在另一个元素里,为改自定义属性设置了一个新值时,那么所有该元素的子元素都会继承那个新值。例如:  

    :root {--main-color: blue;}.alert {--main-color: red;}p {color: var(--main-color);}<--! HTML --><html><head><!-- head code here --></head><body><div><p>blue 的段落</p><div class="alert"><p>red 的段落</p></div></div></body></html>

在上面的标签中,第一个p段落会继承到全局的--main-color值,它是蓝色。

在div标签中拥有.alert类的段落会是红色,因为它的值继承自局部作用域里的--main-color。

示例3代码

知道目前这些规则差不多够了。让我们开始写代码吧!

如何在SVG中使用CSS变量

CSS变量和SVG配合得很好。你可以使用CSS变量去修改SVG中的样式,以及和呈现相关的属性。

举个例子,假设你想让你的SVG图标能跟随其所在父容器而拥有不同的颜色。你可以把CSS变量的作用域限定在父容器中,然后给变量设置想要的颜色,那么里面的图标就会继承父容器的颜色值。下面是相关代码:

    /* inline SVG symbol for the icon */<svg><symbol id="close-icon" viewbox="0 0 200 200"><circle cx="96" cy="96" r="88" fill="none" stroke="var(--icon-color)" stroke-width="15" /><text x="100" y="160" fill="var(--icon-color)" text-anchor="middle" style="font-size:250px;">x</text></symbol></svg>/* first instance of the icon */<svg><use xlink:href="#close-icon" /></svg>

上面的代码使用了<symbol>标签,它让你创建一SVG图形的不可见的版本。然后再使用<use>标签生成一个可见的副本。这种方法可以让你根据自己的喜好创建任意多个自定义的图标,也就是通过它的ID(#close-icon)指向那个<symbol>。这比一遍又一遍地写重复的代码创建图形更加简便。如果你想提高这方便的技术,Massimo Cassandro在他的Build Your Own SVG Icons中提供了一个快速教程。

注意到SVG symbol中,circle元素里的stroke属性和text元素里的fill属性:它们都使用了CSS变量,这里是--icon-color。它被定义在:rootCSS文件的选择器中,像这样:  

    :root {--icon-color: black;}

这是当前图标看起来的样子:

这时,如果你把同样的SVG图标放在不同的父容器中,并且在父容器上,给你的CSS变量设置各自的局部值,那么你就会得到不同颜色的图标,并且不用给你的样式表添加多余的规则。这很酷!

为了展示这一点,我们把同样的图标放在一个有.success类的div里:

    <!-- html --><div class="success"><svg><use xlink:href="#close-icon" /></svg></div>

现在,让--icon-color变量局部化,即把它放在.success中,并设置一个green值。我们来看看发生的变化:

    /* css */.success {--icon-color: green;}

这个图标的颜色就变成了绿色:  

  

来看看一个完整的示例吧: 示例4代码。

如何在@keyframes中使用CSS变量

CSS变量可以在CSS动画中使用,即可用于常规HTML元素,也可以用于内联的SVG。只需要记得,你得知道让什么元素动,把它视为目标元素,然后创建对该目标元素的选择器,在选择器的作用范围中定义你的CSS变量,然后,使用val()获取这些变量,把它们设置到@keyframes代码块中。

例如,让SVG中.bubble类里面的<ellipse>元素动起来,你的CSS可能会看起来像这样:

    .bubble {--direction-y: 30px;--transparency: 0;animation: bubbling 3s forwards infinite;}@keyframes bubbling {0% {transform: translatey(var(--direction-y));opacity: var(--transparency);}40% {opacity: calc(var(--transparency) + 0.2);}70% {opacity: calc(var(--transparency) + 0.1);}100% {opacity: var(--transparency);}}

注意到这是如何借助CSS的calc(),并用var()函数进行计算的。它们增强了你代码的灵活性。

这个例子简洁的地方在于,利用CSS属性,你可以简单的修改相应选择器里变量值而调整动画,而不需要挨个去查找@keyframes里的属性了。

这里有个完整的例子供你体验:示例5代码。  

如何通过JavaScript操作CSS变量

另一个超级酷的事情就是,你可以直接通过JavaScript代码访问CSS变量。

假设在你的CSS文件中,有一个叫做--left-pos的变量,作用在.sidebar选择器中,值为100px:

    .sidebar {--left-pos: 100px;}

那么,通过JavaScript获取--left-pos值,会像下面这样:

    // 缓存你即将操纵的元素const sidebarElement = document.querySelector('.sidebar');// 缓存sidebarElement的样式于cssStyles中const cssStyles = getComputedStyle(sidebarElement);// 获取 --left-pos CSS变量的值const cssVal = String(cssStyles.getPropertyValue('--left-pos')).trim();// 将CSS 变量的值打印到控制台: 100pxconsole.log(cssVal);

如果想通过JavaScript设置CSS变量的值,你可以像这样:

    sidebarElement.style.setProperty('--left-pos', '200px');

上面的代码将sidebar元素中--left-pos变量的值设置为200px。

请看看CodePen中的如下示例,你可以交互式地点击侧边栏,修改blend mode属性和背景色。这些实现只用到了CSS变量和JavaScript。

示例6代码。

CSS变量的浏览器支持

除了IE11(它不支持CSS变量),所有主流浏览器都对CSS变量有全面地支持。

对于不支持CSS变量的浏览器,一个变通的方案是使用具有虚拟查询条件(dummy conditional query)的@supports代码块:

    section {color: gray;}@supports(--css: variables) {section {--my-color: blue;color: var(--my-color, 'blue');}}

考虑到@supports在IE/Edge里也起作用,上面的方法是可行的。如果你在val()函数中使用了备用值,那么你的代码将更加可靠,它能在兼容性不好的浏览器中实现优雅降级。

对于上面的代码,在Chrome和其他支持CSS变量的浏览器中,<section>标签里的文本将是蓝色:

在IE11中,由于它不支持CSS变量,页面将显示灰色文本:

  

可以查看在线的示例7代码。

此方法的一个缺点是,如果你大量使用CSS变量,而那些不支持CSS变量的浏览器在你的项目中有很高的适配优先级,那么相应的代码会变得很复杂,对于维护来说,甚至是噩梦。

在这种情况下,你可以选择使用带有cssnext的PostCSS,它能让你在CSS代码中使用最新的特性,并且让原本不支持这些属性的浏览器,也能运行这些代码(有点像JavaScript转换器做的事情)。

备注:这里可下载本文所有示列代码。


本文是由葡萄城技术开发团队发布,转载请注明出处:葡萄城官网

本中提到的CSS变量已经在SpreadJSWijmo中得到应用,

  1. 了解可嵌入您系统的在线 Excel,请前往 SpreadJS
  2. 了解全面支持Angular、React和Vue的前端开发工具,请前往 WijmoJS

CSS变量(自定义属性)实践指南相关推荐

  1. 使用css 中自定义属性(变量)

    自定义属性(有时候也被称作CSS 变量或者级联变量)是由 CSS 作者定义的,它包含的值可以在整个文档中重复使用. 由自定义属性标记设定值(比如: --main-color: black;),由 va ...

  2. 【css】前端换肤功能方案调研 css变量换肤实践

    场景:应用要做深浅两套主题,内嵌h5页面要根据用户当前选择的主题渲染对应的主题样式. 技术栈:vue-cli3 + less + Vant 接到需求后,上网调研了几种方案:切换className.切换 ...

  3. react css多个变量_如何使用CSS变量和React上下文创建主题引擎

    react css多个变量 CSS variables are really cool. You can use them for a lot of things, like applying the ...

  4. 现货!《PHP7实践指南:o2o网站与App后台开发》京东天猫有售

    终于发售了,啥也不想说了,喜欢的或需要的就点击 链接 进去购买吧. 另外此书将作为 2017 PHP全球开发者大会 现场活动用书 天猫购书 包邮 PHP7实践指南:O2O网站与App后台开发 数据库设 ...

  5. 前端 CSS 变量简介及基本使用方法

    背景 复杂的网站都会有大量的CSS代码,通常也会有许多重复的值. 举个例子,同样一个颜色值可能在成千上百个地方被使用到,如果这个值发生了变化,需要全局搜索并且一个一个替换,效率不高且容易出错. 自定义 ...

  6. 妙用CSS变量,让你的CSS变得更心动

    作者:JowayYoung 仓库:Github.CodePen 博客:掘金.思否.知乎.简书.头条.CSDN 公众号:IQ前端 联系我:关注公众号后有我的微信哟 特别声明:原创不易,未经授权不得对此文 ...

  7. 标梵互动教你巧妙使用CSS变量使您的CSS更有吸引力

    标梵互动教你巧妙使用CSS变量使您的CSS更有吸引力 2020-11-19 私有 「CSS变量」又叫「CSS自定义属性」,为什么会突然提起这个很少人用到的东西呢?因为最近在重构个人官网,不知道为什么突 ...

  8. 入门学习Nginx代理服务器?就看这篇Nginx进阶学习最佳配置实践指南

    前置基础知识学习 1.Nginx基础安装与配置详细 https://blog.weiyigeek.top/2019/9-1-121.html 2.Nginx进阶学习之最佳配置实践指南 https:// ...

  9. 前端 DSL 实践指南(上)—— 内部 DSL

    编者按:本文转载自云音乐前端技术团队,作者网易云音乐前端工程师郑海波 前言 近几年,前端社区中 DSL 这个词开始频繁出镜,这和环境的变化有很大关系: React.Vue.Angular 等现代框架的 ...

  10. 《响应式Web设计:HTML5和CSS3实践指南》——2.9节基于位置伪类的交替行样式

    本节书摘来自华章社区<响应式Web设计:HTML5和CSS3实践指南>一书中的第2章,第2.9节基于位置伪类的交替行样式,作者(美) Benjamin LaGrone,更多章节内容可以访问 ...

最新文章

  1. Task04:青少年软件编程(Python)等级考试模拟卷(一级)
  2. Const *ptr ptr
  3. Spring @Scheduled关键字
  4. 005_FreeMarker入门程序
  5. 盘点2020国内本科开设人工智能专业高校
  6. javascript动态创建表格:新增、删除行和列
  7. 【转载】solr教程,值得刚接触搜索开发人员一看
  8. SQL on and 和 on where 的区别
  9. jquery实现截取pc图片_如何优雅的对网页截取长图
  10. Mac OS使用技巧之十二:解决APP Store更新、下载出错的问题
  11. Android studio IllegalArgumentException: couldn't make a guess
  12. 如何使用终端下载 macOS Monterey 12.1 正式版
  13. unity3d ppsspp模拟器中的post processing shader在unity中使用
  14. 华为笔试题2019年3月
  15. 阿里云 python_阿里云python sdk
  16. 相遇在这茫茫的网海里。你在天涯,我在海角
  17. 形容词记忆(二):ful,ous,ant后缀常用词
  18. 〔首届CSDN.南京区程序员聚会〕正式报名情况[每日更新7月19日 17:30]
  19. Python 实现文本共现网络分析
  20. layui 数据表格 点击分页按钮 监听事件

热门文章

  1. Mysql:日志管理:二进制事务日志
  2. 在面向服务的设计时有四个原则:
  3. 基于端到端深度强化学习的柔性作业车间调度问题研究
  4. AOJ-754 数根
  5. 智能优化算法:被囊群算法-附代码
  6. 不让登陆_梦幻西游:不让刷活动就直说,到下午3点的时候五开准时掉线
  7. Flutter之Align和AlignmentGeometry
  8. python列表查找整数,在数组/整数列表中查找重复项
  9. python发送邮件程序
  10. html能在hade中注释吗,A第1章 HTML超文本标记语言(1-20)OK.doc