【CSS自定义属性】进一步使用(一)

简介: 【CSS自定义属性】进一步使用(一)

进阶使用CSS自定义属性

在之前一篇介绍CSS自定义属性的文章中,我们介绍了什么是CSS自定义属性,var()calc()。本篇文章中,为了进一步使用它,我们将介绍CSS自定义属性的其他用法。

自定义原则

在传统的CSS中,通常我们需要写重复的属性值,而自定义原则能让我们避免这种情况。做到“一处定义,处处使用”。

:root {
  --theme-color: gray;
}
.button {
  background-color: var(--theme-color);
}
.title {
  color: var(--theme-color);
}

以后,一旦要调整,只需要改动--theme-color这个属性的值。

进一步发挥calc()计算

我们知道,calc()与自定义属性结合能实现属性值的计算。

现在,有这样一个场景:实现一个3列的网格布局,其中:内边距8px,网格中的box外边距为8px。

原有的代码:

.image-grid {padding: 8px;}
.image-grid > .box {margin: 8px;}

下面使用calc()改进:

:root {
  --image-grid-spacing: 16px;
}
.image-grid {
  padding: calc(var(--image-grid-spacing)/2);
}
.image-grid > .box {
  margin: calc(var(--image-grid-spacing)/2);
}

注意: Safari/WebKit 目前在 calc()中的计算还有一些问题,这些问题在 Safari 10.1 中有望得到解决。

再来看一个例子:用flexbox实现响应式网格。

.image-grid {
  display: flex;
  flex-wrap: wrap;
  padding: 8px;
}
.image-grid > .image {
  margin: 8px;
  width: calc(100% - 16px);
}
@media (min-size: 600px) {
  /* 3 images per line */
  .image-grid > .image {
    width: calc(100% / 3 - 16px);
  }
}
@media (min-size: 1024px) {
  /* 6 images per line */
  .image-grid > .image {
    width: calc(100% / 6 - 16px);
  }
}

上面这段代码实现的是一组响应式布局,但乍看上去,一头雾水。默认情况下,图片排成一列,也就是一行只显示一张图片;如果屏幕尺寸是600px、1024px…相应的,图片排列变成了三列或者是六列。和上一段代码例子中一样,此处容器边缘宽度和网格间距都是16px。

calc() 中的计算内容比较复杂,我们需要加上注释解释。但如果用上了自定义变量,情况就不同了:

:root {
  --grid-spacing: 16px;
  --grid-columns: 1;
}
.image-grid {
  display: flex;
  flex-wrap: wrap;
  padding: calc(var(--grid-spacing) / 2);
}
.image-grid > .image {
  margin: calc(var(--grid-spacing) / 2);
  width: calc(100% / var(--grid-columns) - var(--grid-spacing));
}
@media (min-size: 600px) {
  :root {
    --grid-columns: 3;
  }
}
@media (min-size: 1024px) {
  :root {
    --grid-columns: 6;
  }
}

可以看出,所有的计算都是在一处完成的。在媒体查询中需要改变的只有自定义属性的值。

CSS 与 Javascript之间的桥梁:自定义属性

假设现在有一个容器元素,我们希望当用户点击它的时候可以移动到最后一位。如果在该容器中设置一个辅助性元素,我们可以这样移动它:

.container {
  position: relative;
  --clickX: 0;
  --clickY: 0;
}
.container > .auxElement {
  position: absolute;
  transform: translate(var(--clickX, 0), var(--clickY, 0));
}
const container = document.querySelector('.container');
container.addEventListener('click', evt => {
  container.style.setProperty('--clickX', `${evt.clientX}px`);
  container.style.setProperty('--clickY', `${evt.clientY}px`);
});

上面,我们使用 CSS 处理视觉表现上了,不再需要通过 JS 更改内联样式

一次定义,处处使用

逻辑上的变化可能伴随着大面积视觉表现上的更改,典型的例子就是选择主题,更换主题时可能引起大部分元素视觉上的变化。

以音乐播放器为例,如果你希望界面颜色随着当前收听专辑的更改而变化,从前你需要维护一系列会出现颜色变化的元素以及属性,需要的时候依次更改:

