搜索
首页web前端css教程仅CSS的星级等级组件等等! (第1部分)

A CSS-Only Star Rating Component and More! (Part 1)

构建星级评分组件是Web开发中的经典练习,已使用多种技术反复实现。通常需要少量JavaScript代码,但仅使用CSS实现呢?是的,可以!

这是一个仅使用CSS实现的星级评分组件演示。您可以点击更新评分。

很酷,对吧?除了仅使用CSS外,HTML代码只是一个单一元素:

<input type="range">

范围输入元素是理想的选择,因为它允许用户在两个边界(最小值和最大值)之间选择数值。我们的目标是设计这个原生元素,将其转换为星级评分组件,无需额外的标记或任何脚本!我们还将在最后创建更多组件,敬请关注。

注意: 本文仅关注CSS部分。虽然我尽力考虑了UI、UX和可访问性方面,但我的组件并不完美。它可能有一些缺点(错误、可访问性问题等),因此请谨慎使用。

<input type="range"> 元素

您可能知道,由于所有默认的浏览器样式以及不同的内部结构,设计原生元素(如输入元素)有点棘手。例如,如果您检查范围输入元素的代码,您会在Chrome(或Safari、Edge)和Firefox之间看到不同的HTML。

幸运的是,我们有一些共同的部分,我将依赖这些部分。我将定位两个不同的元素:主元素(输入本身)和滑块元素(您使用鼠标滑动以更新值的那个元素)。

我们的CSS主要如下所示:

input[type="range"] {
  /* 主元素样式 */
}

input[type="range"][i]::-webkit-slider-thumb {
  /* Chrome、Safari和Edge的滑块样式 */
}

input[type="range"]::-moz-range-thumb {
  /* Firefox的滑块样式 */
}

唯一的缺点是我们需要重复滑块元素的样式两次。不要尝试执行以下操作:

input[type="range"][i]::-webkit-slider-thumb,
input[type="range"]::-moz-range-thumb {
  /* 滑块样式 */
}

这不起作用,因为整个选择器无效。Chrome等不理解::-moz-*部分,而Firefox不理解::-webkit-*部分。为简单起见,在本文中,我将使用以下选择器:

input[type="range"]::thumb {
  /* 滑块样式 */
}

但是演示包含带有重复样式的真实选择器。介绍足够了,让我们开始编码吧!

主元素样式(星形)

我们首先定义大小:

input[type="range"] {
  --s: 100px; /* 控制大小 */

  height: var(--s);
  aspect-ratio: 5;

  appearance: none; /* 删除默认浏览器样式 */
}

如果我们认为每颗星都位于一个正方形区域内,那么对于5星级评分,我们需要宽度等于高度的五倍,因此使用aspect-ratio: 5

该5值也定义为输入元素的max属性的值。

<input type="range" max="5">

因此,我们可以依靠新增强的attr()函数(目前仅限Chrome)来读取该值,而不是手动定义它!

input[type="range"] {
  --s: 100px; /* 控制大小 */

  height: var(--s);
  aspect-ratio: attr(max type(<number>));

  appearance: none; /* 删除默认浏览器样式 */
}</number>

现在您可以通过简单地调整max属性来控制星星的数量。这很棒,因为max属性也被浏览器内部使用,因此更新该值将控制我们的实现以及浏览器的行为。

这个增强的attr()版本目前仅在Chrome中可用,因此我所有的演示都包含一个后备方案来帮助不支持的浏览器。

下一步是使用CSS遮罩来创建星星。我们需要形状重复五次(或更多次,取决于max值),因此遮罩大小应等于var(--s) var(--s)var(--s) 100%或简化为var(--s),因为默认情况下高度将等于100%。

&lt;input type=&quot;range&quot;&gt;

您可能会问mask-image属性是什么?我想我告诉您它需要一些渐变并不奇怪,但它也可以是SVG。本文是关于创建星级评分组件的,但我希望星形部分保持通用性,以便您可以轻松地将其替换为任何您想要的形状。这就是为什么我在这篇文章的标题中说“还有更多”。我们稍后将看到如何使用相同的代码结构获得各种不同的变体。

这里有一个演示,展示了星形的两种不同的实现方式。一种是使用渐变,另一种是使用SVG。

在这种情况下,SVG实现看起来更简洁,代码也更短,但请记住这两种方法,因为渐变实现有时可以做得更好。

滑块样式(选中值)

现在让我们关注滑块元素。使用最后一个演示,然后单击星星,并注意滑块的位置。

好消息是,对于所有值(从最小值到最大值),滑块始终位于给定星形的区域内,但每个星形的位置不同。如果位置始终相同,而不管值如何,那就更好了。理想情况下,为了保持一致性,滑块应始终位于星形的中心。

这是一张图,用于说明位置以及如何更新它。

