CSS 伪类、伪元素的应用实例:电池充电、高能进度条

本文主要是介绍CSS 伪类、伪元素的应用实例:电池充电、高能进度条,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、目的

    本文通过 CSS 伪类、伪元素,结合动画 animation 和 Vue 动态样式属性(通过 CSS 变量)的写法,来实现电池充电、高能进度条的效果,如下图所示。

二、基础知识

1、CSS 伪类、伪元素

简单概括成以下 4 点:

1、CSS 伪类是对当前元素下,处于某些特定状态时而添加特殊效果的样式(基于文档之外的抽象,所以叫伪类),不同状态可以应用不同的样式。不产生新元素,写法用单冒号(:)开头,比如 :hover、:active、:visited、:first-child 等。

2、CSS 伪元素是对当前元素下,某些特殊部位应用样式,通过创建虚拟元素实现,一般与 content 属性一起使用(基于元素的抽象,所以叫伪元素)。表示文档中不存在实际的元素,写法用双冒号(::)开头,比如 ::before、::after 等。

3、注意的是,单冒号(:)在一些旧版 CSS 中也被用来表示伪元素,这是为了兼容旧的浏览器,但是在最新的 CSS 规范中,建议应该使用双冒号(::)来表示伪元素,与伪类区分开来。

4、灵活应用 CSS 伪类、伪元素可以创建出更丰富的前端页面效果。

更多详细可以参考以下文档链接:

  • 伪元素 - CSS:层叠样式表 | MDN
  • CSS 伪元素 | 菜鸟教程

2、CSS 变量 var()

定义:用于插入自定义属性,如果一个属性在多处被使用,该方法就很有用。

语法:var(custom-property-name, value),参数说明如下表格。

描述
custom-property-name必需。自定义属性的名称,必需以 -- 开头。
value可选。备用值,在属性不存在的时候使用。

详细使用示例:

/* 在 :root 上使用自定义属性,其中 :root 表示文档根元素,该定义将在整个文档内生效 */
:root {--main-bg-color: red;--second-bg-color: var(--main-bg-color); /* 可以继承自其他已定义的变量,称为派生变量 */--main-margin: 20px;
}
#div1 {background-color: var(--main-bg-color); /* 等同于 background-color: red; */--main-txt-color: blue; /* 也可以在局部定义变量 */color: var(--main-txt-color); /* 等同于 color: blue; */
}
#div2 {background-color: var(--second-bg-color); /* 等同于 background-color: red; *//* 如果一个变量未被定义,可以使用回退值来替代 */padding: var(--main-padding, 10px); /* 等同于 padding: 10px; *//* 使用自定义属性作为回退值 */margin: var(--second-margin, var(--main-margin, 30px)); /* 等同于 margin: 20px; 因为 --main-margin 有被设置,所以它的回退值不生效*/
}

CSS 变量可以被 JavaScript 动态修改,根据上面示例来操作,如下代码:

// 语法:DOM.style.setProperty(custom-property-name, value)
document.getElementById('div1').style.setProperty('--main-txt-color', 'green')

三、具体操作实现

    为了节省代码,达到简单实用的目的,本次实例代码采用 Vue2 框架,ElementUI 组件库,搭配 CSS 预处理器 Scss 完成的。

    Scss 写样式能用更简单且高级的写法降低开发成本,比如嵌套规则,父选择器 & 等,如果需要 HTML + CSS + JS 的形式,读者可以自行转化。

实例 1 —— Battery.vue 组件:

  1. 首先通过 CSS 伪元素描画出电池雏形和电池容量,同时加入闪电图标;
  2. 接着实现充电时波浪效果所需的容器,通过 CSS 伪类中的 hover 来实现鼠标悬停时效果;
  3. 然后通过 CSS 伪元素描画出充电时的波浪,让 CSS 伪类 hover 与 CSS 伪元素相结合,并加上动画实现样式效果;
  4. 最后通过 Vue 动态属性 :style 绑定值传入 CSS 中的变量 var() 使用,实现动态变化。更多具体内容查看下面完整代码。
