CSS 实现带tooltip的slider

现代 CSS 强大的令人难以置信

这次我们来用 CSS 实现一个全功能的滑动输入器,也就是各大组件库都有的slider,效果如下

还可以改变一下样式,像这样

特别是在拖动时,tooltip还能跟随拖动的方向和速度呈现不同的倾斜角度,这些是如何通过CSS实现的呢?一起来看看吧~

一、自定义input range

首先来看滑动输入器的最原始形态

<input type="range">

效果如下

要自定义样式,一般要修改这几个伪元素

::-webkit-slider-container{/*容器*/
}
::-webkit-slider-runnable-track{/*轨道*/
}
::-webkit-slider-thumb{/*手柄*/
}

这里可以很轻松的改变轨道的宽高,拖拽手柄的大小等等

[type="range"] {-webkit-appearance: none;appearance: none;margin: 0;outline: 0;background-color: transparent;width: 400px;overflow: hidden;height: 20px;
}
[type="range"]::-webkit-slider-runnable-track {height: 4px;background: #eee;border-radius: 4px;
}
[type="range"]::-webkit-slider-thumb {-webkit-appearance: none;appearance: none;width: 20px;height: 20px;border-radius: 50%;background-color: #9747FF;transform: translateY(-50%);margin-top: 2px;
}

效果如下

相信大家很容易做到这一步,因为只需要自定义这几个伪元素就行了。

这里还有一个难点,就是左边滑过的区域,如何也自定义颜色呢?毕竟没有专门的选择器(Firefox有,这里主要讨论Chrome),接下来请继续看

二、自定义滑过区域的颜色

在之前,曾经通过border-image实现过类似的效果,主要原理是border-image可以在绘制元素之外,在拖拽手柄左侧绘制一个足够长的条条就行了

不过这种实现有一个局限,由于是通过超出隐藏的方式裁剪掉多出的部分,使得滑动条边缘是“一刀切”的,无法实现圆角

有兴趣的可以回顾之前这篇文章:纯 CSS 美化滑动输入条 input range

回到这里,可以想想,要实现自定义左边滑过区域的样式,本质是需要知道当前的滑动进度,假设进度是--progress,那么轨道滑过区域的背景色可以这样来表示

[type="range"]::-webkit-slider-runnable-track {height: 4px;background: linear-gradient(#9747FF 0 0) 0 0/calc(var(--progress) * 1%) 100% no-repeat #eee;border-radius: 4px;
}

那么,如何实时获取这个进度呢?

在以往,可以借助 JS实时更新这样一个自定义变量,这也是目前最好的实现方式

而现在,有了更好的方式来彻底实现这样一个功能,那就是滚动驱动动画。

CSS 滚动驱动动画终于正式支持了~

有些同学可能无法理解,这里又没有滚动,怎么会和这个特性有关呢?别急,滚动驱动有两种类型,一个是 scroll()、还有一个是view(),我们这里要用到的就是view(),其实也就是利用这一点来监听元素在视区的位置。

具体怎么做呢?

首先,通过@property定义一个CSS变量,整数类型

@property --progress {syntax: "<integer>";initial-value: 0;inherits: true;
}

然后定一个动画,从0100就行了,表示进度

@keyframes slider {to {--progress: 100;}
}

由于是需要监听拖拽手柄,也就是::-webkit-slider-thumb 的位置,所以要给这个伪元素添加view-timeline,但是我们需要通过::-webkit-slider-thumb改变父级轨道::-webkit-slider-runnable-track的样式,所以需要用到time-scope(可以跨层级关联),具体实现如下

[type="range"]{timeline-scope: --slider;animation: slider linear 3s reverse;animation-timeline: --slider;
}
[type="range"]::-webkit-slider-thumb {/**/view-timeline: --slider inline;
}

这样一来,拖拽手柄的位置就通过动画实时映射到了input 上,效果如下

这样就是实现了自定义滑动区域的样式,是不是非常神奇?

三、实时显示滑动进度

由于前面实现了--progress的实时变化,现在展示出来就比较容易了,需要用CSS计数器

为了方便表示,我们可以单独用一个标签来展示进度,结构如下

<label class="slider"><input type="range"><output class="tooltip"></output>
</label>

然后将--progress通过伪元素呈现出来

.tooltip::before{content: counter(num);counter-reset: num var(--progress);
}

效果如下

数字已经可以正常显示了,但是有个问题,起始点不对,不是0100,我们把拖拽手柄透明度降低,可以看到进度其实是这样的

这是由于默认的animation-rangecover,除了这种方式,还有其他几种方式

很明显,我们这里应该需要contain,因为滑块是始终在轨道内的

.slider{position: relative;timeline-scope: --slider;animation: slider linear 3s reverse;animation-timeline: --slider;animation-range: contain; /*设置animation-range*/
}

效果如下

这样进度就正常了

四、tooltip自动跟随滑块

首先美化一下,小三角可以用另一个伪元素实现

.tooltip{position: absolute;margin: 0 0 20px;box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);font-size: 14px;border-radius: 4px;padding: 10px;color: #f0f0f0;background-color: #333;transform-origin: center bottom;filter: drop-shadow(4px 4px 4px rgba(50, 50, 50, 0.3));
}
.tooltip::after{content: "";position: absolute;top: 100%;left: 50%;margin-left: -5px;border-width: 5px;border-style: solid;border-color: black transparent transparent transparent;
}