这些线是每个值的滑块位置。在左侧,我们有默认位置,其中滑块从主元素的左边缘移动到右边缘。在右侧,如果我们通过在两侧添加一些空间来限制滑块的位置到较小的区域,我们将获得更好的对齐方式。该空间等于一颗星大小的一半,或var(--s)/2。我们可以为此使用填充:

input[type="range"] {
  /* 主元素样式 */
}

input[type="range"][i]::-webkit-slider-thumb {
  /* Chrome、Safari和Edge的滑块样式 */
}

input[type="range"]::-moz-range-thumb {
  /* Firefox的滑块样式 */
}

它更好,但并不完美,因为我没有考虑滑块大小,这意味着我们没有真正的居中。这不是问题,因为我将使用等于1px的宽度使滑块的大小非常小。

input[type="range"][i]::-webkit-slider-thumb,
input[type="range"]::-moz-range-thumb {
  /* 滑块样式 */
}

滑块现在是一条细线,位于星形的中心。我使用红色来突出显示位置,但在现实中,我不需要任何颜色,因为它将是透明的。

您可能认为我们距离最终结果还很远,但我们快完成了!缺少一个属性来完成这个难题:border-image

border-image属性允许我们使用其outset功能在元素外部绘制装饰。为此,我使滑块变小且透明。着色将使用border-image完成。我将使用具有两种纯色的渐变作为源:

input[type="range"]::thumb {
  /* 滑块样式 */
}

我们编写如下内容:

&lt;input type=&quot;range&quot;&gt;

上述内容意味着我们将border-image的区域从元素的每一侧扩展100px,并且渐变将填充该区域。换句话说,渐变的每种颜色将覆盖该区域的一半,即100px。

你明白逻辑了吗?我们在滑块的每一侧创建了一种溢出的着色——一种将逻辑地跟随滑块的着色,因此每次单击一颗星时,它都会滑入到位!

现在,让我们使用一个非常大的值而不是100px:

我们快完成了!着色填充了所有星星,但我们不希望它位于中间,而是位于整个选定星形上。为此,我们稍微更新一下渐变,而不是使用50%,我们使用50% var(--s)/2。我们添加一个等于星形宽度一半的偏移量,这意味着第一种颜色将占据更多空间,我们的星级评分组件就完美了!

我们仍然可以稍微优化代码,而不是为滑块定义高度,我们将它保持为0,并且考虑border-image的垂直outset来扩展着色。

input[type="range"] {
  /* 主元素样式 */
}

input[type="range"][i]::-webkit-slider-thumb {
  /* Chrome、Safari和Edge的滑块样式 */
}

input[type="range"]::-moz-range-thumb {
  /* Firefox的滑块样式 */
}

我们也可以使用圆锥渐变来不同地编写渐变:

input[type="range"][i]::-webkit-slider-thumb,
input[type="range"]::-moz-range-thumb {
  /* 滑块样式 */
}

我知道border-image的语法不容易理解,我对解释有点快。但我有一篇非常详细的文章发表在Smashing Magazine上,我在其中用很多例子剖析了这个属性,我邀请您阅读,以便更深入地了解该属性的工作原理。

我们组件的完整代码如下:

input[type="range"]::thumb {
  /* 滑块样式 */
}
input[type="range"] {
  --s: 100px; /* 控制大小 */

  height: var(--s);
  aspect-ratio: 5;

  appearance: none; /* 删除默认浏览器样式 */
}

就是这样!几行CSS代码,我们就得到了一个漂亮的星级评分组件!

半星评分

如何将评分粒度设置为半星?这很常见,我们可以通过进行一些调整来完成之前的代码。

首先,我们将输入元素更新为以半步而不是全步递增:

<input type="range" max="5">

默认情况下,步长等于1,但我们可以将其更新为.5(或任何值),然后也将最小值更新为.5。在CSS方面,我们将填充从var(--s)/2更改为var(--s)/4,并且对渐变中的偏移量也执行相同的操作。

input[type="range"] {
  --s: 100px; /* 控制大小 */

  height: var(--s);
  aspect-ratio: attr(max type(<number>));

  appearance: none; /* 删除默认浏览器样式 */
}</number>

两种实现方式之间的差异是一个二分之一的因子,这也是步长值。这意味着我们可以使用attr()并创建适用于这两种情况的通用代码。

input[type="range"] {
  --s: 100px; /* 控制大小 */

  height: var(--s);
  aspect-ratio: attr(max type(<number>));

  appearance: none; /* 删除默认浏览器样式 */

  mask-image: /* ... */;
  mask-size: var(--s);
}</number>

这是一个演示,其中修改步长是您需要做的所有事情来控制粒度。不要忘记,您还可以使用max属性来控制星星的数量。

使用键盘调整评分

