"I can't seem to find a way to select all previous siblings on hover"
Unfortunately CSS can only target, and therefore select, subsequent elements in the DOM. Thankfully this can, of course, be emulated with CSS or enabled with JavaScript.
First, the CSS approach which requires either CSS Grid or CSS Flexbox in order to adjust the order of elements on the page:
*,
::before,
::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
div {
/* to place a 1em gap between items, applicable
to both Grid and Flexbox: */
gap: 1em;
width: 80vw;
margin: 1em auto;
}
div.withFlex {
/* Using flexbox layout: */
display: flex;
/* In the HTML you might have noticed that the '5 star'
element comes before the '1 star'...'4 star' element,
this property reverses the order of the flex-items
(the elements) in the flex-box layout: */
flex-direction: row-reverse;
/* spacing the elements apart, this approach places the
available space (after the element-sizes have been
calculated) between the elements: */
justify-content: space-between;
}
div.withFlex span {
border: 1px solid #000;
flex: 1 1 auto;
}
/* here we use Grid layout: */
div.withGrid {
display: grid;
/* we force the grid-items (the elements) to
flow into columns rather than rows: */
grid-auto-flow: column;
/* here we cause the layout - again - to be reversed,
flowing from right-to-left: */
direction: rtl;
}
div.withGrid span {
border: 1px solid currentcolor;
text-align: left;
}
/* here we select the that the user hovers over,
plus any subsequent siblings, and style them differently;
as the subsequent elements appear - visually - before the
hovered- this gives the illusion that we're selecting
previous elements in the DOM: */
span:hover,
span:hover~span {
color: #f90;
border-color: currentcolor;
}
5 stars
4 stars
3 stars
2 stars
1 star
5 stars
4 stars
3 stars
2 stars
1 star
In addition to the above, assuming that you want the elements to have the ability to remain selected – while still using CSS & HTML – then using some
and
elements is also possible: