第2章-第5节 自定义属性(即CSS变量)

4 篇文章 0 订阅

1 起源

2015年,一个期盼已久的CSS规范作为候选推荐标准问世了,叫作层叠变量的自定义属性(Custom Properties for Cascading Variables)
。这个规范给CSS引进了变量的概念,开启了一种全新的基于上下文的动态样式。你可以声明一个变量,为它赋一个值,然后在样式表的其他地方引用这个值,,除了IE,自定义属性已经得到各大主流浏览器的支持。

2 使用

要定义一个自定义属性,只需要像其他CSS属性那样声明即可,如代码清单2-23所示。创建一个新的网页和样式表,将代码清单2-23添加到样式表中。
代码清单2-23 定义一个自定义属性

:root {
  --main-font: Helvetica, Arial, sans-serif;
}

这个代码清单定义了一个名叫–main-font的变量。将其值设置为一些常见的sans-serif字体。变量名前面必须有两个连字符(–),用来跟CSS属性区分,剩下的部分可以随意命名。
变量必须在一个声明块内声明。这里使用了:root选择器,因此该变量可以在整个网页使用,稍后会解释这一点。

变量声明本身什么也没做,我们使用时才能看到效果。将这个变量用到一个段落上,就会产生如图2-13所示的结果。
在这里插入图片描述
图2-13 该段落使用了变量里定义的sans-serif字体
调用函数var()就能使用该变量。利用该函数引用前面定义的变量–main-font。将代码清单2-24里的规则集添加到你的样式表中。
代码清单2-24 使用自定义属性

:root {
  --main-font: Helvetica, Arial, sans-serif;
  p {                (以下3行)将段落的字体设置为Helvetica、Arial、sans-serif
  font-family: var(--main-font);   
} 
}

在样式表某处为自定义属性定义一个值,作为“单一数据源”,然后在其他地方复用它。这种方式特别适合反复出现的值,比如颜色值。代码清单2-25添加了一个叫brand-color的自定义属性。在样式表中可以多次使用这个变量,当你想要改变这个颜色值时,只需要在一个地方修改即可。
代码清单2-25 使用自定义属性定义颜色

:root {
  --main-font: Helvetica, Arial, sans-serif;     
  --brand-color: #369;                        ←---- 定义一个蓝色的brand-color变量
}

p {
  font-family: var(--main-font);
  color: var(--brand-color);
}

var()函数接受第二个参数,它指定了备用值。如果第一个参数指定的变量未定义,那么就会使用第二个值。
代码清单2-26在两个不同的声明中都指定了备用值。在第一个声明里,因为–main-font被定义为Helvetica, Arial, sans-serif,所以使用了这个变量的值。在第二个声明里,因为–secondary-color是一个未定义的变量,所以使用了备用值blue。
代码清单2-26 提供备用值

:root {
  --main-font: Helvetica, Arial, sans-serif;
  --brand-color: #369;
}

p {                                              
  font-family: var(--main-font, sans-serif);  ←---- 指定备用值为sans-serif       
  color: var(--secondary-color, blue);        ←---- secondary-color变量没有定义,因此会使用备用值blue
}

说明 如果var()函数算出来的是一个非法值,对应的属性就会设置为其初始值。比如,如果在padding:
var(–brand-color)中的变量算出来是一个颜色,它就是一个非法的内边距值。这种情况下,内边距会设置为0。

3 动态改变自定义属性

在前面的示例中,自定义属性只不过为减少重复代码提供了一种便捷方式,但是它真正的意义在于,自定义属性的声明能够层叠和继承:可以在多个选择器中定义相同的变量,这个变量在网页的不同地方有不同的值。

例如,可以定义一个变量为黑色,然后在某个容器中重新将其定义为白色。那么基于该变量的任何样式,在容器外部会动态解析为黑色,在容器内部会动态解析为白色。接下来用这种特性来实现如图
2-14所示的效果。s
图2-14 自定义属性基于当前变量值,产生了两种不同颜色的面板

这个面板跟之前的面板(如图2-7所示)类似。它的HTML标记如代码清单2-27所示。代码里的面板有两个实例:一个面板在body里,还有一个面板在深色的区域中。按照代码清单2-27更新HTML。
代码清单2-27 同一个网页中,不同环境下的两个面板

<body>
  <div class="panel">         ←-- 网页中的一个普通面板
    <h2>Single-origin</h2>
    <div class="body">
      We have built partnerships with small farms
      around the world to hand-select beans at the
      peak of season. We then careful roast in
      small batches to maximize their potential.
    </div>
  </div>

  <aside class="dark">    (以下2行)深色容器内的另一个面板
    <div class="panel">   
      <h2>Single-origin</h2>
      <div class="body">
        We have built partnerships with small farms
        around the world to hand-select beans at the
        peak of season. We then careful roast in
        small batches to maximize their potential.
      </div>
    </div>
  </aside>
