Radio buttons y checkboxes iguales en todos los navegadores usando sólo CSS3

Cada navegador le da a los elementos de tipo input la apariencia que ellos definen, y dicha apariencia no puede ser personalizada de forma directa en todos los navegadores. Para radio buttons y checboxes, es posible resolver esta limitación usando sólo CSS3; no es necesario agregar dependencias a nuestro proyecto.

El truco es usar CSS para esconder el elemento input nativo, y luego agregar un elemento span vacío como el primer hijo de la label del input. Tener una label asociada al input nos permite usar la sintaxis "+" de CSS3 para seleccionar esos casos particulares, y luego seleccionar el elemento span hijo del label para darle la apariencia personalizada que reemplazará al radio button.

De esta manera, si deseáramos personalizar nuestros radio buttons, primero, en HTML, es preciso agregar labels y un elemento span vacío dentro de cada una. Por ejemplo:

<!doctype html >
<html>
<div>
	<input type="radio" id="radio01" name="radio" />
	<label for="radio01"><span></span>Radio Button 1</label>
</div>
<div>
	<input type="radio" id="radio02" name="radio" />
	<label for="radio02"><span></span>Radio Button 2</label>
</div>
</html>

Nótese como cada label referencia a un input por su id, usando el atributo for. Además, y esto es esencial, el primer hijo de la label es un span vacío. Eso es lo que aprovecharemos con nuestro CSS:

/* Escondemos el radio button nativo */
input[type="radio"] {
    display: none;
}

/* Le damos estilo al texto del label */
input[type="radio"] + label {
    color: orange;
    font-family: Arial, sans-serif;
    font-size: 14px;
}

/* Le damos formato al radio button no seleccionado, o sea el span vacío.
 * En este ejemplo lo hacemos negro y circular */
input[type="radio"] + label span {
    background-color: black;
    display: inline-block;
    width: 19px;
    height: 19px;
    margin:-1px 4px 0 0;
    vertical-align: middle;
    cursor:pointer;
    -moz-border-radius: 50%;
    border-radius: 50%;
}

/* Cuando el radio está seleccionado, cambiamos sólo el color
 * (se podría agregar bordes, sombra, etc) */
input[type="radio"]:checked + label span{
     background-color: orange;
}

/* Opcional: Animaciones para cambios de estado */
input[type="radio"] + label span,
input[type="radio"]:checked + label span {
  -webkit-transition:background-color 0.4s linear;
  -o-transition:background-color 0.4s linear;
  -moz-transition:background-color 0.4s linear;
  transition:background-color 0.4s linear;
}

Es necesario tener en cuenta que al usar esta solución hay que evitar introducir elementos de tipo span dentro de la label; si eso se hace, serán reemplazados por el radio button y el resultado será horrible. Si es necesario usar un span en la label, se puede usar un p (paragraph) con display: inline en su lugar.

Esta misma idea puede usarse para checkboxes, y otros elementos tipo input como select, para tener una apariencia consistente en todos los navegadores. Y todo esto usando sólo CSS3, ningún framework o biblioteca es necesario.

Inspiración para este post, y demo para probar. El ejemplo usa Compass pero eso es opcional.

Comments

Popular posts from this blog

VB.NET: Raise base class events from a derived class

Apache Kafka - I - High level architecture and concepts

C++/CLI: Convert a String to BSTR or some other nasty stuff