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.hqwc.cn/news/660653.html

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

相关文章

nginx缓存清理

背景 昨天打开我的gpt镜像网站&#xff0c;意外发现静态图片资源全都无法获取了 CoCo-AI 一番排查下来&#xff0c;发现是引用的cdn链接失效了 且cdn源是属于七牛云的&#xff0c;且不再维护&#xff0c;于是果断切换到cloudflare export function getEmojiUrl(unified: str…

nuxt3项目服务端bulid后在本地浏览的3种方式(nuxi preview、Node.js Server、PM2)

你也许会问有了开发调试本地浏览&#xff0c;为什么还要服务端构建之后在本地浏览&#xff1f; 举个简单例子 在 Nuxt 3 服务端打包中&#xff0c;由于运行环境不同&#xff0c;无法直接访问 process 对象。服务端打包通常是在 Node.js 环境中进行的&#xff0c;而 process 对象…

吴恩达深度学习笔记:深度学习的 实践层面 (Practical aspects of Deep Learning)1.11-1.12

目录 第二门课: 改善深层神经网络&#xff1a;超参数调试、正 则 化 以 及 优 化 (Improving Deep Neural Networks:Hyperparameter tuning, Regularization and Optimization)第一周&#xff1a;深度学习的 实践层面 (Practical aspects of Deep Learning)1.11 神经网络的权重…

【记录】Python3| 将 PDF 转换成 HTML/XML(✅⭐pdfminer.six)

本文将会被汇总至 【记录】Python3&#xff5c;2024年 PDF 转 XML 或 HTML 的第三方库的使用方式、测评过程以及对比结果&#xff08;汇总&#xff09;&#xff0c;更多其他工具请访问该文章查看。 注意&#xff01;pdfminer.six 和 pdfminer3k 不是同一个&#xff01;&#xf…

区块链 | 由外部实体导致的 NFT 安全问题

&#x1f98a;原文&#xff1a; Understanding Security Issues in the NFT Ecosystem &#x1f98a;警告&#xff1a; 本文只记录了原文的第 6 节。 1 问题描述 NFT 所指向的数字资产&#xff08;图片、视频等&#xff09;必须是可以访问的&#xff0c;这样 NFT 才具有意义…

Threejs制作服务器机房冷却结构

这节再绘制一个机房的结构&#xff0c;因为内容比较简单&#xff0c;就只使用一个章节来介绍&#xff0c; 先来一张效果图&#xff0c; 需要两个模型&#xff1a;一个冷却设备&#xff0c;一个服务器机箱&#xff0c;我这里是从网上找来的&#xff0c;首先我们搭建一个场景&a…

k8s环境prometheus operator监控集群外资源

文章目录 k8s环境添加其他节点基于prometheus operator k8s环境prometheus operator添加node-exporter方式一&#xff1a;通过 ServiceMonitor 方式可以写多个监控node节点运行 external-node.yaml查看资源有没有被创建热更新 外部需要被监控服务器安装 node-exporterdocker 方…

Stm32CubeMX 为 stm32mp135d 添加网卡 eth

Stm32CubeMX 为 stm32mp135d 添加网卡 eth 一、启用设备1. eth 设备添加2. eth 引脚配置2. eth 时钟配置 二、 生成代码1. optee 配置2. uboot 配置3. linux 配置 bringup 可参考&#xff1a;Stm32CubeMX 生成设备树 一、启用设备 1. eth 设备添加 我这里只启用一个eth设备&…

关于下载上传的sheetjs

一、背景 需要讲后端返回来的表格数据通过前端设置导出其中某些字段&#xff0c;而且得是xlsx格式的。 那就考虑使用控件SheetJS。如果是几年前&#xff0c;一般来说&#xff0c;保存excel的文件都是后端去处理&#xff0c;处理完成给前端一个接口&#xff0c;前端调用了打开…

Postgresql源码(127)投影ExecProject的表达式执行分析

无论是投影还是别的计算&#xff0c;表达式执行的入口和计算逻辑都是统一的&#xff0c;这里已投影为分析表达式执行的流程。 1 投影函数 用例 create table t1(i int primary key, j int, k int); insert into t1 select i, i % 10, i % 100 from generate_series(1,1000000…

国家开放大学2024年春《Matlab语言及其应用》实验五Simulink系统 建模与仿真参考答案

答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 实验报告 姓名&#xff1a; 学号&#xff1a; 实验五名称…

数据挖掘之基于Lightgbm等多模型消融实验的信用欺诈检测实现

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 在当前的金融环境中&#xff0c;信用欺诈行为日益增多&#xff0c;给金融机构和消费者带来了巨大的损…