三种方式使用纯 CSS 实现星级评分

本文介绍三种使用纯 CSS 实现星级评分的方式。每种都值得细品一番~

aa.gif

五角星取自 Element Plus 的 svg 资源

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" style=""><pathfill="currentColor"d="M283.84 867.84 512 747.776l228.16 119.936a6.4 6.4 0 0 0 9.28-6.72l-43.52-254.08 184.512-179.904a6.4 6.4 0 0 0-3.52-10.88l-255.104-37.12L517.76 147.904a6.4 6.4 0 0 0-11.52 0L392.192 379.072l-255.104 37.12a6.4 6.4 0 0 0-3.52 10.88L318.08 606.976l-43.584 254.08a6.4 6.4 0 0 0 9.28 6.72z"></path>
</svg>

三种实现方式的 html 结构是一样的

<div><input type="radio" name="radio" id="radio1"><label for="radio1"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" style=""><path fill="currentColor" d="M283.84 867.84 512 747.776l228.16 119.936a6.4 6.4 0 0 0 9.28-6.72l-43.52-254.08 184.512-179.904a6.4 6.4 0 0 0-3.52-10.88l-255.104-37.12L517.76 147.904a6.4 6.4 0 0 0-11.52 0L392.192 379.072l-255.104 37.12a6.4 6.4 0 0 0-3.52 10.88L318.08 606.976l-43.584 254.08a6.4 6.4 0 0 0 9.28 6.72z"></path></svg></label><input type="radio" name="radio" id="radio2"><label for="radio2"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" style=""><path fill="currentColor" d="M283.84 867.84 512 747.776l228.16 119.936a6.4 6.4 0 0 0 9.28-6.72l-43.52-254.08 184.512-179.904a6.4 6.4 0 0 0-3.52-10.88l-255.104-37.12L517.76 147.904a6.4 6.4 0 0 0-11.52 0L392.192 379.072l-255.104 37.12a6.4 6.4 0 0 0-3.52 10.88L318.08 606.976l-43.584 254.08a6.4 6.4 0 0 0 9.28 6.72z"></path></svg></label><input type="radio" name="radio" id="radio3"><label for="radio3"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" style=""><path fill="currentColor" d="M283.84 867.84 512 747.776l228.16 119.936a6.4 6.4 0 0 0 9.28-6.72l-43.52-254.08 184.512-179.904a6.4 6.4 0 0 0-3.52-10.88l-255.104-37.12L517.76 147.904a6.4 6.4 0 0 0-11.52 0L392.192 379.072l-255.104 37.12a6.4 6.4 0 0 0-3.52 10.88L318.08 606.976l-43.584 254.08a6.4 6.4 0 0 0 9.28 6.72z"></path></svg></label><input type="radio" name="radio" id="radio4"><label for="radio4"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" style=""><path fill="currentColor" d="M283.84 867.84 512 747.776l228.16 119.936a6.4 6.4 0 0 0 9.28-6.72l-43.52-254.08 184.512-179.904a6.4 6.4 0 0 0-3.52-10.88l-255.104-37.12L517.76 147.904a6.4 6.4 0 0 0-11.52 0L392.192 379.072l-255.104 37.12a6.4 6.4 0 0 0-3.52 10.88L318.08 606.976l-43.584 254.08a6.4 6.4 0 0 0 9.28 6.72z"></path></svg></label><input type="radio" name="radio" id="radio5"><label for="radio5"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" style=""><path fill="currentColor" d="M283.84 867.84 512 747.776l228.16 119.936a6.4 6.4 0 0 0 9.28-6.72l-43.52-254.08 184.512-179.904a6.4 6.4 0 0 0-3.52-10.88l-255.104-37.12L517.76 147.904a6.4 6.4 0 0 0-11.52 0L392.192 379.072l-255.104 37.12a6.4 6.4 0 0 0-3.52 10.88L318.08 606.976l-43.584 254.08a6.4 6.4 0 0 0 9.28 6.72z"></path></svg></label>
</div>

利用 radio + label 的方式实现点击效果;将 label 的 for 属性保持和 radio 的 id 一致,并将 radio 框隐藏,这样点击 label 就是点击 radio 了;label 在这里就是每个星星;

html,body{width:100%;height:100%;
}
body{display:flex;justify-content:center;align-items:center;
}
div{display : flex;justify-content:center;align-items:center;
}div input{display:none;
}div label{width:50px;height:50px;padding:0 4px;color:#ccc;cursor:pointer;
}

html 布局效果如下:

image.png

通常星级评分效果包括鼠标滑入和点击,滑入或点击到第几颗星的位置,该位置之前的星高亮,之后的星不高亮或者有高亮的则取消高亮;

接下来分别阐述三种 CSS 实现方式;