效果如下

那么,如何让这个tooltip自动跟随滑块呢?

一种方式是直接通过--progress来计算left

.tooltip{position: absolute;left: calc(var(--progress) * 1%);
}

不过这种计算是有偏差的,这是因为定位是相对于轨道位置的,而不是滑块中心

为了修复这个问题,我们可以给input一个负的margin

[type="range"] {/*  */margin: 0 -10px;
}

这样就可以了

不过这样还有有尺寸方面的问题的,如下

除了这种方式,还可以用锚点定位的方式实现,有兴趣可以参考之前这篇文章:CSS 锚点定位终于来了!

实现非常简单,只需要给滑块一个anchor-name

[type="range"]::-webkit-slider-thumb {/**/anchor-name: --thumb;
}

然后给tooltip设置锚点定位

.tooltip{position: absolute;position-anchor: --thumb;inset-area: top;
}

这样就完美实现了,也不用担心定位偏差的问题

五、自动跟随拖拽方向

还有最后一个效果,可以自动跟随拖拽方向,这是如何实现的呢?其实在之前这篇文章中有详细讲解

纯 CSS 检测滚动的速度和方向

具体原理可以回顾这篇文章,这里简单介绍一下

重新定义一个CSS变量

@property --progress2 {syntax: "<integer>";initial-value: 0;inherits: true;
}

然后给这个变量设置为--progress,但是要给一个过渡时间

.tooltip{--progress2: var(--progress);transition: --progress2 .1s ease-out;
}

由于有过渡时间,所以这两个变量就会有一个差值,类似于这样

根据这个差值,我们不就可以知道拖动方向和速度了吗,然后给一个旋转角度

.tooltip{transform-origin: center bottom;rotate: calc((var(--progress2) - var(--progress))*2deg);
}

这样就实现了文章开头所示效果

完整代码可以查看以下链接

  • CSS slider (codepen.io)')点击预览

还可以改变一下样式