<template><div style="padding: 50px;"><div class="battery" :style="{'--height': `${100 - elecVal || 0}%`}"><img :src="iconUrl" alt="闪电icon"><div class="cover" :style="{'--top': `${0 - elecVal || 0}%`}"></div></div><div style="margin-top: 20px;">当前电量:<el-input-numberv-model="elecVal":min="0":max="100":step="5":precision="2"controls-position="right"style="width: 120px;"></el-input-number>%</div></div>
</template><script>
export default {data() {return {elecVal: 75, // 电池电量iconUrl: 'https://showdoc.keytop.cn/Public/Uploads/2024-04-28/662dbe484313f.png' // 图标线上地址}}
}
</script><style lang="scss" scoped>
.battery { // 电池容器width: 100px;height: 150px;background: rgb(246, 246, 246);border: 1px solid rgb(211, 211, 211);border-radius: 5px; // 大小、背景、边框position: relative; // 后面绝对定位的前提img { // 让闪电图标在电池里水平垂直居中,并处于高层级position: absolute;left: 50%;top: 50%;transform: translate(-50%, -50%);z-index: 100;}&::before { // 伪元素 - 模拟电池正极头content: "";width: 50px;height: 15px;position: absolute;left: 50%;top: -15px;transform: translate(-50%, 0); // 大小,水平居中,垂直定位background: rgb(246, 246, 246);border: 1px solid rgb(211, 211, 211);border-bottom: none;border-radius: 5px 5px 0 0; // 背景、边框}&::after { // 伪元素 - 模拟电量容量content: "";background-color: rgb(68, 220, 148); // 容量颜色position: absolute;left: 0;top: var(--height); // 容量大小,通过值传入动态变化right: 0;bottom: 0;}.cover{ // 充电时波浪效果容器width: 100%;height: 100%;position: absolute;left: 0;top: 0; // 占满整个原电池容器overflow: hidden; // 超出部分隐藏z-index: 10;}&:hover{ // 伪类 - 当鼠标 hover 在电池上时,模拟正在充电的波浪效果.cover::before, .cover::after{ // 伪元素 - 两层波浪content: "";background: rgba(246, 246, 246, 0.8);border-radius: 40% 30%;position: absolute;width: 150px;height: 150px;left: -30%;top: var(--top); // 波浪所处位置,通过值传入动态变化transform: translate(-50%, 0); // 大小,水平居中,垂直定位animation: coverBefore 10s linear infinite; // 通过动画实现波浪}.cover::after{background: rgba(246, 246, 246, 0.6); // 通过背景色深浅来体现出两层效果animation: coverAfter 10s linear infinite;}}
}
// 定义的动画
@keyframes coverBefore {0% {transform: rotate(0deg);}100% {transform: rotate(360deg);}
}
@keyframes coverAfter {0% {transform: rotate(30deg);}100% {transform: rotate(360deg);}
}
</style>

实例 2 —— EnergyProgress.vue 组件:

  1. 首先通过 CSS 描画出进度条容器,设置背景色及背景区域为 content-box;
  2. 接着通过 CSS 伪元素来填充进度条,让其与进度条容器契合,设置相同的 height、padding、background-clip,通过 linear-gradient() 实现填充的渐变颜色;
  3. 然后再通过 CSS 伪元素描画出结尾节点,并对节点的中心点进行定位;
  4. 最后通过 Vue 动态属性 :style 绑定值传入 CSS 中的变量 var() 使用,实现动态变化。更多具体内容查看下面完整代码。
<template><!-- 这里使用该背景色只是为了效果看得更明显而已 --><div style="padding: 50px; background-color: #000; color: #fff;"><div class="energy-progress" :style="{'--width': `${progress || 0}%`}"></div><div style="margin-top: 20px;">当前进度条:<el-input-numberv-model="progress":min="0":max="100":step="5":precision="2"controls-position="right"style="width: 120px;"></el-input-number>%</div></div>
</template><script>export default {data(){return{progress: 66.6, // 进度条值}}}
</script><style lang="scss" scoped>
.energy-progress{ // 进度条容器width: 300px;height: 15px; // 大小background-color: rgb(22, 91, 128);padding: 3px 0;background-clip: content-box; // 缩小容器本身,为了结尾的节点让出空间position: relative; // 后面绝对定位的前提&::before{ // 伪元素 - 已填充进度条的部分content: "";position: absolute;left: 0;top: 0;width: var(--width); // 填充容量,通过值传入动态变化height: 15px;padding: 3px 0;background-clip: content-box; // 为了与进度条容器契合,同理的background-image: linear-gradient(to right, rgb(22, 91, 128) 0%, rgb(97, 177, 242) 70%, #fff 100%); // 进度条填充颜色渐变效果}&::after{ // 伪元素 - 结尾节点content: "";position: absolute;top: 0;left: var(--width); // 根据填充容量定位,通过值传入动态变化width: 6px;height: 15px; // 大小background-color: #fff;border-radius: 5px;margin-left: -3px; // 这个设为宽度一半的负值,让原本是根据左边框对准位置的,这下让其中心对准位置了transform: rotate(30deg);}&:hover{ // 伪类 - 当鼠标 hover 在电池上时,模拟进度条高能效果cursor: pointer;&::before{ // 伪元素 - 宽度填充动画(1 秒完成,且先慢后快)animation: moveBefore 1s;}&::after{ // 伪元素 - 结尾节点填充动画(1 秒完成,且先慢后快)animation: moveAfter 1s;}}
}
// 定义的动画
@keyframes moveBefore {0% {width: 0;}100% {width: var(--width);}
}
@keyframes moveAfter {0% {left: 0;}100% {left: var(--width);}
}
</style>

    这是我本人在工作学习中做的一些总结,同时也分享出来给需要的小伙伴哈 ~ 供参考学习,有什么建议也欢迎评论留言,转载请注明出处哈,感谢支持!

这篇关于CSS 伪类、伪元素的应用实例:电池充电、高能进度条的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/950883

相关文章

Java Stream流之GroupBy的用法及应用场景

《JavaStream流之GroupBy的用法及应用场景》本教程将详细介绍如何在Java中使用Stream流的groupby方法,包括基本用法和一些常见的实际应用场景,感兴趣的朋友一起看看吧... 目录Java Stream流之GroupBy的用法1. 前言2. 基础概念什么是 GroupBy?Stream

python中列表应用和扩展性实用详解

《python中列表应用和扩展性实用详解》文章介绍了Python列表的核心特性:有序数据集合,用[]定义,元素类型可不同,支持迭代、循环、切片,可执行增删改查、排序、推导式及嵌套操作,是常用的数据处理... 目录1、列表定义2、格式3、列表是可迭代对象4、列表的常见操作总结1、列表定义是处理一组有序项目的

C#中的Converter的具体应用

《C#中的Converter的具体应用》C#中的Converter提供了一种灵活的类型转换机制,本文详细介绍了Converter的基本概念、使用场景,具有一定的参考价值,感兴趣的可以了解一下... 目录Converter的基本概念1. Converter委托2. 使用场景布尔型转换示例示例1:简单的字符串到

Spring Boot Actuator应用监控与管理的详细步骤

《SpringBootActuator应用监控与管理的详细步骤》SpringBootActuator是SpringBoot的监控工具,提供健康检查、性能指标、日志管理等核心功能,支持自定义和扩展端... 目录一、 Spring Boot Actuator 概述二、 集成 Spring Boot Actuat

PyTorch中的词嵌入层(nn.Embedding)详解与实战应用示例

《PyTorch中的词嵌入层(nn.Embedding)详解与实战应用示例》词嵌入解决NLP维度灾难,捕捉语义关系,PyTorch的nn.Embedding模块提供灵活实现,支持参数配置、预训练及变长... 目录一、词嵌入(Word Embedding)简介为什么需要词嵌入?二、PyTorch中的nn.Em

MySQL多实例管理如何在一台主机上运行多个mysql

《MySQL多实例管理如何在一台主机上运行多个mysql》文章详解了在Linux主机上通过二进制方式安装MySQL多实例的步骤,涵盖端口配置、数据目录准备、初始化与启动流程,以及排错方法,适用于构建读... 目录一、什么是mysql多实例二、二进制方式安装MySQL1.获取二进制代码包2.安装基础依赖3.清

SpringBoot 异常处理/自定义格式校验的问题实例详解

《SpringBoot异常处理/自定义格式校验的问题实例详解》文章探讨SpringBoot中自定义注解校验问题,区分参数级与类级约束触发的异常类型,建议通过@RestControllerAdvice... 目录1. 问题简要描述2. 异常触发1) 参数级别约束2) 类级别约束3. 异常处理1) 字段级别约束

Apache Ignite缓存基本操作实例详解

《ApacheIgnite缓存基本操作实例详解》文章介绍了ApacheIgnite中IgniteCache的基本操作,涵盖缓存获取、动态创建、销毁、原子及条件更新、异步执行,强调线程池注意事项,避免... 目录一、获取缓存实例(Getting an Instance of a Cache)示例代码:二、动态

Spring Boot3.0新特性全面解析与应用实战

《SpringBoot3.0新特性全面解析与应用实战》SpringBoot3.0作为Spring生态系统的一个重要里程碑,带来了众多令人兴奋的新特性和改进,本文将深入解析SpringBoot3.0的... 目录核心变化概览Java版本要求提升迁移至Jakarta EE重要新特性详解1. Native Ima

从入门到精通详解LangChain加载HTML内容的全攻略

《从入门到精通详解LangChain加载HTML内容的全攻略》这篇文章主要为大家详细介绍了如何用LangChain优雅地处理HTML内容,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录引言:当大语言模型遇见html一、HTML加载器为什么需要专门的HTML加载器核心加载器对比表二