无需 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;
}
变量--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;
}
首先,我们将其设为绝对元素,它将覆盖所有 div 以及逻辑上的所有输入框。这样我们就pointer-events:none;
可以与输入框进行交互,但鼠标光标仍然停留在 div 上<i>
。
其次,我们应用 3 个背景层,如下所示:
- 底层为灰色(
#ccc
),表示星星的数量和未选中的星星的数量 - 中间层是金色。这里我们使用了基于所选星星大小可变的渐变(由变量控制
--p
)。 - 顶层与 (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}
:focus-within
允许我div
在与输入交互时设置整体样式(有利于可访问性)
当输入处于活动状态(单击)时,我将半透明颜色更改为不透明颜色以突出显示单击操作。
我根据输入索引:checked
更新变量--p
。我们可以使用 SASS/LESS 或通过复制粘贴轻松生成代码(只需几秒钟即可编写涵盖最多 20 个输入的代码)。
我们按照:hover
同样的逻辑,但使用变量--l
。
支持情况怎么样rtl
?
我们可以background-position
根据方向属性进行更新,然后简单地添加:
[dir="rtl"] .stars i {
background-position: right;
}
或者我更新代码,不再使用多个背景,而是使用可以轻松放置的伪元素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