无需 JS 即可实现可扩展的“星级评定”(并且无需 SVG 或星级图像)

2025-05-24

无需 JS 即可实现可扩展的“星级评定”(并且无需 SVG 或星级图像)

这是我的“星级评定”系统:

✔️ 无需 JavaScript。✔️
无需复杂的 HTML 代码,仅包含<input>用户交互所需的元素和一个额外元素。✔️
无需复杂的 CSS 代码。✔️
易于扩展。只需添加更多元素<input>即可获得更多星星。无需更改任何 CSS 代码。✔️
支持键盘导航。✔️
无需 SVG,无需图像。星星形状纯 CSS 构建。✔️
您可以轻松调整星星的大小和颜色。✔️
支持ltr双向rtl

观看实际效果:

如上所述,HTML 代码非常简单。一个div包含输入框和一个额外<i>元素的代码。仅此而已!

您所要做的就是添加您想要的星星数量的输入。

对于 CSS 部分,我们有如下简单部分:

.stars {
  --s:50px;
  position:relative;
  display:inline-flex;
}
.stars input {
  width:var(--s);
  height:var(--s);
  margin:0;
  opacity:0;
  cursor:pointer;
}
Enter fullscreen mode Exit fullscreen mode

变量--s将定义我们使用 隐藏的输入框的大小opacity:0。所有内容都位于一个弹性盒子容器内(一个inline可以轻松集成星级评定的容器,例如图像或简单文本)。

真正的诀窍在于i

.stars i {
  position:absolute;
  inset:0 0 calc(var(--s)*0.1);
  pointer-events:none;
  /* the star */
  --v1:transparent,#000 0.5deg 108deg,#0000 109deg;
  --v2:transparent,#000 0.5deg  36deg,#0000  37deg;
  -webkit-mask:
    conic-gradient(from 54deg  at calc(var(--s)*0.68) calc(var(--s)*0.57),var(--v1)),
    conic-gradient(from 90deg  at calc(var(--s)*0.02) calc(var(--s)*0.35),var(--v2)),
    conic-gradient(from 126deg at calc(var(--s)*0.5)  calc(var(--s)*0.7) ,var(--v1)),
    conic-gradient(from 162deg at calc(var(--s)*0.5)  0                  ,var(--v2));
  -webkit-mask-size: var(--s) var(--s);
  -webkit-mask-composite: xor,destination-over;
  mask-composite: exclude,add;
  /**/
  background:
    linear-gradient(rgba(255,0,0,var(--o,0.3)) 0 0),  
    linear-gradient(gold                       0 0)
    #ccc;
  background-size:
     calc(var(--l,0)*var(--s)) 100%,
     calc(var(--p,0)*var(--s)) 100%;
  background-repeat:no-repeat;
}
Enter fullscreen mode Exit fullscreen mode

首先,我们将其设为绝对元素,它将覆盖所有 div 以及逻辑上的所有输入框。这样我们就pointer-events:none;可以与输入框进行交互,但鼠标光标仍然停留在 div 上<i>

其次,我们应用 3 个背景层,如下所示:

  1. 底层为灰色(#ccc),表示星星的数量和未选中的星星的数量
  2. 中间层是金色。这里我们使用了基于所选星星大小可变的渐变(由变量控制--p)。
  3. 顶层与 (2) 类似,并将响应:hover效果(由变量 控制--l)。我将使用半透明的颜色,以便我们仍然可以看到选定的星星。

那些奇怪的渐变和面具怎么样?

这是我的个人风格,也是作品中最疯狂的部分。我运用多种渐变色,构建了星形,mask以便所有背景图层都能透过星形看到。

最后,交互部分使用如下代码完成:

.stars:focus-within {
  outline:1px solid;
}
input:active ~ i{--o:1}
input:nth-of-type(N):checked ~ i {--p:N} 
input:nth-of-type(N):hover ~ i {--l:N}
Enter fullscreen mode Exit fullscreen mode

:focus-within允许我div在与输入交互时设置整体样式(有利于可访问性)

当输入处于活动状态(单击)时,我将半透明颜色更改为不透明颜色以突出显示单击操作。

我根据输入索引:checked更新变量--p。我们可以使用 SASS/LESS 或通过复制粘贴轻松生成代码(只需几秒钟即可编写涵盖最多 20 个输入的代码)。

我们按照:hover同样的逻辑,但使用变量--l

支持情况怎么样rtl

我们可以background-position根据方向属性进行更新,然后简单地添加:

[dir="rtl"] .stars i {
    background-position: right;
}
Enter fullscreen mode Exit fullscreen mode

或者我更新代码,不再使用多个背景,而是使用可以轻松放置的伪元素margin-inline-end

诀窍在于让两个伪元素彼此叠置(这要归功于grid-area:1/1),并设置合适的颜色。它们的宽度将使用控制渐变的相同变量来控制。最后,通过使用 ,它们将根据方向margin-inline-end:auto;被放置在left或 处。right


就是这样

一个简单的非黑客代码,我们就有一个完全交互式的“星级评定”,您可以轻松地将其嵌入任何地方。


奖金

如果您不需要交互部分,这里有一个可以使用 CSS 变量控制的单 div 版本:

文章来源:https://dev.to/afif/scalable-star- rating-without-js-and-no-svg-or-image-for-the-star-2mef
PREV
你的下一个项目还有 100 个 CSS 加载器
NEXT
根据图像大小响应文本