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>

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/5459.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

谷粒商城实战(020 RabbitMQ-消息确认)

Java项目《谷粒商城》架构师级Java项目实战&#xff0c;对标阿里P6-P7&#xff0c;全网最强 总时长 104:45:00 共408P 此文章包含第258p-第p261的内容 消息确认 生产者 publishers 消费者 consumers 设置配置类 调用api 控制台 抵达brocker 代理 新版本ReturnCallbac…

DevEco Studio mac版启动不了【鸿蒙开发Bug已解决】

文章目录 项目场景:问题描述原因分析:解决方案:此Bug解决方案总结Bug解决方案寄语项目场景: 最近也是遇到了这个问题,看到网上也有人在询问这个问题,本文总结了自己和其他人的解决经验,解决了【DevEco Studio mac版启动不了】的问题。 问题描述 报错如下。 -------…

如何判断第三方软件测试公司是否具有资质

在软件开发的过程中&#xff0c;软件测试是确保软件质量、稳定性和用户体验的关键环节。许多企业选择将软件测试工作交给专业的第三方软件测试公司来完成&#xff0c;以确保测试的准确性和公正性。但是&#xff0c;如何判断一个第三方软件测试公司是否具有资质呢&#xff1f;以…

Python urllib 爬虫入门(2)

本文为Python urllib类库爬虫更入门的一些操作和爬虫实例及源码。 目录 模拟浏览器请求 简单模拟 设置随机user-agent 请求超时 HTTP请求类型 Get请求 Post请求 抓取网页动态请求 封装ajax请求 调用 循环调用 抓取小说 封装请求函数 把html写入本地分析 调用 正…

2024年Docker常用操作快速查询手册

目录 一、Linux系统上 Docker安装流程&#xff08;以ubuntu为例&#xff09; 一、卸载所有冲突的软件包 二、设置Docker的apt存储库&#xff08;这里使用的是阿里云软件源&#xff09; 三、直接安装最新版本的Docker 三、安装指定版本的Docker 四、验证Docker是否安装成功…

Linux 手动部署JDK21 环境

1、下载包&#xff08;我下载的是tar) https://www.oracle.com/cn/java/technologies/downloads/#java21 完成后进行上传 2、检查已有JDK&#xff0c;并删除&#xff08;我原有是jdk8&#xff09; rpm -qa | grep -i java | xargs -n1 rpm -e --nodeps3、清理掉 profile中的j…

Mybatis-Plus扩展接口InnerInterceptor

InnerInterceptor 接口就是 MyBatis-Plus 提供的一个拦截器接口&#xff0c;用于实现一些常用的 SQL 处理逻辑&#xff0c;处理 MyBatis-Plus 的特定功能,例如PaginationInnerInterceptor、OptimisticLockerInnerInterceptor 等,都实现了 InnerInterceptor 接口&#xff0c;并添…

Vue项目打包APK----Vue发布App

时隔多年我又来跟新了&#xff0c;今天给大普家及下前端Vue傻瓜式发布App&#xff0c;话不多说直接上干货。 首先准备开发工具HBuilder X&#xff0c;去官网直接下载即可&#xff0c;算了直接给你们上地址吧HBuilderX-高效极客技巧。 打开软件&#xff0c;文件-->新建--&g…

【XR806开发板试用】基于XR806实现智能小车

一、实验功能&#xff1a; 1、 基于XR806实现WIFI连接路由器 2、 XR806设备创建TCP socket服务器&#xff0c;局域网内通过PC端TCP客服端连接XR806 TCP服务器进行指令控制小车运行&#xff08;指令&#xff21;&#xff1a;前进、&#xff22;&#xff1a;后退、&#xff23;&…

实验15 MVC

二、实验项目内容&#xff08;实验题目&#xff09; 编写代码&#xff0c;掌握MVC的用法。 三、源代码以及执行结果截图&#xff1a; inputMenu.jsp&#xff1a; <% page contentType"text/html" %> <% page pageEncoding "utf-8" %> &…

Nginx配置Https缺少SSL模块

