I want to make a pure css [no jquery] star rating system. So I have a html form with 5 radio buttons. So far I can make when I hover/click on a star radio button to change it's own background image. It works for every star BUT separately. When I click on the fifth star - only the fifth star is changed. When I click on the fourth star - only the fourth star is changed and so on. I want to make that when I hover/click on the fifth star -> all stars to change their background image. When I click on the second star the first two stars to change and etc. so the user can see for how much stars he is voting. (you've seen these rating systems all over the internet)
我想制作一个纯粹的css [no jquery]星级评分系统。所以我有一个带有5个单选按钮的html表单。到目前为止,我可以在悬停/点击星形单选按钮时更改它自己的背景图像。它适用于每个明星但分开。当我点击第五颗星时 - 只有第五颗星被改变了。当我点击第四颗星时 - 只有第四颗星被改变,依此类推。当我悬停/点击第五颗星 - >所有星星来改变它们的背景图像时,我想做到这一点。当我点击第二颗星时,前两颗星会改变等等,这样用户就可以看到他投票的星星数量。 (你已经在互联网上看到过这些评级系统)
I want to make like these (again only css):
我想做这些(再次只有CSS):
But I end up with this:
但我最终得到了这个:
So I have 5 stars/radio inputs and each is from a class:
所以我有5星/无线电输入,每个都来自一个类:
1 star -> radioStarButton1
1星 - > radioStarButton1
2 star -> radioStarButton2
2星 - > radioStarButton2
3 star -> radioStarButton3
3星 - > radioStarButton3
4 star -> radioStarButton4
4星 - > radioStarButton4
5 star -> radioStarButton5
5星 - > radioStarButton5
<input type="radio" name="stars" id="'.'2stars-for-id-'.$row['id'].'" class="radioStarButton2" value="2" />
<label for="'.'2stars-for-id-'.$row['id'].'"></label>
<input type="radio" name="stars" id="'.'3stars-for-id-'.$row['id'].'" class="radioStarButton3" value="3" checked />
<label for="'.'3stars-for-id-'.$row['id'].'"></label>
<input type="radio" name="stars" id="'.'4stars-for-id-'.$row['id'].'" class="radioStarButton4" value="4" />
<label for="'.'4stars-for-id-'.$row['id'].'"></label>
<input type="radio" name="stars" id="'.'5stars-for-id-'.$row['id'].'" class="radioStarButton5" value="5" />
<label for="'.'5stars-for-id-'.$row['id'].'"></label>
I want to make when I hover/click on the second class .radioStarButton2 to change also the fist class -> .radioStarButton1 and THAT is the problem - to change more than one class elements IF it is possible.
当我悬停/点击第二个类时,我想制作.radioStarButton2来改变第一类 - > .radioStarButton1和THAT是问题 - 如果可能的话,改变多个类元素。
Also the css: This is working css:
还有css:这是工作css:
input[type="radio"]{
display:none;
}
input[type="radio"] + label
{
background-image: url("uncheckedstar.png");
height: 23px;
width: 23px;
display:inline-block;
padding: 0 0 0 0px;
}
.radioStarButton1:hover + label
{
background-image: url("star.png");
height: 23px;
width: 23px;
display:inline-block;
padding: 0 0 0 0px;
}
.radioStarButton1:checked + label
{
background-image: url("star.png");
height: 23px;
width: 23px;
display:inline-block;
padding: 0 0 0 0px;
}
The next code is obviously wrong but I don't know how to do it. I'm uploading it only for an idea what I'm trying to do:
下一个代码显然是错误的,但我不知道该怎么做。我上传它只是为了一个想法,我正在尝试做什么:
.radioStarButton2:hover + label , .radioStarButton1
{
background-image: url("star.png");
height: 23px;
width: 23px;
display:inline-block;
padding: 0 0 0 0px;
}
.radioStarButton2:checked + label , .radioStarButton1
{
background-image: url("star.png");
height: 23px;
width: 23px;
display:inline-block;
padding: 0 0 0 0px;
}
.radioStarButton3:hover + label , .radioStarButton1 , .radioStarButton2
{
background-image: url("star.png");
height: 23px;
width: 23px;
display:inline-block;
padding: 0 0 0 0px;
}
.radioStarButton3:checked + label , .radioStarButton1 , .radioStarButton2
{
background-image: url("star.png");
height: 23px;
width: 23px;
display:inline-block;
padding: 0 0 0 0px;
}
4 个解决方案
#1
1
An extension of Koen's solution ... and stays after clicked as well ... you need to re-position/style the labels (and add your stars), hide the inputs, but it's CSS only
Koen解决方案的扩展......并且在点击之后保持不变......你需要重新定位/设置标签样式(并添加你的星星),隐藏输入,但它只是CSS
Demo: http://jsfiddle.net/f82Fg/2/
HTML
<div class="butts">
<input id="r5" type="radio" class="butt" value="5" />
<label for="r5">5</label>
<input id="r4" type="radio" class="butt" value="4" />
<label for="r4">4</label>
<input id="r3" type="radio" class="butt" value="3" />
<label for="r3">3</label>
<input id="r2" type="radio" class="butt" value="2" />
<label for="r2">2</label>
<input id="r1" type="radio" class="butt" value="1" />
<label for="r1">1</label>
</div>
CSS
.butts {
float: left;
}
.butt {
display: block;
float: right;
width: 16px;
height: 16px;
}
.butt:hover,
.butt:hover ~ .butt,
.butt:hover ~ label {
background-color: blue;
}
.butt:checked,
.butt:checked ~ .butt,
.butt:checked ~ label {
background-color: red;
}
#2
4
If you place the HTML elements in reverse order, you can use the CSS sibling selector (~
) to select the preceding stars.
如果以相反的顺序放置HTML元素,则可以使用CSS同级选择器(〜)选择前面的星号。
HTML:
<div class="stars">
<span class="star">5</span>
<span class="star">4</span>
<span class="star">3</span>
<span class="star">2</span>
<span class="star">1</span>
</div>
CSS:
.stars {
float: left;
}
.star {
display: block;
float: right;
width: 20px;
height: 20px;
margin: 5px;
background: grey;
}
.star:hover,
.star:hover ~ .star {
background: yellow;
}
#3
3
You can only select “to the right” or “downwards” with CSS, not “to the left” or “upwards” – meaning, selecting descendant elements and siblings on the same level after an element in the DOM is possible; selecting ancestors or previous siblings is not.
您只能使用CSS选择“向右”或“向下”,而不是“向左”或“向上” - 这意味着,在DOM中的元素可能之后选择同一级别的后代元素和兄弟;选择祖先或以前的兄弟姐妹不是。
So what you could do to get the star up to and including the one hovered to change color, is change color of all of them when the container element gets hovered – and then make the stars coming after the hovered one be gray again, using the ~
selector.
因此,你可以做的就是让恒星达到并包括悬停改变颜色的恒星,当容器元素悬停时,它们会改变所有颜色的颜色 - 然后让悬浮的恒星再次变成灰色,使用〜选择器。
No for the “active”/radio-button-checked state, there is no easy way to do this – you could try to use the :target
selector, but that would require the whole stuff to be nested into a couple of elements with different IDs, and it would lose the state again once some other hash-anchor on the page would be used.
对于“活动”/单选按钮检查状态没有,没有简单的方法可以做到这一点 - 你可以尝试使用:target选择器,但这需要将整个东西嵌套到几个不同的元素中ID,并且一旦使用页面上的其他散列锚,它将再次失去状态。
To actually achieve that kind of thing, you will have to change the order of the stars, so that the first one displayed is the last one of them in DOM order, etc. – for example by floating them to the right within their container element, or by using direction
.
要实际实现这种类型的事情,你必须改变星星的顺序,以便显示的第一个是DOM顺序中的最后一个,等等 - 例如通过在它们的容器元素中向右浮动它们,或使用方向。
That way, when the last element gets checked, only that one gets the orange color – and only the first in visible order will be orange.
The second-to-last gets checked, you format the second-to-last one and the last one (again using ~
) – and due to reverse display order, the first to stars in visible order will be orange – etc.
这样,当检查最后一个元素时,只有那个元素获得橙色 - 并且只有可见顺序的第一个元素才是橙色。从秒到后检查,你格式化倒数第二个和最后一个(再次使用〜) - 由于反向显示顺序,第一个以可见顺序显示的星号将是橙色 - 等等。
The only problem left will be combining those two approaches – not exactly sure if that can be done easily.
剩下的唯一问题是将这两种方法结合起来 - 不确定是否可以轻松完成。
Edit: OK, after seeing Koen’s answer, it should be quite easy, if you use the reverse-order trick for both :hover and :checked states.
编辑:好的,看完Koen的答案之后,如果你对两者使用反向排序技巧,它应该很容易:hover和:checked states。
#4
1
You could place each label
in a nested list and apply the hover state to include child elements like you would with a drop-down navigation.
您可以将每个标签放在嵌套列表中,并应用悬停状态以包含子元素,就像使用下拉导航一样。
However, you'd still need some scripting to mark any lower-level star input
fields as selected once a user clicks on a higher-level star anyway. Otherwise, when they move the mouse off, the hover effect would disappear and you'd still have the same issue of only one star is shown as highlighted.
但是,无论如何,一旦用户点击更高级别的星标,您仍然需要一些脚本来将任何较低级别的星形输入字段标记为已选中。否则,当他们将鼠标移开时,悬停效果将消失,您仍然会遇到同样的问题,只有一颗星显示为突出显示。
#1
1
An extension of Koen's solution ... and stays after clicked as well ... you need to re-position/style the labels (and add your stars), hide the inputs, but it's CSS only
Koen解决方案的扩展......并且在点击之后保持不变......你需要重新定位/设置标签样式(并添加你的星星),隐藏输入,但它只是CSS
Demo: http://jsfiddle.net/f82Fg/2/
HTML
<div class="butts">
<input id="r5" type="radio" class="butt" value="5" />
<label for="r5">5</label>
<input id="r4" type="radio" class="butt" value="4" />
<label for="r4">4</label>
<input id="r3" type="radio" class="butt" value="3" />
<label for="r3">3</label>
<input id="r2" type="radio" class="butt" value="2" />
<label for="r2">2</label>
<input id="r1" type="radio" class="butt" value="1" />
<label for="r1">1</label>
</div>
CSS
.butts {
float: left;
}
.butt {
display: block;
float: right;
width: 16px;
height: 16px;
}
.butt:hover,
.butt:hover ~ .butt,
.butt:hover ~ label {
background-color: blue;
}
.butt:checked,
.butt:checked ~ .butt,
.butt:checked ~ label {
background-color: red;
}
#2
4
If you place the HTML elements in reverse order, you can use the CSS sibling selector (~
) to select the preceding stars.
如果以相反的顺序放置HTML元素,则可以使用CSS同级选择器(〜)选择前面的星号。
HTML:
<div class="stars">
<span class="star">5</span>
<span class="star">4</span>
<span class="star">3</span>
<span class="star">2</span>
<span class="star">1</span>
</div>
CSS:
.stars {
float: left;
}
.star {
display: block;
float: right;
width: 20px;
height: 20px;
margin: 5px;
background: grey;
}
.star:hover,
.star:hover ~ .star {
background: yellow;
}
#3
3
You can only select “to the right” or “downwards” with CSS, not “to the left” or “upwards” – meaning, selecting descendant elements and siblings on the same level after an element in the DOM is possible; selecting ancestors or previous siblings is not.
您只能使用CSS选择“向右”或“向下”,而不是“向左”或“向上” - 这意味着,在DOM中的元素可能之后选择同一级别的后代元素和兄弟;选择祖先或以前的兄弟姐妹不是。
So what you could do to get the star up to and including the one hovered to change color, is change color of all of them when the container element gets hovered – and then make the stars coming after the hovered one be gray again, using the ~
selector.
因此,你可以做的就是让恒星达到并包括悬停改变颜色的恒星,当容器元素悬停时,它们会改变所有颜色的颜色 - 然后让悬浮的恒星再次变成灰色,使用〜选择器。
No for the “active”/radio-button-checked state, there is no easy way to do this – you could try to use the :target
selector, but that would require the whole stuff to be nested into a couple of elements with different IDs, and it would lose the state again once some other hash-anchor on the page would be used.
对于“活动”/单选按钮检查状态没有,没有简单的方法可以做到这一点 - 你可以尝试使用:target选择器,但这需要将整个东西嵌套到几个不同的元素中ID,并且一旦使用页面上的其他散列锚,它将再次失去状态。
To actually achieve that kind of thing, you will have to change the order of the stars, so that the first one displayed is the last one of them in DOM order, etc. – for example by floating them to the right within their container element, or by using direction
.
要实际实现这种类型的事情,你必须改变星星的顺序,以便显示的第一个是DOM顺序中的最后一个,等等 - 例如通过在它们的容器元素中向右浮动它们,或使用方向。
That way, when the last element gets checked, only that one gets the orange color – and only the first in visible order will be orange.
The second-to-last gets checked, you format the second-to-last one and the last one (again using ~
) – and due to reverse display order, the first to stars in visible order will be orange – etc.
这样,当检查最后一个元素时,只有那个元素获得橙色 - 并且只有可见顺序的第一个元素才是橙色。从秒到后检查,你格式化倒数第二个和最后一个(再次使用〜) - 由于反向显示顺序,第一个以可见顺序显示的星号将是橙色 - 等等。
The only problem left will be combining those two approaches – not exactly sure if that can be done easily.
剩下的唯一问题是将这两种方法结合起来 - 不确定是否可以轻松完成。
Edit: OK, after seeing Koen’s answer, it should be quite easy, if you use the reverse-order trick for both :hover and :checked states.
编辑:好的,看完Koen的答案之后,如果你对两者使用反向排序技巧,它应该很容易:hover和:checked states。
#4
1
You could place each label
in a nested list and apply the hover state to include child elements like you would with a drop-down navigation.
您可以将每个标签放在嵌套列表中,并应用悬停状态以包含子元素,就像使用下拉导航一样。
However, you'd still need some scripting to mark any lower-level star input
fields as selected once a user clicks on a higher-level star anyway. Otherwise, when they move the mouse off, the hover effect would disappear and you'd still have the same issue of only one star is shown as highlighted.
但是,无论如何,一旦用户点击更高级别的星标,您仍然需要一些脚本来将任何较低级别的星形输入字段标记为已选中。否则,当他们将鼠标移开时,悬停效果将消失,您仍然会遇到同样的问题,只有一颗星显示为突出显示。