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

相关文章

在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码

《在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码》在MyBatis的XML映射文件中,trim元素用于动态添加SQL语句的一部分,处理前缀、后缀及多余的逗号或连接符,示... 在MyBATis的XML映射文件中,<trim>元素用于动态地添加SQL语句的一部分,例如SET或W

Java操作ElasticSearch的实例详解

《Java操作ElasticSearch的实例详解》Elasticsearch是一个分布式的搜索和分析引擎,广泛用于全文搜索、日志分析等场景,本文将介绍如何在Java应用中使用Elastics... 目录简介环境准备1. 安装 Elasticsearch2. 添加依赖连接 Elasticsearch1. 创

使用C#代码计算数学表达式实例

《使用C#代码计算数学表达式实例》这段文字主要讲述了如何使用C#语言来计算数学表达式,该程序通过使用Dictionary保存变量,定义了运算符优先级,并实现了EvaluateExpression方法来... 目录C#代码计算数学表达式该方法很长,因此我将分段描述下面的代码片段显示了下一步以下代码显示该方法如

将Python应用部署到生产环境的小技巧分享

《将Python应用部署到生产环境的小技巧分享》文章主要讲述了在将Python应用程序部署到生产环境之前,需要进行的准备工作和最佳实践,包括心态调整、代码审查、测试覆盖率提升、配置文件优化、日志记录完... 目录部署前夜:从开发到生产的心理准备与检查清单环境搭建:打造稳固的应用运行平台自动化流水线:让部署像

vue解决子组件样式覆盖问题scoped deep

《vue解决子组件样式覆盖问题scopeddeep》文章主要介绍了在Vue项目中处理全局样式和局部样式的方法,包括使用scoped属性和深度选择器(/deep/)来覆盖子组件的样式,作者建议所有组件... 目录前言scoped分析deep分析使用总结所有组件必须加scoped父组件覆盖子组件使用deep前言

VUE动态绑定class类的三种常用方式及适用场景详解

《VUE动态绑定class类的三种常用方式及适用场景详解》文章介绍了在实际开发中动态绑定class的三种常见情况及其解决方案,包括根据不同的返回值渲染不同的class样式、给模块添加基础样式以及根据设... 目录前言1.动态选择class样式(对象添加:情景一)2.动态添加一个class样式(字符串添加:情

Python中实现进度条的多种方法总结

《Python中实现进度条的多种方法总结》在Python编程中,进度条是一个非常有用的功能,它能让用户直观地了解任务的进度,提升用户体验,本文将介绍几种在Python中实现进度条的常用方法,并通过代码... 目录一、简单的打印方式二、使用tqdm库三、使用alive-progress库四、使用progres

Linux中Curl参数详解实践应用

《Linux中Curl参数详解实践应用》在现代网络开发和运维工作中,curl命令是一个不可或缺的工具,它是一个利用URL语法在命令行下工作的文件传输工具,支持多种协议,如HTTP、HTTPS、FTP等... 目录引言一、基础请求参数1. -X 或 --request2. -d 或 --data3. -H 或

在Ubuntu上部署SpringBoot应用的操作步骤

《在Ubuntu上部署SpringBoot应用的操作步骤》随着云计算和容器化技术的普及,Linux服务器已成为部署Web应用程序的主流平台之一,Java作为一种跨平台的编程语言,具有广泛的应用场景,本... 目录一、部署准备二、安装 Java 环境1. 安装 JDK2. 验证 Java 安装三、安装 mys

Python中构建终端应用界面利器Blessed模块的使用

《Python中构建终端应用界面利器Blessed模块的使用》Blessed库作为一个轻量级且功能强大的解决方案,开始在开发者中赢得口碑,今天,我们就一起来探索一下它是如何让终端UI开发变得轻松而高... 目录一、安装与配置:简单、快速、无障碍二、基本功能:从彩色文本到动态交互1. 显示基本内容2. 创建链