极简 CSS 实现星级评分

Avatar of Chris Coyier
Chris Coyier 发布

DigitalOcean 提供适用于旅程各个阶段的云产品。 立即开始使用 $200 免费信用额度!

这里有一篇更新的文章: 五种实现五星级评分的方法,虽然它没有涵盖这种确切的技术,但这仍然是一个合法的 CSS 技巧!

星级评分是一种经典的 UX 模式,每个人都曾经尝试过。 我有一个想法,可以用很少的代码和不使用 JavaScript 来完成 UX 部分。

标记使用 unicode 实体来表示星号 (☆)。 如果你有 UTF-8 字符集,这应该没什么大不了的。 或者,你可以使用 ☆ (计算器 可以用来做这种事情)。 你可以使用任意数量的星号

<div class="rating">
<span>☆</span><span>☆</span><span>☆</span><span>☆</span><span>☆</span>
</div>

现在我们需要用“实心”星号来覆盖“空心”星号,并在悬停时显示出来 (画廊 可以用来查找这些类型的字符)。 很简单,只需在 :hover 上放置一个实心星号 (★) 的伪元素即可

.rating > span:hover:before {
   content: "\2605";
   position: absolute;
}

由于它是绝对定位的,所以 top: 0; left: 0; 是隐含的(至少在现代浏览器中)。 所以实心星号正好位于空心星号之上。 你甚至可以根据需要更改颜色或大小。

但是到目前为止,我们所做的只能对单个星号有效。 UX 模式要求所有星号都被填满。 例如,如果我们悬停在第四颗星上,第四颗星将变为实心,但第一、第二和第三颗星也会变为实心。

通过 CSS,无法选择之前的子元素。 但是,有一种方法可以使用相邻或通用兄弟组合器 来选择之后的子元素。 如果我们字面上颠倒字符的顺序,那么我们就可以利用通用兄弟组合器来选择在视觉上出现在悬停星之前,但在 HTML 中出现在悬停星之后的所有星号。

.rating {
  unicode-bidi: bidi-override;
  direction: rtl;
}
.rating > span:hover:before,
.rating > span:hover ~ span:before {
   content: "\2605";
   position: absolute;
}

就是这样! 整个星级评分 UX 模式,只需很少的代码即可实现。 以下是使它生效的整个 CSS 代码段

.rating {
  unicode-bidi: bidi-override;
  direction: rtl;
}
.rating > span {
  display: inline-block;
  position: relative;
  width: 1.1em;
}
.rating > span:hover:before,
.rating > span:hover ~ span:before {
   content: "\2605";
   position: absolute;
}

查看演示

并且这里有一个 Dabblet,如果你想修改它。

实际使用

很有可能,JavaScript 将会参与到评分星的处理中。 当用户点击一颗星时,评分将通过 Ajax 报告回来,小部件本身也会获得一个类,以永久显示他们选择的星数。 既然 JavaScript 已经参与进来,那么依靠它来对星号周围的类进行翻转,使它们正常工作是否可以接受? 如果你的应用程序完全依赖 JavaScript 才能正常工作,那么当然,这是可以的。 如果你有兴趣构建一个无需 JavaScript 仍然可以正常工作的网站,那么这些星级评分将需要更多工作。 你应该参考Lea Verou 的示例,它使用了单选按钮,这可以是表单的一部分,可以在没有 JavaScript 的情况下提交以“评级”。

其他

在我在 Twitter 上首次分享后,其他几个人以略微不同的方式尝试了一下。 @dmfilipenkoDabblet@mprogano 的 Dabblet