星级评分是一种经典的 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 上首次分享后,其他几个人以略微不同的方式尝试了一下。 @dmfilipenko 的 Dabblet。 @mprogano 的 Dabblet
在 Safari 5.1.2 中部分损坏: http://cl.ly/DqpH
嗯……
https://img.skitch.com/20120202-tdahxwtcyf1fdag65uwh2iybmd.jpg
另外,我认为,从语义上来说,使用 比较好,不是吗?
<ul>,抱歉
对于那个特定问题,事实证明,至少对绝对定位的填充星使用
left: 0;
是最好的。我个人认为,无序列表不行。 如果有,则是有序列表,但我认为,它只是一些可以点击的星号,它不是一个“列表”。
我喜欢这个想法!
如果是我,我会在 :hover 状态下添加 “cursor:pointer”。
是的,那会很棒!
在 Chrome(Mac)上实际上偏离了一些像素。
不错的文章。 分享这个有用的帖子真是太好了。 谢谢分享。
我认为它在触控方面的移动 Safari 上不起作用,就像在我的手机上一样。
这是一个很棒的技术,但我也在 OS X 上的 Firefox 10 中看到了那个像素偏移。
我这边也是。 我使用的是 Ubuntu(Linux)上的 Firefox 10。
FYI:
top: 0; left: 0;
永远不会隐含。 如果一个元素被绝对定位,但没有指定水平或垂直位置,那么元素将占据它在静态定位(即在流中)时会占据的水平或垂直位置。这是所有当前浏览器的情况。(它也适用于旧版本的 IE,但并不完全适用:旧版本的 IE 在绝对定位的内联元素方面存在问题。)
另请参阅: CSS 2.1:视觉格式化模型详细信息 – 10.6.4:绝对定位的非替换元素
扩展以使用透明单选按钮来捕获和保留状态,而无需任何 JS
http://dabblet.com/gist/1709019
我只在 Chrome 中测试过,但请将其视为概念验证。 可能需要一些 JS 来支持旧浏览器,但这是一个开始。
我刚刚在 Firefox 9 中测试过,它在那里也完美运行。 其他人测试过吗?
你必须将其保存为一个新的 Dabblet
啊 - 我复制了错误的 URL。 我已经把它保存为一个新的 dabblet 了
http://dabblet.com/gist/1722368
好技巧! 但你知道为什么在 Windows 上的 Chrome 中星号看起来很丑吗?
如何使半颗星处于活动状态? 如果我想给 3.5 颗星
一份礼物;)
类似于“copypaste”的 Unicode 符号映射书签
http://panmental.de/symbols/info.htm
有人之前提到过语义,在我看来,只有在涉及 时,这才是语义的。
否则,如果你不需要除了可用字体提供的之外的星号处理,这真是太棒了!
哎哟... 如果涉及 的话
对我来说看起来像五个方块。 Chrome 15
这将是
:nth-letter(n)
(尚未发布)的完美用例,而不是所有这些 span。如果你看到方块,这意味着在你的浏览器中渲染的系统字体不支持文章中提到的那些代码点的字形。
我对网页开发场景还比较陌生,我很难理解为什么避免使用 JS 和 CSS 很重要。 用户会使用禁用 JS 的浏览器吗? 这对我来说似乎不太可能,但话又说回来,我对这个领域还很生疏。
我将在我的网站上使用它。谢谢!
使用 SVG 会非常容易。
怎么样?
不需要反转方向到 rtl。
查看 这个 Dabblet。
你能解释一下你是如何成功地复制了 Chris 的示例而没有反转方向到“从右到左”的吗?我读过 Dabblet,但我不太明白你在那里做了什么,伙计。
不错的解决方案,没有 rtl!
唯一的问题是,因为 .rating 是一个块级元素,所以将鼠标悬停在 div 的非星形区域上(例如,将鼠标垂直对齐到星形,但位于页面的最左侧),会导致所有星形变为金色。
很棒的文章。这些对实验很有用,但我还是会坚持使用 jQuery 的。
如果目标仅仅是最小的 css,你可以去掉 .rating 选择器及其内部内容,并在每个 span 中添加 float: right。这是另一种翻转顺序的方法。一个副作用是,你会失去居中…….
很巧妙的技术!
Chris,你用 CSS 做出的创意太棒了。我永远不会想到这种解决方案。
不过,正如评论中提到的,当你使用 Unicode 星形符号而不是使用图像时,是否存在浏览器兼容性问题?
—— Rick
将鼠标悬停在星星上时,光标在文本和指针之间闪烁(我使用的是 chrome),这有点烦人。也许用 div 包裹每个星星,并设置一致的光标?
在 Windows XP 上无效。但在 Windows Vista 和 Windows 7 上有效,因为它们具有更大/更新的字符集。
感谢你发布的精彩文章,内容非常丰富,对我们非常有用。感谢你的分享,继续发布吧。
非常好..
谢谢
嗨,
我找不到星星。:)
不错!这真的很轻量级!
我喜欢它,我尝试着使用它。
谢谢
这是我的实现:http://pressedweb.com/sandbox/star_ratings
全部使用 CSS。保存状态。一直回退到 IE6。你可以轻松地添加任意数量的星形。
这是一个巧妙的 :target 使用方法。需要注意的是,当我想要使用 :target 做一些很酷的功能时,总会让我很头疼,那就是你不能仅使用 CSS 来阻止页面向下跳转(至少据我所知)。因此,如果页面内容足够多,以至于页面滚动,点击页面时会跳转,使得星形与顶部边缘对齐。
当试图通过 CSS 实现点击/切换功能时,我更喜欢使用 复选框/单选按钮技巧。Lea Verou 使用了它:http://lea.verou.me/2011/08/accessible-star-rating-widget-with-pure-css/
我也不会说她的方法是 hack,因为选择一组星形基本上就是单选按钮的用途。
啊,该死。你说得完全正确。感谢提醒。当我在没有内容包围的情况下测试它时,我没有意识到它会跳转到那个页面锚点。
她的解决方案在未来是不错的(尤其是在 IE9/10 强制安装的情况下),但在 8 及以下版本中,回退是丑陋的单选按钮和文本标签。
看来她的解决方案 + 在标签中使用图像 + 用标签掩盖单选按钮 + 将标签链接到单选按钮 = 解决方案。我 99% 确定这是最佳解决方案,并且经过一些针对 IE6+ 的定位 TLC 处理后,它将成为标准。
非常酷的技术,我们可以用在我们的网站上。谢谢!
我永远不会想到这样的东西——太棒的解决方案了!
我在 http://dabblet.com/gist/1817473 上做了自己的小修改,主要包括一些设计变化(最初是点而不是星形),以及删除了“unicode-bidi”,因为我不知道它是什么。
这些技巧非常好,我在我的网站上使用了它们,感谢你与我们分享。
它不支持 IE6,对吗?因为在我的电脑上,我在 IE6 中测试了,但失败了。哪个版本的 IE 浏览器可以使用?
很酷的想法,但它在一定程度上限制了可访问性。屏幕阅读器不会说:评级 4 星,而是:星 星 星 星 空心星(如果它甚至知道如何处理不同星形字符之间的差异,我对此表示怀疑)。机器人也不能理解它。对于人类访客,你能确定这些星星仍然有意义吗,即使它们的布局被破坏了,例如,如果 CSS 失效或屏幕太小?
我更喜欢使用旧方法,即使用数字进行评级,然后动态地将数字替换为适当数量的星形,这更容易用背景图像完成。
单选按钮的另一种替代方案是在每个星形上放置一个锚点,其中包含一个查询字符串,供 php 将评级保存到数据库中。事实上,我认为应该使用锚点而不是 span,并且 Javascript 可以阻止默认的点击事件。
如何增大星形的大小?我试过使用
<h1>
,但它会换行。请建议。你可以在 rating 类中指定 font-size。
如何获得红色星形?
只需在 .rating > span:hover:before 和 .rating > span:hover ~ span:before 中添加一个 color 属性。
将单选按钮放在标签内怎么样?http://codepen.io/thelucid/pen/JacHC
我还是不明白
如何改变星形内部的颜色?
如何改变星形内部的颜色?