1、:has()选择器 + input:checked

当点击星星时,高亮当前星星

input:checked + label{color:gold;
}

input:checked + label 表示 选择紧挨着已选中 input 框的后面一个 label;

当鼠标移入星星时,高亮当前星星,并且该位置之后的星星取消高亮;

label:hover{cursor:pointer;color:gold;& ~ label{color:#ccc!important;}
}

那么如何让该位置之前的星星也高亮呢,目前的兄弟选择器包括 + 和 ~ ,但都不能选择之前的兄弟元素;此时 :has() 选择器就登场了;

:has() 提供了一种针对引用元素选择父元素或者先前的兄弟元素的方法。

比如:

a:has(p) 表示选择包含子元素 p 的 a 元素;

a:has(> p) 表示选择有直接后代 p 元素的 a 元素,也就是 p 只能是 a 的 "儿子" 元素;

a:has(+ p) 表示选择后面紧跟着的兄弟元素是 p 的 a 元素;

所以回到上面问题,当鼠标移入星星时,让该位置之前的所有星星也高亮,可以这么做

div:has(label:hover) label:not(:hover,:hover ~ *){color:gold;
}

label:not(:hover,:hover ~ *) 表示排除当前 hover 的 label 和之后的所有元素;也就自然选择了前面所有星星;

bb.gif

同样,当点击星星时,点亮当前选择的之前所有的星星也如此

div:has(input:checked) label:not(input:checked ~ label){color:gold;
}

div:has(input:checked) 表示选择包含被选中的 input 的 div;

label:not(input:checked ~ label) 表示排除当前选中的 input 后面的所有 label,也就选择到前面所有的 label 了;

完整示例

cc.gif

2、:indeterminate + input:checked 巧妙实现

这种实现的思路是,假设初始所有的星星都是高亮的,鼠标移入或点击时保持前面星星的高亮,取消后面星星的高亮;

div label{width:50px;height:50px;padding:0 4px;color:gold;  => 默认星星高亮cursor:pointer;
}

然后当鼠标移入或点击时,取消该位置后面的星星的高亮

div input:checked ~ input + label,
div label:hover ~ label{color:#ccc;
}

gg.gif

但一开始默认设置的星星是高亮的,但页面上并不想在 radio 未被选中时高亮,这时 :indeterminate 就登场了;

:indeterminate表示任意的状态不确定的表单元素。对于 radio 元素,:indeterminate 表示当表单中具有相同名称值的所有单选按钮均未被选中时。

所以这里设置每个星星在对应的 radio 的未被选中时非高亮;并且只是在初始状态,鼠标移入时这种初始状态就应该被改变

div:not(:hover) input:indeterminate + label,
div:not(:hover) input:checked ~ input + label,
div input:hover ~ input + label{color:#ccc;
}

:not() 表示用来匹配不符合一组选择器的元素;div:not(:hover) 表示鼠标移入时,不匹配这行规则,这样在初始状态下或者在鼠标点击星星后,鼠标移入仍然会高亮当前点击位置之前的星星;

这样效果就达到了;

完整示例

cc.gif

3、flex-direction:row-reverse; + input:checked 巧妙实现

目前 html 布局是从左到右布局,但如果我们倒过来呢,从右到左布局;

div{width:300px;display:flex;/* 从右往左排列 */flex-direction:row-reverse;justify-content:space-around;
}

dd.png

那么之前利用 :has() 选择之前的兄弟元素现在就可以直接用 ~ 来选择了;

// 之前
label:not(input:checked ~ label){color:gold;
}// 现在
label:hover ~ label{color:gold;
}

dd.gif

点击星星也是

input:checked ~ label{color:gold;
}

但是这样还不够完善

ee.gif

当我们点击第二颗星星时,鼠标滑入到第三个星星,第二颗星星并没有取消高亮,所以这里还是得借助下 :has()

label:has(~ label:hover){color:#ccc;
}

上面表示选择后面被 hover 的兄弟元素的元素,也就是 hover 元素的前面的所有元素;这样就没问题了;

完整示例

ff.gif

总结

以上使用了三种纯 css 实现星级评分的方式;

  • :has()选择器 + input:checked

  • :not()选择器 + input:checked

  • flex-direction:row-reverse; + input:checked 巧妙实现

特别是 :has() 选择器可以选择之前的兄弟元素,搭配 :not() 能发挥很多作用,以前很多需要用 js 实现的效果或许现在可以用 :has() 来试试了;

附上 :has() 和 :not() 的兼容性截图

:has()

:not()

文章转载自:xingba-coder

原文链接:https://www.cnblogs.com/zsxblog/p/18072530

体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

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

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

相关文章

分析型数据库的主要使用场景有哪些?

如今数据已经成为了企业和组织的核心资产。如何有效地管理和利用这些数据&#xff0c;成为了决定竞争力的关键。分析型数据库作为数据处理领域的重要工具&#xff0c;为各行各业提供了强大的数据分析和洞察能力。基于分析型数据库&#xff08;Apache Doris &#xff09;构建的现…

【机器学习】机器学习创建算法第2篇:K-近邻算法【附代码文档】

机器学习&#xff08;算法篇&#xff09;完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;机器学习算法课程定位、目标&#xff0c;K-近邻算法&#xff0c;1.1 K-近邻算法简介&#xff0c;1.2 k近邻算法api初步使用定位,目标,学习目标,1 什么是K-近邻算法,…

Trie树(详解+例题)

1、介绍Trie树 Trie树&#xff0c;即字典树&#xff0c;又称单词查找树或键树&#xff0c;是一种树形结构&#xff0c;每个节点保存一个字符&#xff0c;一条路径表示一个字符串。它的优点是&#xff1a;利用字符串的公共前缀来减少查询时间&#xff0c;最大限度地减少无谓的字…

Java代码审计安全篇-反序列化漏洞

前言&#xff1a; 堕落了三个月&#xff0c;现在因为被找实习而困扰&#xff0c;着实自己能力不足&#xff0c;从今天开始 每天沉淀一点点 &#xff0c;准备秋招 加油 注意&#xff1a; 本文章参考qax的网络安全java代码审计和部分师傅审计思路以及webgoat靶场&#xff0c;记录…

ASP.NET Mvc+FFmpeg+Video实现视频转码

目录 首先&#xff0c;做了视频上传的页面&#xff1a; FFmpeg&#xff1a;视频转码 FFmpegHelper工作类&#xff1a; 后台控制器代码&#xff1a; 前端视图代码&#xff1a; 参考文章&#xff1a; 首先&#xff0c;做了视频上传的页面&#xff1a; 借鉴了这篇文章 ASP.…

【Miniconda】基于conda列出当前环境下所有已创建的虚拟环境

【Miniconda】基于conda列出当前环境下所有已创建的虚拟环境 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望得到您的…

代理IP速度变慢的原因是什么,要如何解决?

许多用户在使用代理IP时都可能会遇到网络速度变慢的问题&#xff0c;这和我们很多人使用代理IP的初衷背道而驰了&#xff0c;所以&#xff0c;代理IP的网络延迟到底是什么原因造成的&#xff0c;我们又要如何解决这个问题呢&#xff1f;今天就和大家一起来探讨探讨。 一、原因 …

C#,图论与图算法,无向图断开点(Articulation Points)的算法与源代码

1 无向图断开点 如果移除无向连通图中的顶点(以及穿过该顶点的边)会断开该图,则该顶点是一个连接点(或切割顶点Cutting Point)。连接点表示连接网络中的漏洞–单点故障会将网络拆分为两个或多个组件。它们对于设计可靠的网络很有用。 对于断开连接的无向图,连接点是顶点…

SSM SpringBoot vue智能手机参数分析平台

SSM SpringBoot vue智能手机参数分析平台 系统功能 首页 图片轮播 新闻资讯 手机信息 手机百科 登录注册 个人中心 后台管理 登录注册 个人中心 手机百科管理 用户管理 手机对比管理 配置管理 新闻资讯管理 手机信息管理 对比信息管理 我的收藏管理 开发环境和技术 开发语言…

【New Release】PostgreSQL小版本(16.2, 15.6, 14.11, 13.14,12.18) 发布了

前言 PostgreSQL遵循小版本的发布规律&#xff0c;这一个季度的小版本又发布了。可以算作是2024年第一个季度的版本发布。如果总结其规律&#xff1a;大概就是2月、5月、8月、11月的样子。通常因为11月配合大版本的发布&#xff0c;它是起点&#xff0c;也有可能就是终点。起点…

KKVIEW远程控制: 比TODESK好用的软件

比ToDesk更好用的软件&#xff1a;探索远程桌面工具的新选择 在数字化时代&#xff0c;远程桌面工具已经成为许多个人和企业用户不可或缺的一部分。这类工具使得用户可以从一个设备远程控制另一个设备&#xff0c;无论它们相隔多远。其中&#xff0c;ToDesk是一款广受欢迎的远…

微信小程序--开启下拉刷新页面

1、下拉刷新获取数据enablePullDownRefresh 开启下拉刷新&#xff1a; enablePullDownRefreshbooleanfalse是否开启当前页面下拉刷新 案例&#xff1a; 下拉刷新&#xff0c;获取新的列表数据,其实就是进行一次新的网络请求&#xff1a; 第一步&#xff1a;在.json文件中开…