1、Linux下Nginx配置https nginx下载和安装此处就忽略&#xff0c;可自行百度 1.1、配置https 打开nginx配置文件 vim /opt/app/nginx/conf/nginx.conf相关https配置 server {listen 443 ssl; #开放端口server_name echarts.net;#域名#redirect to https#ssl on; #旧版#ssl证…

C语言-嵌入式-STM32:FreeRTOS说明和详解

Free即免费的&#xff0c;RTOS的全称是Real time operating system&#xff0c;中文就是实时操作系统。 注意&#xff1a;RTOS不是指某一个确定的系统&#xff0c;而是指一类操作系统。比如&#xff1a;uc/OS&#xff0c;FreeRTOS&#xff0c;RTX&#xff0c;RT-Thread 等这些都…

应用监控(Prometheus + Grafana)

可用于应用监控的系统有很多&#xff0c;有的需要埋点(切面)、有的需要配置Agent(字节码增强)。现在使用另外一个监控系统 —— Grafana。 Grafana 监控面板 这套监控主要用到了 SpringBoot Actuator Prometheus Grafana 三个模块组合的起来使用的监控。非常轻量好扩展使用。…

JDK-Mac系统和Windows系统安装及Java版本新特性(java9 - java19)

过去岁月不可追&#xff0c; 未来日子要珍惜。 莫愁身外七八事&#xff0c; 且尽眼前两三杯。 当你纠结于过去之时&#xff0c;懊恼与悔恨难免会让你陷入不欢。 当你忧愁于未来之时&#xff0c;未知与不安又会逐渐侵蚀你的心灵。 勿要纠结于过去&#xff0c;勿要忧愁于未来&…

使 Elasticsearch 和 Lucene 成为最佳向量数据库:速度提高 8 倍,效率提高 32 倍

作者&#xff1a;来自 Elastic Mayya Sharipova, Benjamin Trent, Jim Ferenczi Elasticsearch 和 Lucene 成绩单&#xff1a;值得注意的速度和效率投资 我们 Elastic 的使命是将 Apache Lucene 打造成最佳的向量数据库&#xff0c;并继续提升 Elasticsearch 作为搜索和 RAG&a…

透视天气:数据可视化的新视角

数据可视化在天气方面能够为我们带来极大的帮助。天气是人类生活中一个重要的因素&#xff0c;对于农业、交通、航空、能源等各个领域都有着重要的影响。而数据可视化技术通过将复杂的天气数据转化为直观、易懂的图表、图像或地图等形式&#xff0c;为我们提供了更深入、更全面…

如何提升制造设备文件汇集的可靠性和安全性?

制造设备文件汇集通常指的是将与制造设备相关的各种文档和资料进行整理和归档的过程。这些文件可能包括但不限于&#xff1a; 生产数据&#xff1a;包括生产计划、订单信息、生产进度等。 设计文件&#xff1a;如CAD图纸、设计蓝图、产品模型等。 工艺参数&#xff1a;用于指…

PaddlePaddle与OpenMMLab

产品全景_飞桨产品-飞桨PaddlePaddle OpenMMLab算法应用平台

AnyMP4 Blu-ray Ripper for Mac:您的蓝光影音转换专家

AnyMP4 Blu-ray Ripper for Mac&#xff0c;一款功能强大的蓝光影音转换软件&#xff0c;让您的蓝光内容焕发新生。 AnyMP4 Blu-ray Ripper for Macv9.0.58激活版下载 它采用最高效的解决方案&#xff0c;将蓝光光盘翻录为任何您想要的视频格式&#xff0c;无论是MP4、MKV还是A…

【Excel】excel计算相关性系数R、纳什效率系数NSE、Kling-Gupta系数KGE

对于采用的数据&#xff1a; B2:B10958是观测值的所在范围 C2:C10958是模型计算值的所在范围 一、相关系数R是用来衡量两个变量之间线性关系强度和方向的统计量。在水文学和气象学中&#xff0c;常用的相关系数是皮尔逊相关系数&#xff08;Pearson correlation coefficient&am…