关于javascript:CSS-变量由浅入深提升效率必备知识

43次阅读

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

作者:Ahmad Shadeed
译者:前端小智
起源:ishadeed

有幻想,有干货,微信搜寻 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。

本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。

CSS 变量(又名自定义属性)已在 Web 浏览器中反对了近四年。我个别也会依据我的项目状况应用它们。它们十分有用且易于应用,然而前端开发人员通常可能会误用或误会它们。

简介

CSS 变量是在 CSS 文档中定义的值,其目标是可重用性并缩小 CSS 值中的冗余。上面是一个根本示例。

.section {border: 2px solid #235ad1;}

.section-title {color: #235ad1;}

.section-title::before {
  content: "";
  display: inline-block;
  width: 20px;
  height: 20px;
  background-color: #235ad1;
}

在此代码段中,#235ad1应用了 3 次。设想一下,对于一个大型项目,不同的 CSS 文件,如果哪天被要求更改色彩。咱们能够做的最好快的形式就是“查找并替换”。

应用 CSS 变量,能够更快解决这个问题。定义变量名须要用 -- 结尾。首先,咱们当初将在 :root<html>元素中定义变量。

:root {--color-primary: #235ad1;}

.section {border: 2px solid var(--color-primary);
}

.section-title {color: var(--color-primary);
}

.section-title::before {
  /* Other styles */
  background-color: var(--color-primary);
}

是不是比后面的洁净得多?--color-primary变量是全局变量,因为咱们在 :root 元素中定义了它。然而,咱们还能够将变量范畴限定到整个文档中的某些元素。

命名变量

与编程语言命名变量类似,CSS 变量的无效命名应蕴含字母数字字符,下划线和破折号。另外,值得一提的是 CSS 变量辨别大小写。

/* 非法命名 */
:root {
    --primary-color: #222;
    --_primary-color: #222;
    --12-primary-color: #222;
    --primay-color-12: #222;
}

/* 非法命名 */
:root {
    --primary color: #222; /* Spacings are not allowed */
    --primary$%#%$#
}

作用域

CSS 变量也有本人的作用域,这个概念相似于其余编程语言。以 JS 为例:

:root {--primary-color: #235ad1;}

.section-title {
  --primary-color: d12374;
  color: var(--primary-color);
}

变量 element 是全局的,因而能够在 cool() 函数外部拜访。然而,只能在 cool() 函数中拜访变量otherElement

:root {--primary-color: #235ad1;}

.section-title {
  --primary-color: d12374;
  color: var(--primary-color);
}

变量 --primary-color 是全局变量,能够从文档中的任何中央拜访。变量 --primary-color 因为是在 .section-title 定义的,所以只能在 .section-title 中拜访。

上面是一个比拟直观的示例图片,能够增强咱们的了解:

变量 --primary-color 用于题目色彩。咱们想为 作者名 最新文章题目 自定义色彩,因而咱们须要将 --primary-color 笼罩。这同样实用于 --unit 变量。

/* 全局变量 */
:root {
  --primary-color: #235ad1;
  --unit: 1rem;
}

/* section-title 默认的色彩和间距 */
.section-title {color: var(--primary-color);
  margin-bottom: var(--unit);
}

/* 笼罩 section-title 款式 */
.featured-authors .section-title {--primary-color: #d16823;}

.latest-articles .section-title {
  --primary-color: #d12374;
  --unit: 2rem;
}

回退计划

这里的回退不是不反对 CSS 变量的回退,而是 CSS 变量能够反对回退计划。思考以下示例:

.section-title {color: var(--primary-color, #222);
}

留神,var()有多个值。第二个 #221 只在变量 --primary-color 因为某种原因没有定义的状况下无效。不仅如此,咱们还能够将 var() 嵌套到另一个 var() 中。

.section-title {color: var(--primary-color, var(--black, #222));
}

在变量值依赖于某个动作的状况下,该个性十分有用。当变量没有值时,为它提供一个回退很重要。

用例一:管制组件的大小

在设计零碎中,按钮通常有多种尺寸。通常,按钮能够具备三种尺寸(Small, normal, large)。应用 CSS 变量来实现它并不容易:

.button {
  --unit: 1rem;
  padding: var(--unit);
}

.button--small {--unit: 0.5rem;}

.button--large {--unit: 1.5rem;}

通过在按钮组件作用域内更改变量--unit,咱们创立了按钮的不同变体。

用例二:CSS 变量和 HSL 色彩

HSL代表色调,饱和度,亮度。色相的值决定了色彩,饱和度和亮度值能够管制色彩的深浅。

:root {
  --primary-h: 221;
  --primary-s: 71%;
  --primary-b: 48%;
}

.button {background-color: hsl(var(--primary-h), var(--primary-s), var(--primary-b));
  transition: background-color 0.3s ease-out;
}

/* 使背景更暗 */
.button:hover {--primary-b: 33%;}

这里何通过减小变量 --primary-b 使按钮变暗。

用例三:比例调整

如果您应用过 PhotoshopSketchFigmaAdobe XD之类的设计程序,那么咱们会想在调整元素大小的同时按住 Shift 键以防止扭曲它。

在 CSS 中,没有间接的办法来做到这一点,然而咱们有一个简略的解决办法,应用 CSS 变量。

假如有一个图标,并且其宽度和高度应该相等。我定义了变量--size,用于宽度和高度。

.icon {
  --size: 22px;
  width: var(--size);
  height: var(--size);
}

当初,您只需更改 --size 变量的值即可模仿 Shift 调整大小的成果。

用例四:CSS Grid

CSS 变量对于网格十分有用。假如心愿网格容器依据定义的首选宽度显示其子项。与为每个变体创立类并复制 CSS 相比,应用变量更容易做到这一点。

.wrapper {
  --item-width: 300px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--item-width), 1fr));
  grid-gap: 1rem;
}

.wrapper-2 {
  --item-width: 500px;

这样,咱们能够创立一个残缺的网格零碎,该零碎灵便,易于保护,并且能够在其余我的项目中应用。能够将雷同的概念利用于 grid-gap 属性。

wrapper {
  --item-width: 300px;
  --gap: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--item-width), 1fr));
}

.wrapper.gap-1 {--gap: 16px;}

用例五:全值申明,CSS 突变

以全值示意,例如,相似突变的货色。如果整个零碎中应用突变或背景,将其存储到 CSS 变量中可能是一件坏事。

:root {--primary-gradient: linear-gradient(150deg, #235ad1, #23d1a8);
}

.element {background-image: var(--primary-gradient);
}

或者咱们能够存储一个值。以角度为例:

.element {
  --angle: 150deg;
  background-image: linear-gradient(var(--angle), #235ad1, #23d1a8);
}

.element.inverted {--angle: -150deg;}

用例六:Background Position

咱们能够在 CSS 变量中蕴含多个值,这在须要依据特定上下文将元素搁置在不同地位的状况下很有用。

.table {
  --size: 50px;
  --pos: left center;
  background: #ccc linear-gradient(#000, #000) no-repeat;
  background-size: var(--size) var(--size);
  background-position: var(--pos);
}

用例七:在明暗模式之间切换

当初,网站比以往任何时候都更须要深色和浅色模式。应用 CSS 变量,咱们能够存储它们的两个版本,并依据用户或零碎偏好在它们之间切换。

:root {
  --text-color: #434343;
  --border-color: #d2d2d2;
  --main-bg-color: #fff;
  --action-bg-color: #f9f7f7;
}

/* 增加到 `<html>` 元素的类 */
.dark-mode {
  --text-color: #e9e9e9;
  --border-color: #434343;
  --main-bg-color: #434343;
  --action-bg-color: #363636;
}

用例八:设置默认值

在某些状况下,您将须要应用 JavaScript 设置 CSS 变量。假如咱们须要获取可扩大组件的高度。

变量 --details-height-open 为空,它将被增加到特定的 HTML 元素中。当 JavaScript 因为某种原因失败时,提供适当的默认值或后备值很重要。

.section.is-active {max-height: var(--details-height-open, auto);
}

auto值是 JS 失败时的回退值,并且没有定义 CSS 变量——details-height-open

用例九:管制 wrapper 宽度

网站wrapper 能够有多种变动。有时候是须要一个小包装一个页面,一个大包装另一个页面。在这种状况下,合并 CSS 变量可能是有用的。

.wrapper {
  --size: 1140px;
  max-width: var(--size);
}

.wrapper--small {--size: 800px;}

用例十一:动静网格我的项目

咱们能够在 style 属性中增加 --item-width 变量,仅此而已。例如,这种办法能够帮忙建设网格原型。

HTML

<div class="wrapper" style="--item-width: 250px;">
  <div></div>
  <div></div>
  <div></div>
</div>

CSS

.wrapper {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--item-width), 1fr));
  grid-gap: 1rem;
}

事例:https://codepen.io/shadeed/pe…

用例十二:用户头像

另一个有用的用例是大小调整元素。假如咱们须要四种不同大小的用户头像,并且只能应用一个变量来管制其大小。

<img src="user.jpg" alt=""class="c-avatar"style="--size: 1" />
<img src="user.jpg" alt=""class="c-avatar"style="--size: 2" />
<img src="user.jpg" alt=""class="c-avatar"style="--size: 3" />
<img src="user.jpg" alt=""class="c-avatar"style="--size: 4" />
.c-avatar {
  display: inline-block;
  width: calc(var(--size, 1) * 30px);
  height: calc(var(--size, 1) * 30px);
}

用例十三:媒体查问

组合 CSS 变量和媒体查问对于调整整个网站中应用的变量十分有用。我能想到的最简略的示例是更改间距值。

:root {--gutter: 8px;}

@media (min-width: 800px) {
  :root {--gutter: 16px;}
}

应用 --gutter 变量的任何元素都将依据视口大小更改其间距,这是不是很棒吗?

用例十四:继承

是的,CSS 变量的确继承。如果父元素中定义了 CSS 变量,那么子元素将继承雷同的 CSS 变量。咱们看上面的例子:

HTML

<div class="parent">
  <p class="child"></p>
</div>

css

.parent {--size: 20px;}

.child {font-size: var(--size);
}

.child元素能够拜访变量--size,因为它从父元素继承了它。很乏味, 那它在理论的我的项目中有啥用呢?

咱们有一组以下需要的操作项

  • 扭转一个变量就能够扭转所有项的大小
  • 间距应该是动静的

HTML

<div class="actions">
  <div class="actions__item"></div>
  <div class="actions__item"></div>
  <div class="actions__item"></div>
</div>

CSS

.actions {
  --size: 50px;
  display: flex;
  gap: calc(var(--size) / 5);
}

.actions--m {--size: 70px;}

.actions__item {width: var(--size);
  height: var(--size);
}

请留神,这里是如何将变量 --size 用于 flexbox gap属性的。这意味着间距能够是动静的,并且取决于 --size 变量。

另一个有用的例子是应用 CSS 变量继承来定制 CSS 动画:

@keyframes breath {
  from {transform: scale(var(--scaleStart));
  }
  to {transform: scale(var(--scaleEnd));
  }
}

.walk {
  --scaleStart: 0.3;
  --scaleEnd: 1.7;
  animation: breath 2s alternate;
}

.run {
  --scaleStart: 0.8;
  --scaleEnd: 1.2;
  animation: breath 0.5s alternate;
}

这样,咱们就不须要定义 @keyframes 两次,它将继承 .walk.run元素的定制 CSS 变量。

CSS 变量的工作形式

var() 函数中的 CSS 变量有效时,浏览器将依据所应用的属性用初始值或继承值替换。

:root {--main-color: 16px;}

.section-title {color: var(--main-color);
}

我应用 16pxcolor属性的值。这是齐全谬误的。因为 color 属性是继承的,因而浏览器将执行以下操作:

  • 该属性是否可继承?

    • 如果是,父节点是否领有该属性?

      • 是的,继承该值
      • 否: 设置为初始值
    • 否: 设置为初始值

上面解释浏览器工作的流程图。

网址值

咱们可能无法控制网页中的所有资源,其中一些必须在线托管。在这种状况下,您能够将链接的 URL 值存储在 CSS 变量中。

:root {--main-bg: url("https://example.com/cool-image.jpg");
}

.section {background: var(--main-bg);
}

然而,能想晓得是否能够应用 url() 插入 CSS 变量。思考以下

:root {--main-bg: "https://example.com/cool-image.jpg";}

.section {background: url(var(--main-bg));
}

因为 var(--main-bg) 被视为 url 自身,因而有效。当浏览器计算出该值时,该值将不再无效,并且将无奈按预期运行。

存储多个值

CSS 变量也能够示意多个值,看上面的例子:

:root {--main-color: 35, 90, 209;}

.section-title {color: rgba(var(--main-color), 0.75);
}

在示例中,咱们有一个 rgba() 函数,并且 RGB 值存储在 CSS 变量中,以逗号分隔。如果咱们想依据元素调整 alpha 值,这样做能够提供灵活性。惟一的毛病是无奈应用 DevTools 色彩选择器来调整 rgba 值。

另一个例子是将它与 background 属性一起应用。

:root {--bg: linear-gradient(#000, #000) center/50px;
}

.section {background: var(--bg);
}

.section--unique {background: var(--bg) no-repeat;
}

@keyframes规定中的动画变量

如果你浏览过 CSS 变量标准,则可能会读到“动画净化 ”一词。这个想法是,在@keyframes 规定中应用 CSS 变量时,无奈对其进行动画解决。

html

<div class="box"></div>

CSS

.box {
  width: 50px;
  height: 50px;
  background: #222;
  --offset: 0;
  transform: translateX(var(--offset));
  animation: moveBox 1s infinite alternate;
}

@keyframes moveBox {
  0% {--offset: 0;}
  50% {--offset: 50px;}
  100% {--offset: 100px;}
}

动画无奈顺利进行。它将仅对值 (0, 50px, 100px)进行动画解决。依据 CSS 标准:

@keyframes规定中应用的任何自定义属性都会受到动画净化,这将影响通过动画属性中的 var() 函数援用它时如何解决它。

如果咱们心愿上述动画可能失常工作,则应采纳老式的办法。这意味着,咱们须要用要设置动画的理论 CSS 属性替换变量。

@keyframes moveBox {
  0% {transform: translateX(0);
  }
  50% {transform: translateX(50px);
  }
  100% {transform: translateX(100px);
  }
}

计算

你可能不晓得能够应用 CSS 变量进行计算。思考上面示例:

.c-avatar {
  display: inline-block;
  width: calc(var(--size, 1) * 30px);
  height: calc(var(--size, 1) * 30px);
}

.c-avatar 大小会有不同的变动。我将默认值设置为 1,所以默认大小为(30px * 30px)。留神不同的类变动以及更改--size 值如何导致化身的大小变动。

.c-avatar--small {--size: 2;}

.c-avatar--medium {--size: 3;}

.c-avatar--large {--size: 4;}

Devtools 和 CSS 变量

咱们能够在浏览器 DevTools 中应用一些有用的技巧,这样就能更轻松地应用 CSS 变量。

看到色彩

应用 CSS 变量时,看到色彩或背景值的视觉指示器是否有用?Chrome 和 Edge 证实了这一点。

计算值

要查看 CSS 变量的计算值,只有将鼠标悬停或单击即可。

禁用 CSS 变量

当咱们须要从应用 CSS 变量的所有元素中禁用 CSS 变量时,能够通过从定义它的元素中勾销选中它来实现。参见下图:

本文介绍了 CSS 变量的很多内容,心愿能对你有些帮忙,二创不易,还望点个赞 + 转发。


代码部署后可能存在的 BUG 没法实时晓得,预先为了解决这些 BUG,花了大量的工夫进行 log 调试,这边顺便给大家举荐一个好用的 BUG 监控工具 Fundebug。

原文:https://ishadeed.com/article/…

交换

有幻想,有干货,微信搜寻 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。

本文 GitHub https://github.com/qq44924588… 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。

正文完
 0