const thingsToUpdate = new Map([
  ['playButton', 'background-color'],
  ['title': 'color'],
  ['progress': 'background-color']
]);
for (let [id, property] of thingsToUpdate) {
  document.getElementById(id).style.setProperty(property, newColor);
}

HTML 结构如下:

<span class="title js-update-color">Song title</span>
<button class="play-button js-update-background">Play</button>
<div class="progress-track js-update-background"></div>
const colorList = document.querySelectorAll('.js-update-color');
for (let el of colorList) {
  el.style.setProperty('color', newColor);
}
const backgroundList = document.querySelectorAll('.js-update-background');
for (let el of backgroundList) {
  el.style.setProperty('background-color', newColor);
}

这种方式,不管怎么样,都要常常更新跟随主题变化的元素和属性,所以这个方法会让后续维护变得艰难。

还有一种解决方式是引入一个新样式(!important),它将会覆盖旧样式。这个方法相对好一些(虽然比较 hacky),但还是避免不了要覆盖一系列的样式,这其中依然有着维护成本。

  • 通过自定义属性处理

只要改变位于 DOM 结构中最高点的元素,接着让浏览器去改变该节点之下的节点:

.player {
  --theme-color: red;
}
.play-button {
  background-color: var(--theme-color);
}
.title {
  color: var(--theme-color);
}
.progress-track {
  background-color: var(--theme-color);
}
document.querySelector('.player').style.setProperty('--theme-color', newColor);

JavaScript 根本不需要知道哪些元素哪些属性会发生变化,也不需要开发者维护受影响的元素列表。使用自定义元素,明显比前文中的方案都好!

这样,CSS和JS分别独立实现样式和逻辑部分,维护起来更加容易


相关文章
|
10月前
|
前端开发
css的渐变属性linear-gradient
css的渐变属性linear-gradient
|
10月前
|
前端开发
CSS属性:盒子模型
CSS属性:盒子模型
80 0
|
10月前
|
前端开发
CSS属性
CSS属性
74 0
|
8月前
|
前端开发
CSS 浮动属性讲解和使用
本文介绍了CSS中的浮动(float)属性,包括其基本功能、属性选项及其在网页布局中的应用。浮动使元素脱离文档流,向左或右排列,周围元素随之调整。文章还详细讲解了清除浮动的方法,如使用clear属性、设置父元素高度、利用overflow属性、伪元素等,以解决因浮动导致的布局问题。最后,强调了浮动在创建复杂布局时的作用,并预告后续内容。
223 2
|
8月前
|
前端开发
CSS transition过渡属性详解
本文介绍了CSS中`transition`属性的作用、用法及实例。`transition`用于在元素属性变化时添加平滑过渡动画,通过设置`transition-property`、`transition-duration`、`transition-timing-function`和`transition-delay`等属性值,可以精细控制过渡效果。文末提供了HTML示例代码,展示了如何使用`transition`实现鼠标悬停时背景颜色的平滑变化。
391 1
|
8月前
|
Web App开发 前端开发 iOS开发
css所有缩写属性,CSS属性简写整理
css所有缩写属性,CSS属性简写整理
155 1
|
10月前
|
前端开发
前端基础(五)_CSS文本文字属性、背景颜色属性
本文详细介绍了CSS中关于文本和背景颜色的样式属性。包括字体大小、字体族、字体加粗、字体样式、文本行高、`font`属性、文本颜色、文本对齐方式、文本装饰线、首行缩进等文本属性,以及背景颜色、背景图片、背景重复、背景位置等背景属性。文章通过示例代码展示了这些属性的具体应用和效果。
347 3
前端基础(五)_CSS文本文字属性、背景颜色属性
|
9月前
|
前端开发
CSS 中哪些属性可以继承
在 CSS 中,属性分为可继承与不可继承。可继承属性会在子元素中沿用父元素的样式设定。常见可继承属性包括:文本属性(如 `font-family`, `color`),列表属性(如 `list-style`),表格布局属性(如 `border-collapse`),以及其他如 `visibility` 和 `direction` 等属性。正确理解这些属性有助于更高效地进行样式设计。
|
8月前
|
前端开发
css简写属性
css简写属性
83 0