(给前端大全加星标,提升前端技能)

作者:IQ前端 公号 / JowayYoung(本文来自作者投稿)

前言

「CSS变量」又叫「CSS自定义属性」,为什么会突然提起这个很少人用到的东西呢?因为最近在重构个人官网,不知道为什么突然喜欢用上「CSS变量」,可能其自身隐藏的魅力,让笔者对它刮目相看。

谈到为什么会在CSS中使用变量,下面举个栗子,估计大家一看就会明白。

/* 不使用CSS变量 */
.title {
background-color: red;
}
.desc {
background-color: red;
}

/* 使用CSS变量 */
:root {
--bg-color: red;
}
.title {
background-color: var(--bg-color);
}
.desc {
background-color: var(--bg-color);
}

看完可能会觉得使用「CSS变量」的代码量多了一点,但是有没有想到突然某天万恶的策划小哥哥和设计小姐姐说要做一个换肤功能。按照平常的思路,估计有些同学就会按照默认颜色主题增加一份对照的新颜色主题CSS文件。这样每次新增需求都同时维护几套主题颜色多麻烦啊。

此时「CSS变量」就派上用场了,提前跟设计小姐姐规范好各种需要变换的颜色并通过「CSS变量」进行定义,通过JS批量操作这些定义好的「CSS变量」即可。这也是「变换主题颜色」的一种解决方案之一,好处在于只需写一套CSS代码。

["red", "blue", "green"].forEach(v => {
const btn = document.getElementById(`${v}-theme-btn`);
btn.addEventListener("click", () => document.body.style.setProperty("--bg-color", v));
});

在此总结下CSS使用变量的好处:

可能有些同学会问,Sass和Less早就实现了变量这个特性,何必再多此一举呢。可是细想一下,「CSS变量」对比Sass和Less的变量,又有它的过人之处。

认识

本来打算用一半篇幅讲述「CSS变量」的规范和用法,但是网上一搜一大把就感觉没必要了,贴上阮一峰老师写的教程《CSS变量教程》。同时笔者也对「CSS变量」的细节地方进行一个整理,方便大家记忆。

作用域

接下来使用几个特别的场景展示「CSS变量」的魅力。还是那句话,「一样东西有使用的场景,那自然就会有它的价值」,那么用的人也会越来越多。

使用场景

其实「CSS变量」有一个特别好用的场景,那就是结合List元素集合使用。如果不明白这是什么,请继续往下看。

以下所有演示代码基于Vue文件,但HTML、CSS和JS分开书写,为了简化CSS的书写而使用Sass进行预处理,方便代码演示

条形加载条

一个条形加载条通常由几条线条组成,并且每条线条对应一个存在不同时延的相同动画,通过时间差运行相同的动画,从而产生加载效果。估计大部分的同学可能会把CSS代码写成以下这样。

css鼠标样式怎么改_css改变鼠标样式_css鼠标效果

<ul class="strip-loading flex-ct-x">
<li v-for="v in 6" :key="v"></li>
</ul>

.loading {
width: 200px;
height: 200px;
li {
border-radius: 3px;
width: 6px;
height: 30px;
background-color: #f66;
animation: beat 1s ease-in-out infinite;
& + li {
margin-left: 5px;
}
&:nth-child(2) {
animation-delay: 200ms;
}
&:nth-child(3) {
animation-delay: 400ms;
}
&:nth-child(4) {
animation-delay: 600ms;
}
&:nth-child(5) {
animation-delay: 800ms;
}
&:nth-child(6) {
animation-delay: 1s;
}
}
}

分析代码发现,每个只是存在animation-delay不同,而其余代码则完全相同,换成其他类似的List元素集合场景,那岂不是有10个就写10个:nth-child。

显然这种方法不灵活也不容易封装成组件,如果能像JS那样封装成一个函数css改变鼠标样式,并根据参数输出不同的样式效果,那就更棒了。说到这里,很明显就是为了铺垫「CSS变量」的开发技巧了。

对于HTML部分的修改,让每个拥有一个自己作用域下的「CSS变量」。对于CSS部分的修改,就需要分析哪些属性是随着index递增而发生规律变化的,对规律变化的部分使用「CSS变量」表达式代替即可。

<ul class="strip-loading flex-ct-x">
<li v-for="v in 6" :key="v" :style="`--line-index: ${v}`"></li>
</ul>

.strip-loading {
width: 200px;
height: 200px;
li {
--time: calc((var(--line-index) - 1) * 200ms);
border-radius: 3px;
width: 6px;
height: 30px;
background-color: #f66;
animation: beat 1.5s ease-in-out var(--time) infinite;
& + li {
margin-left: 5px;
}
}
}

源码链接可在文章结尾处获取

代码中的变量–line-index和–time使每个拥有一个属于自己的作用域。例如第2个,–line-index的值为2,–time的计算值为200ms,换成第3个后这两个值又会不同了。

这就是「CSS变量」的作用范围所致(在当前元素块作用域及其子元素块作用域下有效)css改变鼠标样式,因此在.strip-loading的块作用域下调用–line-index是无效的。

/* flex属性无效 */
.loading {
display: flex;
align-items: center;
flex: var(--line-index);
}

