好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

巧用CSS变量,让你的项目更加炫酷!

本篇 文章 带大家 了解 一下 CSS变量 ,介绍一下CSS变量的用法,看看如何巧用CSS变量,让你的CSS变得更心动,让你的项目更加炫酷!

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

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

/* 不使用CSS变量 */
.t IT le {
    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"].for each (v => {
    const  BT n = document.getElementById(`${v} -t heme-btn`);
    btn.addEventListener("click", () => document.body.style.set PR o PE rty("--bg-color", v));
});

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

减少样式代码的重复性 增加样式代码的扩展性 提高 样式代码的灵活性 增多一种CSS与JS的通讯方式 不用 深层遍历DOM 改变 某个样式

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

浏览器原生特性,无需经过任何转译就可直接运行 DOM对象一员,极大便利了CSS与JS之间的联系

认识

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

声明: -- 变量名 读取: var(--变量名, 默认值) 类型 普通:只能用作 属性值 不能用作 属性名 字符:与字符串拼接 "Hello, "var(--n am e) 数值:使用 calc() 与数值单位连用 var(--width) * 10px 作用域 范围:在 当前元素块作用域 及其 子元素块作用域 下有效 优先级别: 内联样式 > ID选择器 > 类选择器 = 属性选择器 = 伪类 选择器 > 标签选择器 = 伪元素选择器

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

使用场景

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

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

条形加载条

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

<ul class="strip-loading flex-ct-x">
    <li v-for="v in 6" :key="v"></li>
</ul>
.loading {
    width: 200px;
    h ei ght: 200px;
    li {
        border-radius: 3px;
        width: 6px;
        height: 30px;
        background-color:  # f66;
        animation: beat 1s ease -i n-out infinite;
        &am p;  + li {
            m arg in-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;
        }
    }
}

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

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

对于HTML部分的修改,让每个 <li> 拥有一个自己作用域下的 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 {
            mar gin -left: 5px;
        }
    }
}

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

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

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

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

心形加载条

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

通过动图分析,发现每条线条的背景色和动画时延不一致,另外动画运行时的高度也不一致。细心的你可能还会发现,第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变量 在JS中的运用。

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

读取变量: elem.style.getPropertyValue() 设置变量: elem.style.setProperty() 删除变量: elem.style.removeProperty()

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

<div class="tab-na vb ar">
    <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- rev erse;
    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;
        }
    }
}
 export  default {
    data() {
        return {
            index: 0,
            list: ["#f66", "#09f", "#3c9"]
        };
    },
    methods: {
        select(i) {
            this.index = i;
            this.$refs.tabs.style.setProperty("--tab-index", i);
        }
    }
};

在 <ul> 上定义 --tab-index 表示Tab当前的索引,当点击按钮时重置 --tab-index 的值,就可实现不操作DOM来移动 <ul> 的位置显示指定的Tab。不操作DOM而可移动 <ul> 是因为定义了 --tab-move ,通过 calc() 计算 --tab-index 与 --tab-move 的关系,从而操控 transform: translate3d() 来移动 <ul> 。

另外在 <li> 上定义 --bg-color 表示Tab的背景色,也是一种比较简洁的模板赋值方式,总比写 <li :style="backgroundColor: ${color}"> 要好看。如果多个CSS属性依赖一个变量赋值,那么使用 CSS变量 赋值到style上就更方便了,那些CSS属性可在CSS文件里进行计算与赋值,这样可帮助JS分担一些属性计算工作。

当然,这个标签导航栏也可通过纯CSS实现,有兴趣的同学可看看笔者之前一篇文章里的纯CSS标签导航栏。

悬浮跟踪按钮

通过几个栗子实践了 CSS变量 在CSS和JS上的运用,相信大家已经掌握了其用法和技巧。之前在某个网站看过一个比较酷炫的鼠标悬浮特效,好像也是使用 CSS变量 实现的。笔者凭着记忆也使用 CSS变量 实现一番。

其实思路也比较简单,先对按钮进行布局和着色,然后使用伪元素标记鼠标的位置,定义 --x 和 --y 表示伪元素在按钮里的坐标,通过JS获取鼠标在按钮上的 offsetLeft 和 offsetLeft 分别赋值给 --x 和 --y ,再对伪元素添加径向渐变的背景色,大功告成,一个酷炫的鼠标悬浮跟踪特效就这样诞生了。

<a class="track-btn pr tac" @mou SEM ove=" ;m ove">
    <span>妙用CSS变量,让你的CSS变得更心动</span>
</a>
.track-btn {
    display: block;
    overflow: hidden;
    border-radius: 100px;
    width: 400px;
    height: 50px;
    background-color: #66f;
    line-height: 50px;
    cursor: pointer;
    font-weight: bold;
    font -s ize: 18px;
    color: #fff;
    span {
        position: relative;
    }
    & :: before {
        --size: 0;
        position: absolute;
        left: var(--x);
        top: var(--y);
        width: var(--size);
        height: var(--size);
        background-image: radial-gra die nt(circle closest-side, #09f, transparent);
        content: "";
        transform: translate3d(-50%, -50%, 0);
        transition: all 200ms ease;
    }
    &:hover::before {
        --size: 400px;
    }
}
e xp ort default {
    name: "track-btn",
    methods: {
        move(e) {
            const x = e.pageX - e.target.offsetLeft;
            const y = e.pageY - e.target.offsetTop;
            e.target.style.setProperty("--x", `${x}px`);
            e.target.style.setProperty("--y", `${y}px`);
        }
    }
};

其实可结合鼠标事件来完成更多的酷炫效果,例如 动画关联 、 事件响应 等操作。没有做不到,只有想不到,尽情发挥你的想象力啦。

之前在CodePen上还看到一个挺不错的栗子,一个悬浮视差按钮,具体代码涉及到一些3D变换的知识。看完 源 码后,按照其思路自己也实现一番,顺便对代码稍加改良并封装成Vue组件, 存放 到本课件示例代码中。感觉 录制 的GIF有点别扭,显示效果不太好,有兴趣的同学可下载本课件示例代码,自己运行看看效果。

兼容

对于现代浏览器来说, CSS变量 的兼容性其实还是蛮好的,所以大家可放心使用。毕竟现在都是各大浏览器厂商快速迭代的时刻,产品对于用户体验来说是占了很大比重,因此在条件允许的情况下还是大胆尝新,不要被一些过去的所谓的规范所约束着。

试问现在还有多少人愿意去维护IE6~IE9的兼容性,如果一个产品的用户体验受限于远古浏览器的压制( 可能政务Web应用和金融Web应用除外吧 ),相信这个产品也不会走得很远。

我们在完成一个产品的 过程中 ,不仅仅是为了完成工作 任务 ,如果在保证 进度 的同时能花点心思点缀一下,可能会有意外的收获。 用心写好每一段代码,才是享受写代码的真谛 。

总结

本文通过循序渐进的方式探讨了 CSS变量 的运用和技巧,对于一个这么好用的特性,当然是不能放过啦。其实多多思考,就能把 CSS变量 用在很多场景上。

更多编程相关知识,请访问:编程入门!!

以上就是巧用CSS变量,让你的项目更加炫酷!的详细内容,更多请关注其它相关文章!

总结

以上是 为你收集整理的 巧用CSS变量,让你的项目更加炫酷! 全部内容,希望文章能够帮你解决 巧用CSS变量,让你的项目更加炫酷! 所遇到的问题。

如果觉得 网站内容还不错, 推荐好友。

查看更多关于巧用CSS变量,让你的项目更加炫酷!的详细内容...

  阅读:23次