如您所知,我们可以使用键盘调整范围滑块输入的值,因此我们也可以使用键盘来控制评分。这是一件好事,但有一个警告。由于使用了mask属性,我们不再具有指示键盘焦点的默认轮廓,这对依赖键盘输入的用户来说是一个可访问性问题。

为了获得更好的用户体验并使组件更易于访问,最好在焦点时显示轮廓。最简单的解决方案是添加一个额外的包装器:

&lt;input type=&quot;range&quot;&gt;

当内部的输入具有焦点时,这将具有轮廓:

input[type="range"] {
  /* 主元素样式 */
}

input[type="range"][i]::-webkit-slider-thumb {
  /* Chrome、Safari和Edge的滑块样式 */
}

input[type="range"]::-moz-range-thumb {
  /* Firefox的滑块样式 */
}

尝试在下面的示例中使用键盘来调整这两个评分:

另一个想法是考虑更复杂的遮罩配置,该配置使元素周围的小区域保持可见以显示轮廓:

input[type="range"][i]::-webkit-slider-thumb,
input[type="range"]::-moz-range-thumb {
  /* 滑块样式 */
}

我更喜欢使用最后一种方法,因为它保持了单元素实现,但也许您的HTML结构允许您在父元素上添加焦点,您可以保持遮罩配置简单。这完全取决于您!

更多示例!

正如我之前所说,我们制作的不仅仅是一个星级评分组件。您可以轻松更新遮罩值以使用任何您想要的形状。

这是一个示例,我使用的是心的SVG而不是星形。

为什么不是蝴蝶?

这次我使用PNG图像作为遮罩。如果您不习惯使用SVG或渐变,则可以使用透明图像。只要您有SVG、PNG或渐变,您就可以使用此方法做任何形状的事情。

我们可以进一步定制并创建一个像下面的音量控制组件:

在最后一个示例中,我没有重复特定的形状,而是使用复杂的遮罩配置来创建信号形状。

结论

我们从一个星级评分组件开始,最后得到了许多很酷的示例。标题本可以是“如何设计范围输入元素”,因为这就是我们所做的。我们在没有任何脚本或额外标记的情况下升级了一个原生组件,并且只使用了几行CSS代码。

你呢?你能想到另一个使用相同代码结构的漂亮组件吗?在评论区分享您的示例!

文章系列

  1. 仅CSS的星级评分组件及更多!(第一部分)
  2. 仅CSS的星级评分组件及更多!(第二部分)— 3月7日推出!

以上是仅CSS的星级等级组件等等! (第1部分)的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
两个图像和一个API:我们重新着色产品所需的一切两个图像和一个API:我们重新着色产品所需的一切Apr 15, 2025 am 11:27 AM

我最近找到了一种动态更新任何产品图像的颜色的解决方案。因此,只有一种产品之一,我们可以以不同的方式对其进行着色以显示

每周平台新闻:第三方代码,被动混合内容,连接最慢的国家的影响每周平台新闻:第三方代码,被动混合内容,连接最慢的国家的影响Apr 15, 2025 am 11:19 AM

在本周的综述中,灯塔在第三方脚本上阐明了灯光,不安全的资源将在安全站点上被阻止,许多国家连接速度

托管您自己的非JavaScript分析的选项托管您自己的非JavaScript分析的选项Apr 15, 2025 am 11:09 AM

有很多分析平台可帮助您跟踪网站上的访问者和使用数据。也许最著名的是Google Analytics(广泛使用)

它全部都在头上:管理带有React头盔的React Power Site的文档头它全部都在头上:管理带有React头盔的React Power Site的文档头Apr 15, 2025 am 11:01 AM

文档负责人可能不是网站上最迷人的部分,但是其中所处的内容对于您的网站的成功也一样重要

JavaScript中的Super()是什么?JavaScript中的Super()是什么?Apr 15, 2025 am 10:59 AM

当您看到一些称为super()的JavaScript时,在子类中,您会使用super()调用其父母的构造函数和超级。访问它的

比较不同类型的本机JavaScript弹出窗口比较不同类型的本机JavaScript弹出窗口Apr 15, 2025 am 10:48 AM

JavaScript具有各种内置弹出API,它们显示用于用户交互的特殊UI。著名:

为什么可访问的网站如此难以构建?为什么可访问的网站如此难以构建?Apr 15, 2025 am 10:45 AM

前几天,我与一些前端人们聊天,讲述了为什么这么多公司努力创建可访问的网站。为什么可访问的网站如此艰难

'隐藏”属性显然很弱'隐藏”属性显然很弱Apr 15, 2025 am 10:43 AM

有一个HTML属性,它可以正是您认为应该做的:

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
4 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
4 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
4 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
1 个月前By尊渡假赌尊渡假赌尊渡假赌

热工具

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境