关于css:如何在CSS中使用变量

8次阅读

共计 10834 个字符,预计需要花费 28 分钟才能阅读完成。

前言

CSS 变量(官网称为自定义属性)是用户定义的值,它能够在你的代码库中设置一次并屡次应用。它们使治理色彩、字体、大小和动画值变得更加容易,并确保整个 web 利用的一致性。

举个例子,你能够将品牌色彩设置为一个 CSS 属性(--primarycolor: #7232FA),并在任何应用品牌色彩的组件或款式中应用这个值(background: var(--primarycolor);)。

除了更加简洁以及不反复的代码,CSS 变量可用于构建调色板,进步响应能力,并创立动静类型零碎。

定义 CSS 变量

要定义一个自定义属性,抉择一个名称并在其后面加上两个连字符。任何字母数字字符都能够是名称的一部分。连字符(-)和下划线(_)也是被容许的。大范畴的 Unicode 字符能够成为自定义属性名称的一部分。这也包含 emoji,但为了清晰度和可读性,请保持应用字母数字名称。

上面是个例子:

--primarycolor: #0ad0f9ff; /* RGB alpha 16 进制色彩 */

--向 CSS 解释器表明这是一个自定义属性。当作为一个变量应用时,解释器引擎会将该属性替换为其值。

自定义属性名称是辨别大小写的。这意味着--primaryColor 和 --primarycolor 被认为是两种不同的属性名称。这与传统的 CSS 不同,在传统的 CSS 中,属性和值的大小写并不重要。然而,它与 ECMAScript 中的变量名规定是统一的。

与其余属性一样,比如说 display 或者font,CSS 自定义属性必须定义在申明块内。一个常见的模式是应用 :root 伪元素作为选择器来定义自定义属性。

:root {--primarycolor: #0ad0f9ff;}

:root是一个伪元素,它指向文档中的根元素。对 HTML 文档而言,指向的就是 <html> 元素。对 SVG 文档而言,指向的就是 <svg> 元素。应用:root 会让属性在整个文档中立刻可用。

应用 CSS 变量

为了让自定义属性作为变量来应用,咱们须要应用 var() 函数。例如,如果咱们想将 --primarycolor 自定义属性作为背景色彩来应用,咱们须要这么做:

body {background-color: var(--primarycolor);
}

咱们自定义属性的值将成为 background-color 属性的计算值。

到目前为止,自定义属性只能被用作变量来为规范的 CSS 属性设置值。例如,你不能把一个属性名称存储为一个变量,而后重用它。以下的 CSS 就无奈运行:

:root {
    --top-border: border-top; /* Can't set a property as custom property's value */
    var(--top-border): 10px solid #bc84d8; /* Can't use a variable as a property */
}

你也不能把属性 - 值对存储为一个变量,而后重用它。上面的例子也是有效的:

:root {--text-color: 'color: orange'; /* Invalid property value */}
body {var(--text-color); /* Invalid use of a property */
}

最初,你不能把一个变量作为值的一部分拼接起来:

:root {--base-font-size: 10;}
body {font: var(--base-font-size)px / 1.25 sans-serif; /* Invalid CSS syntax */
}

CSS 自定义属性 VS CSS 变量

“ 自定义属性 ” 是一个面向未来的名称,它阐明了这个性能有一天可能会被应用。然而,如果浏览器供应商施行了 CSS 扩大标准,这种状况就会扭转。该标准定义了用自定义选择器组合、函数和 at-rules 来扩大 CSS 的办法。

咱们通常称自定义属性为 “ 变量 ”,到目前为止,这也是咱们能够应用它们的惟一形式。在实践上,它们并不是齐全能够调换的术语。不过目前为止在实践中是能够调换的术语。在这篇文章中,我次要应用 自定义属性 ,因为那是它们的正确叫法。如果能是句子更加清晰,我将应用 变量 的叫法。

设置备用值

var()函数接管两个参数。第一个参数是自定义属性名称。第二个参数是可选的,但必须是申明值。这个申明值的性能是当自定义属性值没有被定义时,作为一个备用值或默认值被利用。

让咱们来看看上面的 CSS:

.btn__call-to-action {background: var(--accent-color, deepskyblue);
}

如果定义了 --accent-color,咱们假如其值为#f30,那么任何带有.btn__call-to-action 类的背景色将是橘红色的。如果没有定义,背景色将是深天蓝色。

申明值也能够嵌套。换句话说,能够应用变量作为 var 函数的备用值。

body {background-color: var(--books-bg, var(--arts-bg));
}

在下面 CSS 中,如果定义了--books-bg,背景色将会被设置为--books-bg 属性的值。如果没有定义,背景色将是调配给 --arts-bg 的任何值。如果两个属性都没有定义,背景色将会是属性的初始值。在这个例子中,初始值为transparent

当一个自定义属性的值对它所应用的属性来说是有效的,也会产生相似的状况。能够思考上面的 CSS:

:root {
    --text-primary: #600;
    --footer-link-hover: #0cg; /* Not a valid color value */
}
body {color: var(--text-primary);
}
a:link {color: blue;}
a:hover {color: red;}
footer a:hover {color: var(--footer-link-hover);
}

在这个例子中,--footer-link-hover 属性的值不是无效色彩。反而,footer a:hover<body> 元素中继承了 color 值。

解析自定义属性的形式与解析其余 CSS 值的形式雷同。假使值是有效的或者未定义的,如果属性是可继承的,CSS 解析器就会应用继承的值(比如说 colorfont)。如果属性是不可继承的,CSS 解析器就会应用初始值(比如说background-color)。

层叠值

自定义属性也遵循层叠的规定。它们的值会被后续的规定所笼罩:

:root {--text-color: #190736; /* navy */}
body {--text-color: #333;  /* dark gray */}
body {color: var(--text-color);
}

在上述示例中,body字体色彩将会是深灰色。咱们还能够在每个选择器的根底上重置值。让咱们向这个 CSS 增加更多的规定:

:root {--text-color: #190736; /* navy */}
body {--text-color: #333;   /* dark gray */}
p {--text-color: #f60;  /* orange */}
body {color: var(--text-color);
}
p {color: var(--text-color)
}

在这个例子中,任何包裹在 <p> 标签内的文本会是橘黄色。然而 <div> 内的文本或是其余元素内的文本依然是深灰色。

也能够应用 style 属性来设置自定义属性的值。比如说,style="--brand-color: #9a09af"

调色板

自定义属性特地适宜治理 HSL 调色板。HSL 代表 hue, saturation, lightness。这是一款基于亮度的色彩模型,相似于 RGB。咱们能够在 CSS 中应用 HSL,这要归功于hsl()hsla()色彩函数。hsl()函数接管三个参数,别离是 hue, saturation, 和 lightness,也就是色相、饱和度、亮度。hsla() 函数同时接管第四个参数,示意色彩的 alpha 透明度(取值范畴是 0 - 1 之间)。

RGB 零碎用红、绿、蓝的比例来表白色彩,而 HSL 则应用一个色彩圈,色相是该圈上的一个度数地位,而色调或暗影则用饱和度和亮度值来定义。饱和度的范畴从 0% 到 100%,其中 0% 是灰色,100% 是全色。亮度的范畴也是从 0% 到 100%,其中 0% 是彩色,100% 是红色,50% 是失常色彩。

在 HSL 色彩零碎中,次要色彩红、绿、蓝三原色在 0 度 /360 度、120 度和 240 度处相距 120 度。二级色彩 – 青色、品红和黄色 – 也相距 120 度,但位于次要色彩的对面,别离为 180 度、300 度和 60 度 /420 度。三级、四级和其余色彩则以大概 10 度的增量介于两者之间。蓝色用 HSL 来写的话,将会是hsl(240, 100%, 50%)

HSL 参数单位

当你在 hsl()hsla()函数的第一个参数中应用无单位的值时,浏览器会假设它是一个以度为单位的角度。然而,你能够应用任何受反对的 CSS 角度单位。蓝色也能够示意为hsl(240deg, 100%, 50%)hsl(4.188rad, 100%, 50%) 或者 hsla(0.66turn, 100%, 50%)

这就是乏味的中央。咱们能够应用自定义属性设置色相值,以及通过调整饱和度和亮度来设置更亮和更暗的暗影:

:root {
    --brand-hue:      270deg;  /* purple */
    --brand-hue-alt:  .25turn; /* green */

  /*
    hsl()和 hsla()能够承受逗号分隔的参数或空格分隔的参数。但旧的浏览器(如 Internet Explorer 11)只反对逗号分隔的参数。*/

    --brand-primary:   hsl(var( --brand-hue) 100% 50% );
    --brand-highlight: hsl(var( --brand-hue) 100% 75% );
    --brand-lowlight:  hsl(var( --brand-hue) 100% 25% );
    --brand-inactive:  hsl(var( --brand-hue)  50% 50% );

    --brand-secondary:     hsl(var( --brand-hue-alt) 100% 50% );
    --brand-2nd-highlight: hsl(var( --brand-hue-alt) 100% 75% );
    --brand-2nd-lowlight:  hsl(var( --brand-hue-alt) 100% 25% );
    --brand-2nd-inactive:  hsl(var( --brand-hue-alt)  50% 50% );
}

下面的 CSS 提供了上面所示的调色板。

这是一个繁难版本,但你也能够应用自定义属性来调整饱和度和亮度值。

健全的调色板生成

另一个想法是联合自定义属性和 calc() 函数,从一个根本色调中生成一个方形的配色计划。让咱们在上面的例子中创立一个方形配色计划。一个方形配色计划由四种色彩组成,这些色彩在色轮上彼此等距,也就是相距 90 度:

:root {
    --base-hue: 310deg; /* Hot pink */
    --distance: 90deg;

    --color-a: hsl(var(--base-hue), 100%, 50% );
    --color-b: hsl(calc( var(--base-hue) + var(--distance) ), 100%, 50% );
    --color-c: hsl(calc( var(--base-hue) + (var( --distance) * 2 ) ), 100%, 50% );
    --color-d: hsl(calc( var(--base-hue) + (var( --distance) * 3 ) ), 100%, 50% );
}

CSS 为咱们提供了如下所示的颇具寒带风情的色调计划。

自定义属性也能很好地与媒体查问相互配合,咱们会在前面章节中看到。

深色主题调色板

你能够应用 CSS 自定义变量为你的网站,定义与深色和浅色主题相干的一系列的变量。

以上面的页面款式为例,咱们能够在 :root 中为相应的色彩定义了自定义属性后,用变量替换不同选择器中所有的 HSL 色彩:

:root {
  /*...*/
  --nav-bg-color: hsl(var(--primarycolor) , 50%, 50%);
  --nav-text-color: hsl(var(--primarycolor), 50%, 10%);
  --container-bg-color: hsl(var(--primarycolor) , 50%, 95%);
  --content-text-color: hsl(var(--primarycolor) , 50%, 50%);
  --title-color: hsl(var(--primarycolor) , 50%, 20%);
  --footer-bg-color: hsl(var(--primarycolor) , 93%, 88%);
  --button-text-color: hsl(var(--primarycolor), 50%, 20%);
}

曾经为自定义属性应用了适当的名称。比如说,--nav-bg-color 指的是导航栏背景色,--nav-text-color 指的是导航栏前景色或者文本色。

而后,复制 :root 选择器及其内容,但要为其增加一个带有 dark 值的主题属性:

:root[theme='dark']{/*...*/}

如果带有 dark 值的主题属性被增加到 <html> 元素上,那么该主题将被激活。

当初咱们能够手动操作这些变量值,通过缩小 HSL 色彩的亮度值来提供一个深色主题。或者咱们能够应用其余技术,如 invert()brightness()等 CSS 过滤器,它们通常用于调整图像的渲染,但也可用于其余任何元素。

增加如下代码到 :root[theme='dark'] 中:

:root[theme='dark'] {
  --dark-hue: 240;
  --light-hue: 250;
  --primarycolor: var(--dark-hue);
  --nav-bg-color: hsl(var(--primarycolor), 50%, 90%);
  --nav-text-color: hsl(var(--primarycolor), 50%, 10%);
  --container-bg-color: hsl(var(--primarycolor), 50%, 95%);
  --content-text-color: hsl(var(--primarycolor), 50%, 50%);
  --title-color: hsl(--primarycolor, 50%, 20%);
  --footer-bg-color: hsl(var(--primarycolor), 93%, 88%);
  --button-text-color: hsl(var(--primarycolor), 50%, 20%);
  filter: invert(1) brightness(0.6);
}

invert()过滤器会反转所选元素的所有色彩(在本例中是每个元素)。反转的值能够用百分比或数字来指定。参数值 100% 或 1 将齐全反转元素的色相、饱和度和亮度值。

brightness()过滤器使元素更加亮堂或者暗黑。如果数值为 0,就会呈现一个齐全暗黑的元素。

invert()过滤器会使一些元素变得十分亮堂。须要通过设置 brightness(0.6) 来升高亮度。

具备不同水平深色的深色主题:

应用 JavaScript 切换主题

当初,当用户点击深色 / 浅色按钮时,咱们应用 JavaScript 来切换深色和浅色主题。在 HTML</body>标签闭合前增加行内 <script> 标签,标签内具备如下代码:

const toggleBtn = document.querySelector("#toggle-theme");
toggleBtn.addEventListener('click', e => {console.log("Switching theme");
  if(document.documentElement.hasAttribute('theme')){document.documentElement.removeAttribute('theme');
  }
  else{document.documentElement.setAttribute('theme', 'dark');
  }
});

Document.documentElement指的是文档中的根 DOM 元素,也就是 <html>。这段代码应用.hasAttribute() 办法查看 theme 属性是否存在。如果不存在,就将 dark 增加到该属性上,从而导致切换到深色主题。否则,它将删除该属性,从而导致切换到浅色主题。

留神:你还应该把它与 CSS 中的 prefers-color-scheme 性能联合起来应用,它能够用来从用户的操作系统或用户代理(浏览器)设置中主动扭转浅色 / 深色主题。这将在下一节中展现。

媒体查问

咱们还能够在媒体查问中应用自定义属性。比如说,你能够应用自定义属性来定义明暗配色计划:

:root {--background-primary: hsl(34, 78%, 91%);
    --text-primary: hsl(25, 76%, 10%);
    --button-primary-bg: hsl(214, 77%, 10%);
    --button-primary-fg: hsl(214, 77%, 98%);
}
@media screen and (prefers-color-scheme: dark) {
    :root {--background-primary: hsl(25, 76%, 10%);
      --text-primary: hsl(34, 78%, 91%);
      --button-primary-bg: hsl(214, 77%, 98%);
      --button-primary-fg: hsl(214, 77%, 10%);
  }
}

同样地,咱们能够应用自定义属性来扭转适宜于屏幕与打印的基准字体大小。

:root {--base-font-size: 10px;}
@media print {
    :root {--base-font-size: 10pt;}
}
html {font: var(--base-font-size) / 1.5 sans-serif;
}
body {font-size: 1.6rem;}

在本例中,咱们正在应用适宜于打印和屏幕的媒体单位。对于这两种媒体,咱们将应用 10 个单位的基准字体大小,对于屏幕来说是像素(px),对于打印来说是点(pt)。咱们还将应用 --base-font-size: 的值来为咱们的根元素(html)设置一个起始尺寸。而后咱们能够 rem 单位来调整绝对于基准字体尺寸的排版。

在 JavaScript 中应用自定义属性

请记住:自定义属性是 CSS 属性,而且咱们能够与它们进行互动。比如说,咱们能够应用CSS.supports()API 来检测浏览器是否反对自定义属性:

const supportsCustomProps = CSS.supports('--primary-text: #000');

// 如果浏览器反对自定义属性,则打印 true
console.log(supportsCustomProps);

咱们也能够应用 setProperty() 办法来设置自定义属性值:

document.body.style.setProperty('--bg-home', 'whitesmoke');

应用 removeProperty() 的形式也是相似的。只需传递自定义属性名称作为参数:

document.body.style.removeProperty('--bg-home');

要应用自定义属性作为 JavaScript 的值,能够应用 var() 函数,并将属性名称作为其参数。

document.body.style.backgroundColor = 'var(--bg-home)';

还有,你不能应用 style 对象的方括号语法或驼峰属性来设置自定义属性。换句话说,document.body.style.--bg-homedocument.body.style['--bg-home'] 都无奈发挥作用。

在组件中应用自定义属性

像 React、Angular 和 Vue 这样的 JavaScript 框架让开发者应用 JavaScript 来创立可重用、可共享的 HTML 块,通常会在组件层面上定义 CSS。

这是一个无关 React 组件的示例,应用 JSX 语法编写:

import React from 'react';

/* Importing the associated CSS into this component */
import '../css/field-button.css';

class FieldButtonGroup extends React.Component {render() {
        return (
            <div className="field__button__group">
                <label htmlFor={this.props.id}>{this.props.labelText}</label>
                <div>
                    <input type={this.props.type}
                      name={this.props.name}
                      id={this.props.id}
                      onChange={this.props.onChangeHandler} />
                    <button type="submit">{this.props.buttonText}</button>
                 </div>
            </div>
        );
    }
}

export default FieldButtonGroup;

咱们的 React 组件将 CSS 导入到一个 JavaScript 文件中。编译时,field-button.css的内容被内联加载。这里有一个可行的办法来应用自定义属性:

.field__button__group label {display: block;}
.field__button__group button {
    flex: 0 1 10rem;
    background-color: var(--button-bg-color, rgb(103, 58, 183)); /* include a default */
    color: #fff;
    border: none;
}

在该示例中,咱们应用自定义属性 --button-bg-color 作为按钮的背景色彩,同时随同着默认色彩,以防 --button-bg-color 没有定义。在这里,咱们能够在全局样式表或通过 style 属性设置--button-bg-color 的值。

让咱们将值设置为 React 属性。React props(简称为属性)模拟元素属性。它们是一种将数据传入 React 组件的形式。在本例中,咱们将增加一个名为 buttonBgColor 的属性:

import FieldButtonGroup from '../FieldButtonGroup';

class NewsletterSignup extends React.Component {render() {
        // For brevity, we've left out the onChangeHandler prop.
        return (
            <FieldButtonGroup type="email" name="newsletter" id="newsletter"
              labelText="E-mail address" buttonText="Subscribe"
              buttonBgColor="rgb(75, 97, 108)" />
        );
    }
}

export default NewsletterSignup;

当初,咱们须要更新 FieldButtonGroup 组件,来反对本次更改:

class FieldButtonGroup extends React.Component {render() {
        /*
        In React, the style attribute value must be set using a JavaScript
        object in which the object keys are CSS properties. Properties
        should either be camelCased (e.g. backgroundColor) or enclosed in
        quotes.
        */

        const buttonStyle = {'--button-bg-color': this.props.buttonBgColor};

        return (
            <div className="field__button__group">
                <label htmlFor={this.props.id}>{this.props.labelText}</label>
                <div>
                    <input type={this.props.type} 
                      name={this.props.name} id={this.props.id}
                      onChange={this.props.onChangeHandler} />
                    <button type="submit" style={buttonStyle}>
                      {this.props.buttonText}
                    </button>
                </div>
            </div>
        );
    }
}

在上述代码中,咱们增加了一个 buttonStyle 对象,该对象蕴含自定义属性的名称,并将其值设置为 buttonBgColor 属性的值,并为按钮增加 style 属性。

应用 style 属性可能与你所学到的对于编写 CSS 的常识相悖。CSS 的一个卖点是,咱们能够定义一套款式,在多个 HTML 和 XML 文档中应用。另一方面,style 属性将 CSS 的范畴限度在它所利用的元素上,导致咱们不能重用它。并且也不能利用层叠的劣势。

但在一个基于组件的前端架构中,一个组件可能在多种状况下被多个团队应用,甚至可能在客户端我的项目中共享。在这些状况下,你可能想把层叠的 全局范畴 style属性所提供的 部分范畴 联合起来。

style 属性设置自定义属性值,能够将成果限度在 FieldButtonGroup 组件这个特定实例中。然而,因为咱们应用了一个自定义属性而不是规范的 CSS 属性,咱们依然能够抉择在样式表中定义--button-bg-color,而不是作为一个组件属性。

总结

自定义属性采纳了预处理器的最佳性能之一 – 变量,并使其成为 CSS 的原生性能。应用自定义属性,咱们能够:

  • 创立可重用的、主题化的组件
  • 轻松调整内边距、外边距以及排版,以适应各种视口尺寸和媒体
  • 改良 CSS 色彩值的一致性

变量有一系列的利用,在基于组件的设计零碎中特地有用。我心愿你当初对如何在 CSS 中应用变量或自定义属性有了更好的了解。

以上就是全部内容,如果对你有所帮忙,欢送点赞珍藏转发~

正文完
 0