css变量教程

    |     2020年4月27日   |   html/css/js, web前端技术   |     0 条评论   |    1063

当微软宣布 Edge 将支持 CSS 变量时,这项能力在主要浏览器里已经齐了。原生 CSS 从此可以声明可复用的自定义属性,再用 var() 读出来。变量名用两根连词线 --,因为 $foo 被 Sass 占用,@foo 被 Less 占用。

CSS 变量又叫 CSS 自定义属性(CSS custom properties):和 color、font-size 一样写在规则里,只是没有默认含义。变量名大小写敏感,--header-color 和 --Header-Color 是两个变量。

一、变量的声明

声明时变量名前面加两根连词线:

body {
  --foo: #7F583F;
  --bar: #F7EFD2;
}

上面在 body 里声明了 --foo 和 --bar。各种值都可以放进 CSS 变量:

:root{
  --main-color: #4d4e53;
  --main-bg: rgb(255, 255, 255);
  --logo-border-color: rebeccapurple;

  --header-height: 68px;
  --content-padding: 10px 20px;

  --base-line-height: 1.428571429;
  --transition-duration: .35s;
  --external-link: "external link";
  --margin-top: calc(2vh + 20px);
}

二、var() 函数

var() 用于读取变量:

a {
  color: var(--foo);
  text-decoration-color: var(--bar);
}

第二个参数是默认值,变量不存在时使用:

color: var(--foo, #7F583F);

第二个参数不处理内部的逗号或空格,都视作参数的一部分:

var(--font-stack, "Roboto", "Helvetica");
var(--pad, 10px 15px 20px);

var() 也可以用在变量的声明里:

:root {
  --primary-color: red;
  --logo-text: var(--primary-color);
}

注意:变量值只能当属性值,不能当属性名:

.foo {  --side: margin-top;  /* 无效 */  var(--side): 20px;}
写法 含义
--foo: #7F583F; 声明自定义属性
var(--foo) 读取
var(--foo, #7F583F) 读取,缺省用第二参
var(--side): 20px 当属性名,无效

三、变量值的类型

如果变量值是字符串,可以和其它字符串拼接:

--bar: 'hello';
--foo: var(--bar)' world';

利用这一点可以 debug:

body:after {
  content: '--screen-category : 'var(--screen-category);
}

如果变量值是数值,不能和单位直接连用:

.foo {
  --gap: 20;
  /* 无效 */
  margin-top: var(--gap)px;
}

必须用 calc() 把它们连起来:

.foo {
  --gap: 20;
  margin-top: calc(var(--gap) * 1px);
}

如果变量值带单位,就不能写成字符串:

/* 无效 */.foo {  --foo: '20px';  font-size: var(--foo);}
/* 有效 */.foo {  --foo: 20px;  font-size: var(--foo);}

四、作用域

同一个 CSS 变量可以在多个选择器里声明。读取时优先级最高的声明生效,这和 CSS 的层叠(cascade)一致。下面这段里三段文字颜色不同:

<style>
  :root { --color: blue; }
  div { --color: green; }
  #alert { --color: red; }
  * { color: var(--color); }
</style>

<p>蓝色</p>
<div>绿色</div>
<div id="alert">红色</div>

变量的作用域就是它所在选择器的有效范围:

body {
  --foo: #7F583F;
}

.content {
  --bar: #F7EFD2;
}

--foo 的作用域是 body,--bar 的作用域是 .content。全局变量通常放 :root:

:root {
  --main-color: #06c;
}

五、响应式布局

CSS 是动态的。可在 media 里改变量,让不同屏幕宽度用不同值:

body {
  --primary: #7F583F;
  --secondary: #F7EFD2;
}

a {
  color: var(--primary);
  text-decoration-color: var(--secondary);
}

@media screen and (min-width: 768px) {
  body {
    --primary:  #F7EFD2;
    --secondary: #7F583F;
  }
}

六、兼容性处理

不支持 CSS 变量的浏览器,可以先写回退值:

a {
  color: #7F583F;
  color: var(--primary);
}

也可以用 @supports 检测:

@supports ( (--a: 0)) {
  /* supported */
}

@supports ( not (--a: 0)) {
  /* not supported */
}

七、JavaScript 操作

JS 也能检测是否支持 CSS 变量:

const isSupported =  window.CSS &&  window.CSS.supports &&  window.CSS.supports('--a', 0);if (isSupported) {  /* supported */} else {  /* not supported */}

读写、删除的写法:

// 设置变量
document.body.style.setProperty('--primary', '#7F583F');

// 读取变量
document.body.style.getPropertyValue('--primary').trim();
// '#7F583F'

// 删除变量
document.body.style.removeProperty('--primary');

这意味着 JS 可以把任意值存进样式表。监听鼠标就是把坐标写入变量:

const docStyle = document.documentElement.style;

document.addEventListener('mousemove', (e) => {
  docStyle.setProperty('--mouse-x', e.clientX);
  docStyle.setProperty('--mouse-y', e.clientY);
});

对 CSS 无用的信息也可以放进变量,供 JS 读取:

--foo: if(x > 5) this.width = 10;

上面 --foo 在 CSS 里是无效语句,但 JS 读得到。可以把样式设定写在 CSS 变量里,让 JS 来读。CSS 变量因此是 JS 与 CSS 通信的一条路。

八、浏览器支持

当时全球网站流量约 77% 支持 CSS 变量,美国接近 90%。Scrimba.com 已经在用,因为客户大多使用现代浏览器。

20200427084200

一句话总结:用 –name 声明自定义属性,用 var() 读取(可带默认值);作用域跟选择器走,全局放 :root,media 里可改值,JS 用 setProperty / getPropertyValue 通信。

转载请注明来源:css变量教程
本文链接地址:https://ai.zhousir.top/?p=2924
回复 取消