</body>

接下来,用变量定义文字和背景颜色,进而重新定义这个面板。将代码清单2-28加入你的样式表。这会将背景色设置为白色,将文字设置为黑色。在实现深色面板之前,我先解释一下它的工作原理。
代码清单2-28 使用变量定义面板颜色

:root {
  --main-bg: #fff;      (以下2行)分别将背景色和文字颜色变量定义为白色和黑色
  --main-color: #000;   
}

.panel {
  font-size: 1rem;
  padding: 1em;
  border: 1px solid #999;
  border-radius: 0.5em;
  background-color: var(--main-bg);    (以下2行)在面板样式中使用变量
  color: var(--main-color);             
}

.panel > h2 {
  margin-top: 0;
  font-size: 0.8em;
  font-weight: bold;
  text-transform: uppercase;
}

首先还是在:root选择器的规则集中定义变量。这很重要,如此一来这些值就可以提供给根元素(整个网页)下的任何元素。当根元素的后代元素使用这个变量时,就会解析这里的值。

我们有两个面板,它们看起来一样。接下来在另一个选择器中重新定义这两个变量。代码清单2-29定义了深色容器的样式,为该容器设置了深灰色背景,还有一些内边距和外边距,同时也重新定义了两个变量。将代码清单2-29添加到样式表中。
代码清单2-29 深色容器的样式

.dark {
  margin-top: 2em;   ←---- 给深色容器和前面的面板之间加上外边距
  padding: 1em;         

  background-color: #999;    ←---- 给深色容器加上深灰色背景
  --main-bg: #333;      (以下2行)在容器内重定义--main-bg和--main-color变量
  --main-color: #fff;    
}

重新加载网页,会看到第二个面板有深色背景和白色文字。这是因为面板使用了这些变量,它们会解析成深色容器内定义的值,而不是根元素内定义的值。注意,这里并没有重新定义面板样式,或者给面板加上额外的类。
在本例中,总共定义了自定义属性两次:第一次在根元素上(–main-color为黑色),第二次在深色容器上(–main-color为白色)。自定义属性就像作用域变量一样,因为它的值会被后代元素继承。在深色容器中,–main-color为白色,在页面其他地方,则是黑色。

4 使用JavaScript改变自定义属性

还可以使用JavaScript在浏览器中实时访问和修改自定义属性。本书并不是介绍JavaScript的,所以只会简单介绍概念。需要你自己在JavaScript项目中实现剩下的功能。

代码清单2-30展示了如何访问一个元素上的属性。在网页中插入一个脚本,该脚本记录了根元素的–main-bg属性值。
代码清单2-30 访问JavaScript的自定义属性

<script type="text/javascript">
  var rootElement = document.documentElement;
  var styles = getComputedStyle(rootElement);    ←-- 获取一个元素的styles对象
  var mainColor = styles.getPropertyValue('--main-bg');   ←-- 获取styles对象的--main-bg值
  console.log(String(mainColor).trim());   ←---- 确保mainColor是一个字符串,并去掉前后空格;打印结果为“#fff”
</script>

因为你可以实时改变自定义属性的值,所以可以用JavaScript为–main-bg动态设置一个新值。如果将其设置为浅蓝色,效果会如图2-15所示。
在这里插入图片描述
图2-15 JavaScript可以通过改变–main-bg变量的值,设置面板的背景色

代码清单2-31给根元素上的–main-bg设置了一个新值。将这个代码清单放到

var rootElement = document.documentElement;
rootElement.style.setProperty('--main-bg', '#cdf');  ←---- 将根元素上的--main-bg设置为浅蓝色

如果运行以上脚本,所有继承了–main-bg属性的元素都会更新,使用新的值。在网页中,第一个面板的背景色会改为浅蓝色。第二个面板保持不变,因为它依然继承了深色容器里的属性。

利用这种技术,就可以用JavaScript实时切换网站主题,或者在网页中突出显示某些元素,或者实时改变任意多个元素。只需要几行JavaScript代码,就可以进行更改,从而影响网页上的大量元素。

5 探索自定义属性

自定义属性是CSS中一个全新的领域,开发人员刚刚开始探索。因为浏览器支持有限,所以还没有出现“典型”的用法。我相信假以时日,会出现各种最佳实践和新的用法。这需要你持续关注。继续使用自定义属性,看看能用它做出什么效果。

值得注意的是,在不支持自定义属性的浏览器上,任何使用var()的声明都会被忽略。请尽量为这些浏览器提供回退方案。

color: black;
color: var(--main-color);

然而这种做法不是万能的,比如当用到自定义属性的动态特性时,就很难有备用方案。关注 Can I Use网站,查看最新的浏览器支持情况。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值