[type="range"]::-webkit-slider-runnable-track {height: 20px;background: linear-gradient(#9747FF 0 0) 0 0/calc(var(--progress) * 1% + 20px * (50 - var(--progress))/100) 100% no-repeat #eee;border-radius: 24px;
}
[type="range"]::-webkit-slider-thumb {-webkit-appearance: none;appearance: none;width: 20px;height: 20px;border-radius: 50%;background-color: #fff;border: 3px solid #9747FF;view-timeline: --slider inline;anchor-name: --thumb;
}

这样可以得到下面的效果

完整代码可以查看以下链接

  • CSS custom slider (codepen.io)')点击预览

六、兼容性和总结

这个实现主要依赖于滚动驱动动画,所以兼容性要求Chrome 115+,如果需要tooltip的锚点定位,则需要Chrome 125+,下面总结一下

  1. Chrome 没有专门的选择器来自定义滑过区域的样式
  2. 通过border-image可以自定义滑过区域的样式,但是不能实现圆角
  3. 滚动驱动动画的视图滚动可以监听滑块的位置
  4. 通过CSS变量和滚动驱动动画可以将实时进度传递给轨道,从而通过线性渐变绘制滑过区域颜色
  5. 借助CSS计数器和伪元素可以将CSS变量显示在页面

当然,不兼容的浏览器也可以采用回退措施,比如不支持滚动驱动动画,我们可以用JS来动态赋值--progress变量,不支持锚定定位,我们可以用绝对定位,配合left也能实现,虽然复杂一点,但也是现阶段比较好的处理方式了,剩下的就交给时间吧。

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

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

相关文章

关于SAP Router连接不稳定的改良

这个也是网上看来的&#xff0c;之前在用的时候也在想是不是建立一个长连接&#xff0c;就不至于断线。今天正好看到。 关于SAP Router连接不稳定的改良 我们在使用SAPRouter时经常会碰到断线&#xff0c;其发生原因有很多&#xff0c;如&#xff1a;网络不稳定、操作间隔时间…

docker 搭建自动唤醒UpSnap工具

1、拉取阿里UpSnap镜像 docker pull crpi-k5k93ldwfc7o75ip.cn-hangzhou.personal.cr.aliyuncs.com/upsnap/upsnap:4 2、创建docker-compose.yml文件&#xff0c;进行配置&#xff1a; version: "3" services:upsnap:container_name: upsnapimage: crpi-k5k93ldwf…

Python课设-谁为影狂-豆瓣数据【数据获取与预处理课设】

&#x1f3c6; 作者简介&#xff1a;席万里 ⚡ 个人网站&#xff1a;https://dahua.bloggo.chat/ ✍️ 一名后端开发小趴菜&#xff0c;同时略懂Vue与React前端技术&#xff0c;也了解一点微信小程序开发。 &#x1f37b; 对计算机充满兴趣&#xff0c;愿意并且希望学习更多的技…

STM32 进阶SPI案例1:软件模拟SPI读写FLASH

需求描述 基于寄存器操作&#xff0c;使用软件模拟SPI协议&#xff0c;完成读写FLASH。 硬件电路设计 寄存器代码书写 main.c #include "usart1.h" #include "string.h" #include <stdio.h> #include "m24c02.h" #include "soft_…

Qt WORD/PDF(一)使用 QtPdfium库实现 PDF 预览

文章目录 一、简介二、下载 QtPdfium三、加载 QtPdfium 动态库四、Demo 使用 关于QT Widget 其它文章请点击这里: QT Widget 姊妹篇: Qt WORD/PDF&#xff08;一&#xff09;使用 QtPdfium库实现 PDF 操作 Qt WORD/PDF&#xff08;二&#xff09;使用 QtPdfium库实现…

【SpringCloud】OpenFeign配置时间Decode

文章目录 1.自定义反序列化器2.配置类与自定义 ObjectMapper客户端 需求&#xff1a;OpenFeign配置自定义decode&#xff0c;解析http请求返回的时间字符串 1.自定义反序列化器 Date 自定义反序列化器 import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.j…

java程序设计2(二)

自动装箱和自动拆箱&#xff1a;基本数据类型和包装类型之间可以直接相互转换的包装类通常可以区分有效数据和无效数据&#xff0c;例如&#xff1a;0和nullString类 获取字符串的方式 【企业面试】 String str1 "hello"; 这种获取字符串的方式&#xff0c;在串池…

百度地图JavaScript API核心功能指引

百度地图JavaScript API是一套由JavaScript语言编写的应用程序接口&#xff0c;它能够帮助您在网站中构建功能丰富、交互性强的地图应用&#xff0c;包含了构建地图基本功能的各种接口&#xff0c;提供了诸如本地搜索、路线规划等数据服务。百度地图JavaScript API支持HTTP和HT…

让 Win10 上网本 Debug 模式 QUDPSocket 信号槽 收发不丢包的方法总结

在前两篇文章里&#xff0c;我们探讨了不少UDP丢包的解决方案。经过几年的摸索测试&#xff0c;其实方法非常简单, 无需修改代码。 1. Windows 下设置UDP缓存 这个方法可以一劳永逸解决UDP的收发丢包问题&#xff0c;只要添加注册表项目并重启即可。即使用Qt的信号与槽&#…

【他山之石】Leading-Trim: The Future of Digital Typesetting:数字排版的未来 —— Leading-Trim

文章目录 【他山之石】Leading-Trim: The Future of Digital Typesetting&#xff1a;数字排版的未来 —— Leading-TrimHow an emerging CSS standard can fix old problems and raise the bar for web apps1. The problem with text boxes today2. How we got here: a histor…

MySQL基础大全(看这一篇足够!!!)

文章目录 前言一、初识MySQL1.1 数据库基础1.2 数据库技术构成1.2.1 数据库系统1.2.2 SQL语言1.2.3 数据库访问接口 1.3 什么是MySQL 二、数据库的基本操作2.1 数据库创建和删除2.2 数据库存储引擎2.2.1 MySQL存储引擎简介2.2.2 InnoDB存储引擎2.2.3 MyISAM存储引擎2.2.4 存储引…

uniapp/HBuilder X引入weex报错weex is not defined

出现错误&#xff1a; ‍[⁠ReferenceError⁠]‍ {message: "weex is not defined"} 在www.iconfont.cn把想要的图标放进个人项目中并且下载css文件&#xff1a; 进入HBuilder自己创建的项目中添加一个目录common&#xff0c;添加一个文件free-icon.css 把刚才下载…

Python随机抽取Excel数据并在处理后整合为一个文件

本文介绍基于Python语言&#xff0c;针对一个文件夹下大量的Excel表格文件&#xff0c;基于其中每一个文件&#xff0c;随机从其中选取一部分数据&#xff0c;并将全部文件中随机获取的数据合并为一个新的Excel表格文件的方法。 首先&#xff0c;我们来明确一下本文的具体需求。…

【数据分析】表结构数据特征、获取、使用

文章目录 表结构数据事实表及维度表表结构数据特征-1表结构数据特征-2处理缺失值-1表结构数据特征-3确定主键的方法“应用”表格结构数据、“引用”表结构数据关系型数据库管理系统商业智能系统-BIETL功能数据仓库 - DWOLAP表结构数据的横向合并表结构数据的横向合并1表结构数据…

【计算机网络】Layer4-Transport layer

目录 传输层协议How demultiplexing works in transport layer&#xff08;传输层如何进行分用&#xff09;分用&#xff08;Demultiplexing&#xff09;的定义&#xff1a;TCP/UDP段格式&#xff1a; UDPUDP的特点&#xff1a;UDP Format端口号Trivial File Transfer Protocol…

深入剖析MyBatis的架构原理

架构设计 简要画出 MyBatis 的架构图 >> ​​ Mybatis 的功能架构分为哪三层&#xff1f; API 接口层 提供给外部使用的接口 API&#xff0c;开发人员通过这些本地 API 来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。MyBatis 和数据库的…

CTF 攻防世界 Web: FlatScience write-up

题目名称-FlatScience 网址 index 目录中没有发现提示信息&#xff0c;链接会跳转到论文。 目前没有发现有用信息&#xff0c;尝试目录扫描。 目录扫描 注意到存在 robots.txt 和 login.php。 访问 robots.txt 这里表明还存在 admin.php admin.php 分析 在这里尝试一些 sql…

智能客户服务:科技赋能下的新体验

在当今这个数字化时代&#xff0c;客户服务已经不仅仅是简单的售后服务&#xff0c;它已竞争的关键要素之一。随着人工智能、大数据、云计算等技术的飞速发展&#xff0c;智能客户服务正逐步改变着传统的服务模式&#xff0c;为企业和消费者带来了前所未有的新体验。 一、智能客…

发布/部署WebApi服务器(IIS+.NET8+ASP.NETCore)

CS软件授权注册系统-发布/部署WebApi服务器(IIS.NET8ASP.NETCore) 目录 本文摘要VS2022配置发布VS2022发布WebApiIIS服务器部署WebApi 将程序文件复制到云服务器添加网站配置应用程序池配置dns域名配置端口阿里云ECS服务器配置19980端口配置https协议 (申请ssl证书)测试WebAp…

安卓 文件管理相关功能记录

文件管理细分为图片、视频、音乐、文件四类 目录 权限 静态声明权限 动态检查和声明权限方法 如何开始上述动态申请的流程 提示 图片 获取图片文件的对象列表 展示 删除 视频 获取视频文件的对象列表 获取视频file列表 按日期装载视频文件列表 展示 播放 删除…