Cualquier sistema de votación (star-rating system) requiere de los 3 componentes básicos de todo sitio web: HTML, CSS y JavaScript. Pero a medida que la tecnología avanza, es posible dejar la ayuda que JavaScript brindó por mucho tiempo mientras CSS no entraba de lleno a la capa de interacción, principalmente a través de CSS3. Pero existen propiedades CSS2 que siempre han permitido cierto grado de complejidad pero que por culpa de IE6 y su hermano mutante y deforme IE7 no eran posible utilizarlos. Con soporte IE8+ ya podemos utilizar tranquilamente -por ejemplo- selectores avanzados de atributos y descendientes, los que precisamente son los protagonistas de este artículo.

star-rating

Me propuse a hacer un star-rating con HTML y CSS, dejando a JavaScript la tarea de conectar el dato con el servidor, si fuese el caso. Terminé con 2 opciones diferentes, y al ponerme a investigar descubrí que ya existía por lo menos una de las soluciones a las que llegué. Para no perder el trabajo, de todas maneras las expongo aquí por si a alguien más les son útiles.

Para ambos ejemplos el marcado HTML es el mismo:

<div class="star-rating">
  <a href="#">★</a>
  <a href="#">★</a>
  <a href="#">★</a>
  <a href="#">★</a>
  <a href="#">★</a>
</div>

Técnica 1

Consiste en al hacer :hover a todo el contenedor .star-rating y al elemento (estrella), se cambia el color de todos al color de estrella seleccionado (amarillo), salvo a los selectores hermanos del elemento que vuelven a tener el color normal:

.star-rating a {
  display: inline-block;
  color: #95a5a6; /* gris (normal) */
}
.star-rating:hover a {
  color: #f39c12; /* amarillo (seleccionado) */
}
  .star-rating:hover a:hover ~ a {
    color: #95a5a6; /* gris (normal) */
  }

Ejemplo en JS Bin

Técnica 2

Como en CSS los hermanos adyacentes sólo alcanzan los que están hacia adelante en el árbol que el propio, no podemos dar estilos a los anteriores al :hover, el cual es el propósito de todo star-rating. Entonces, por qué no darlos vuelta? Flotamos los elementos (estrellas) hacia la derecha (float: right;) logrando invertirlos y obtenemos el resultado que necesitamos:

.star-rating a {
  float: right;
  color: #95a5a6; /* gris (normal) */
}
  .star-rating a:hover {
    color: #f39c12; /* amarillo (seleccionado) */
  }
  .star-rating a:hover ~ a {
    color: #f39c12; /* amarillo (seleccionado) */
  }

Ejemplo en JS Bin