通过妙用「CSS变量」,也把CSS代码从29行缩减到15行,对于那些含有List元素集合越多的场景,效果就更明显。而且这样写也更加美观更加容易维护,某天说加载效果的时间差不明显,直接将calc((var(–line-index) – 1) * 200ms)里的200ms调整成400ms即可。就无需对每个:nth-child(n)进行修改了。

心形加载条

前段时间刷掘金看到陈大鱼头兄的心形加载条,觉得挺漂亮的,很带感觉。

css鼠标效果_css鼠标样式怎么改_css改变鼠标样式

通过动图分析,发现每条线条的背景色和动画时延不一致,另外动画运行时的高度也不一致。细心的你可能还会发现,第1条和第9条的高度一致,第2条和第8条的高度一致,依次类推,得到高度变换相同类的公式:对称index = 总数 + 1 – index。

背景色使用了滤镜的色相旋转hue-rotate函数,目的是为了使颜色过渡得更加自然;动画时延的设置和上面条形加载条的设置一致。下面就用「CSS变量」根据看到的动图实现一番。

<div class="heart-loading flex-ct-x">
<ul style="--line-count: 9">
<li v-for="v in 9" :key="v" :class="`line-${v}`" :style="`--line-index: ${v}`"></li>
</ul>
</div>

.heart-loading {
width: 200px;
height: 200px;
ul {
display: flex;
justify-content: space-between;
width: 150px;
height: 10px;
}
li {
--Θ: calc(var(--line-index) / var(--line-count) * .5turn);
--time: calc((var(--line-index) - 1) * 40ms);
border-radius: 5px;
width: 10px;
height: 10px;
background-color: #3c9;
filter: hue-rotate(var(--Θ));
animation-duration: 1s;
animation-delay: var(--time);
animation-iteration-count: infinite;
}
.line-1,
.line-9 {
animation-name: line-move-1;
}
.line-2,
.line-8 {
animation-name: line-move-2;
}
.line-3,
.line-7 {
animation-name: line-move-3;
}
.line-4,
.line-6 {
animation-name: line-move-4;
}
.line-5 {
animation-name: line-move-5;
}
}

源码链接可在文章结尾处获取

一波操作后就有了下面的效果。和陈大鱼头兄的心形加载条对比一下,颜色、波动曲线和跳动频率有点不一样,在暖色调的蔓延和肾上腺素的飙升下,这是一种心动的感觉。想起自己曾经写的一首诗:我见犹怜,爱不释手,雅俗共赏,君子好逑。

css改变鼠标样式_css鼠标效果_css鼠标样式怎么改

标签导航栏

上面通过两个加载条演示了「CSS变量」在CSS中的运用以及一些妙用技巧,现在通过标签导航栏演示「CSS变量」在JS中的运用。

JS中主要有3个操作「CSS变量」的API,看上去简单易记,分别如下:

先上效果图,效果中主要是使用「CSS变量」标记每个Tab的背景色和切换Tab的显示状态。

css鼠标样式怎么改_css改变鼠标样式_css鼠标效果

<div class="tab-navbar">
<nav>
<a v-for="(v, i) in list" :key="v" :class="{ active: index === i }" @click="select(i)">标题{{i + 1}}</a>
</nav>
<div>
<ul ref="tabs" :style="`--tab-count: ${list.length}`">
<li v-for="(v, i) in list" :key="v" :style="`--bg-color: ${v}`">内容{{i + 1}}</li>
</ul>
</div>
</div>

.tab-navbar {
display: flex;
overflow: hidden;
flex-direction: column-reverse;
border-radius: 10px;
width: 300px;
height: 400px;
nav {
display: flex;
height: 40px;
background-color: #f0f0f0;
line-height: 40px;
text-align: center;
a {
flex: 1;
cursor: pointer;
transition: all 300ms;
&.active {
background-color: #66f;
font-weight: bold;
color: #fff;
}
}
}
div {
flex: 1;
ul {
--tab-index: 0;
--tab-width: calc(var(--tab-count) * 100%);
--tab-move: calc(var(--tab-index) / var(--tab-count) * -100%);
display: flex;
flex-wrap: nowrap;
width: var(--tab-width);
height: 100%;
transform: translate3d(var(--tab-move), 0, 0);
transition: all 300ms;
}
li {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
background-color: var(--bg-color);
font-weight: bold;
font-size: 20px;
color: #fff;
}
}
}

exportdefault {
data() {
return {
index: 0,
list: ["#f66", "#09f", "#3c9"]
};
},
methods: {
select(i) {
this.index = i;
this.$refs.tabs.style.setProperty("--tab-index", i);
}
}
};

源码链接可在文章结尾处获取

写到最后,送给大家一个大大的彩蛋,一个暖心彩虹色调搭配的爱心点赞按钮。如果你觉得本文写得棒棒哒,请给笔者一个赞喔,就像下面那样。当然,彩蛋源码也在课件示例代码里啦。想了解更多的CSS开发技巧,可移步到笔者19年写的一篇9.2万阅读量的爆款文章《灵活运用CSS开发技巧(66个骚操作案例)》,保证满足你的眼球。

css鼠标样式怎么改_css鼠标效果_css改变鼠标样式

公众号:阿哲项目网
站长微信:lovemeaAZ

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注