我能控制嵌套元素的:hover CSS选择器吗?

4

我是一个能翻译的有用的助手。

我正在尝试解决以下问题。我有以下HTML:

<div style="width:50em; height:10em">
    <span class='rating-5 rating-span'>
        <span class='rating-4 rating-span'>
            <span class='rating-3 rating-span'>
                <span class='rating-2 rating-span'>
                    <span class='rating-1 rating-span'>
                        <div class='rating-star unselected'></div>
                    </span>
                    <div class='rating-star unselected'></div>
                </span>
                <div class='rating-star unselected'></div>
             </span>
             <div class='rating-star unselected'></div>
         </span>
         <div class='rating-star unselected'></div>
     </span>
</div>

并且以下是CSS:

div.rating-star{
    display:inline-block;
    width:20%;
    height:100%;
    /*border:solid thin black;*/
    padding:0px;
    margin:0px;
}

div.rating-star.unselected {
    background-image: url(star.jpg);   
    background-size: contain;
    background-repeat: no-repeat;
}

.rating-span:hover div.rating-star {
    background-image: url(hover.jpg);   
    background-size: contain;
    background-repeat: no-repeat;
}

这个想法是,如果你悬停在一个星星上,所有左边的星星都会亮起来。 然而,实际上发生的是,无论你在哪里悬停,所有的星星都会亮起来。
现在我清楚地看到,这是因为我的:hover选择器选择了最外层的元素。我的问题是:在:hover选择器的情况下,有一种确定正在悬停的元素的方法。在该元素包含其他元素(相同类型)的情况下,是否有一种方式可以指定选择哪个元素。在这种情况下,应选择最低的那个元素。
我很感激我可以用JavaScript很简单地做到这一点;我只是希望有一种纯CSS的解决方案。
更新 这里是一个JSFiddle:http://jsfiddle.net/MkJmj/1/ 它稍微修改了使用绝对URL的图像,但是其余部分都相同。

1
这个问题可以很好地通过CSS单独解决。对于一个有趣的问题点赞。 - Bojangles
1
不发布为答案,只是提供一个你可能会感兴趣的内容:http://www.htmldrive.net/items/show/689/Pure-CSS-Star-Rating-System 我认为这个解决方案比你试图做的要*干净得多。 - Strelok
如果要从右到左高亮显示而不是从左到右,那么使用像 .rating-star:hover, .rating-star:hover ~ .rating-star 这样的东西会很容易和干净,而且可以放弃不美观的嵌套内容。不幸的是,并不存在“兄弟节点前面”的选择器,也不太可能存在这样的选择器。 - JimmiTh
@Dancrumb:没有嵌套的HTML,这是我测试中首先要去掉的东西。;-) - JimmiTh
这里似乎有问题,需要修复。 - mezod
显示剩余4条评论
2个回答

5

纯CSS解决方案

jsFiddle: http://jsfiddle.net/alecgorge/Sw5Ym/

这是一种纯CSS解决方案。我建议更改HTML,但这是一个有趣的练习。 这是我所做的更改:

div.rating-star{
    display:inline-block;

...

.rating-span:hover div.rating-star {

to

div.rating-star{
    display:block;
    float:right;

...

.rating-span:hover > div.rating-star {

更好的解决方案

通过将 div 改为 span,您可以获得有效的HTML(尽管有点凌乱),并且您可以拥有完全兼容IE 7+的解决方案:http://jsfiddle.net/alecgorge/FEHuw/

请确保调整窗口大小以在一行上显示所有星星。一旦星星图像变小,span 就可以变小,事情就会变得更好。


谢谢你提供的解决方案;我需要更改我的无效HTML,所以我猜我最终不会使用这个...但是感谢你找到了一个解决方案! - Dancrumb
1
这个代码片段似乎也出了问题 :/ - mezod

1
我简化了你的HTML,因为它既无效又笨重(更不用说很难用CSS选择器轻松定位)。有了修改后的HTML,下面的CSS似乎可以按照你的要求工作。虽然只在Chromium 14中进行了测试,但旧版浏览器几乎肯定不能正常工作。至于Internet Explorer,可能根本就不行:
HTML:
<div>
    <div class='rating-star unselected'></div>
    <div class='rating-star unselected'></div>
    <div class='rating-star unselected'></div>
    <div class='rating-star unselected'></div>
    <div class='rating-star unselected'></div>
</div>

而且CSS:

div:hover div.rating-star:hover ~ div.rating-star {
    background-image: url(http://danrumney.co.uk/images/star.jpg);   
    background-size: contain;
    background-repeat: no-repeat;
}

JS Fiddle


这是一个令人愉悦的解决方案。事实证明,MSIE根本不喜欢background-size,所以我可能会一无所获。但是,我真的很喜欢这个解决方案...非常整洁。 - Dancrumb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接