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

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

aa.gif

五角星取自 Element Plus 的 svg 资源

<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>

三种实现方式的 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快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL大小写敏感、MySQL设置字段大小写敏感

文章目录 一、MySQL大小写敏感规则二、设置数据库及表名大小写敏感2.1、查询库名及表名是否大小写敏感2.2、修改库名及表名大小写敏感 三、MySQL列名大小写不敏感四、lower_case_table_name与校对规则4.1、验证校对规则影响大小写敏感4.1、验证校对规则影响排序 五、设置字段内…

Django之图形验证码

Django之图形验证码 目录 Django之图形验证码【1】静态图片【2】视图层绑定静态文件【3】PIL生成图片(固定背景)【4】将图片存储在内存【5】生成文本信息【6】实现图片刷新 【1】静态图片 最基础的生成图片就是获取静态文件 <div style"margin-left: 10px;">…

idea+vim+pycharm的块选择快捷键

平时开发的时候&#xff0c;有的时候我们想用矩形框住代码&#xff0c;或者想在某列上插入相同字符 例如下图所示&#xff0c;我想在22-24行的前面插入0000 1. Idea的快捷键&#xff1a;option 鼠标 2. Pycharm的快捷键&#xff1a;shift option 鼠标 2. Vim 块选择 v/V/c…

Python读取Excel工作表数据写入CSV、XML、文本

Excel工作簿是常用的表格格式&#xff0c;许多数据呈现、数据分析和数据汇报都是以Excel工作表的形式进行。然而&#xff0c;在实际的数据管理、分析或自动化流程构建过程中&#xff0c;我们常常需要将这些Excel中的数据迁移至更其他数据系统&#xff0c;或者以文本形式存储以便…

AI日报:欧盟人工智能法案通过后行业面临合规障碍

文章目录 人工智能新规对web爬网的影响对英国的影响。 人工智能新规 立法者已经通过了欧盟人工智能法案。企业现在必须确保其人工智能应用程序符合规则。 全面的新规定对可能影响公民权利的人工智能系统实施制裁&#xff0c;并有可能彻底禁止某些系统。 违反规定的公司可能面…

4、鸿蒙学习-@ohos.promptAction (弹窗)

创建并显示文本提示框、对话框和操作菜单。 说明 本模块首批接口从API version 9开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 该模块不支持在UIAbility的文件声明处使用&#xff0c;即不能在UIAbility的生命周期中调用&#xff0c;需要在创建…

音频占用磁盘空间太多 需要把mp3音频转aac音频缩小占用空间 应该怎么操作?

一&#xff1a;什么是aac格式&#xff1f; aac是一种音频压缩格式&#xff0c;它是MPEG-2标准下的一种音频压缩方式&#xff0c;也可以作为HE-AAC&#xff0c;AAC或AAC-LC格式使用&#xff0c;是音频压缩领域中的一种重要格式。与MP3的比较&#xff0c;aac在保证音质的同时可以…

C++类与对象二

目录 一、类的嵌套 二、对象引用私有数据成员 通过公有函数为私有成员赋值 利用指针访问私有数据成员 利用函数访问私有数据成员 利用引用访问私有数据成员 三、成员函数重载 四、this指针 一、类的嵌套 #include <iostream> using namespace std;class CC1 { p…

Tomcat会话保持

文章目录 Tomcat会话保持1、代理服务器配置2、web服务器配置3、会话保持3.1 方法一&#xff1a;修改代理服务器配置&#xff08;nginx&#xff09;3.2 方法二&#xff1a;修改web服务器配置&#xff08;tomcat&#xff09;访问官方文档&#xff0c;查看需要添加的配置文件修改t…

C++STL栈与队列的实现

我最近开了几个专栏&#xff0c;诚信互三&#xff01; > |||《算法专栏》&#xff1a;&#xff1a;刷题教程来自网站《代码随想录》。||| > |||《C专栏》&#xff1a;&#xff1a;记录我学习C的经历&#xff0c;看完你一定会有收获。||| > |||《Linux专栏》&#xff1…

【Streamlit学习笔记】实现包含多个sheet的excel文件下载

1、什么是Streamlit Streamlit是一个免费的开源框架&#xff0c;用于快速构建和共享漂亮的机器学习和数据科学Web应用程序&#xff0c;官网链接 Streamlit Streamlit API链接 API reference 实际项目中遇到的问题&#xff1a;包含多个sheet的excel文件下载&#xff0c;下面将给…

STM32初识2

复位和时钟控制&#xff08;RCC&#xff1a;reset clock control&#xff09; 系统复位 当发生以下任一事件时&#xff0c;产生一个系统复位&#xff1a; 1. NRST 引脚上的低电平 ( 外部复位 ) 2. 窗口看门狗计数终止 (WWDG 复位 ) 3. 独立看门狗计数终止 (IWDG 复位 ) …

【JAVA基础】API:Math、System、runtime、object、BigInteger 、BigDecima、爬虫、分组、时间类、包装类

1.Math 2.System public class Main {public static void main(String[] args) {int[] arr {1, 2, 3, 4, 5, 6, 7, 8};int[] arr1 new int[8];System.arraycopy(arr,0,arr1,1,5); // 从1970.1.1开始到现在的毫秒形式long l1 System.currentTimeMillis();//171046475…

HandyControl PropertyGrid及自定义编辑器

前提条件 项目引入对应HandyControl对应版本包。 使用案例 UI部分 <Window xmlns:hc"https://handyorg.github.io/handycontrol"><hc:TabControl><hc:TabItem Header"默认样式"><hc:PropertyGrid Width"380" SelectedO…

huawei services HK华为云服务

huaweiserviceshk是一种云计算服务&#xff0c;为华为云服务用户提供了多种服务&#xff0c;包括云服务器、数据库、存储、网络等&#xff0c;用户可以根据自己的需求选择不同的服务并支付相应的费用 如何付费呢&#xff0c;这里可以使用441112&#xff0c;点击获取 卡片信息在…

swiftUI中的可变属性和封装

swiftUI的可变属性 关于swift中的属性&#xff0c;声明常量使用let &#xff0c; 声明变量使用var 如果需要在swiftUI中更改视图变化那么就需要在 var前面加上state 。 通过挂载到state列表 &#xff0c;从而让xcode找到对应的改变的值 例子&#xff1a; import SwiftUIstruc…

前端组件化:构建高效应用的艺术

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

点的基本操作

点的基本操作 要求 提供空间点数据文本文件&#xff0c;包含ID、name、X、Y四个字段信息&#xff0c; 1&#xff09;读取数据&#xff0c;并且在窗口中显示点的具体位置&#xff0c;用实心圆绘制。 2&#xff09;鼠标任意点击三个点&#xff0c;将点连线&#xff0c;用黑色笔…

微服务技术栈SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式(五):分布式搜索 ES-中

文章目录 一、DSL查询文档1.1 简单查询1.2 复合查询 二、搜索结果处理三、RestClient演示 查询与结果分析四、案例4.1 问题解析4.2 代码4.2.1 实体bean4.2.2 控制层4.2.3 业务service4.2.4 启动类 一、DSL查询文档 1.1 简单查询 # 1. DSL查询 # 1.1 查询所有GET /hotel/_searc…

Github和TeamCity的持续集成构建

一、简介 TeamCity是JetBrains旗下的一款持续集成[Continuous Integration&#xff0c;简称CI]工具&#xff0c;开箱即用。TeamCity提供一系列特性可以让团队快速实现持续集成&#xff1a;IDE工具集成、各种消息通知、各种报表、项目的管理、分布式的编译等等。 二、安装使用(…