Aplicar estilos CSS a campos radio y checkbox
Un problema típico de los formularios es dar estilos personalizados a los elementos input de tipo radio y checkbox. Aunque se les pueden aplicar algunas propiedades de CSS como width, height o box-shadow, lo cierto es que poco más se puede hacer con estos elementos.
Pero ojo, en este artículo no vamos a ver como dar estilos a los propios elementos input…
Los estilos personalizados se los vamos a dar a los pseudo-elementos :after y :before del label asociado a cada input, dependiendo de si este tiene la propiedad checked (si está checkeado) o no.
¿Y por que no damos estilos directamente a los pseudo-elementos de los input…?
Sería una opción más limpia, pero algunos navegadores (Firefox & Edge) no reconocen los pseudo-elementos :after y :before en los input, así que, tenemos que usar los pseudo-elementos de los label asociados al input , de esta manera aprovecharemos la “zona de selección” del label como podremos ver más adelante.
HTML
La estructura HTML es muy importante, ya que después con CSS podremos dar estilos a los elementos dependiendo de como estén colocados.
Si ponemos el input y a continuación el label podemos crear un estilo del tipo input:checked+label que solo se aplicará cuando el input esté checkeado.
<input type="checkbox" id="check1" ><label for="check1">Check me!</label>
Con los input de tipo radio igual, primero ponemos el input y después el label :
<input type="radio" id="radio1"><label for="radio1">Radio 1</label>
<input type="radio" id="radio2"><label for="radio2">Radio 2</label>
Manteniendo esa estructura podemos hacer lo que queramos: flotar elementos, rodearlos con un contenedor, meterlos en una lista, ocultarlos…
CSS
Teniendo en cuenta la anterior estructura HTML para los input y sus label podemos crear los siguientes estilos CSS:
input[type="checkbox"] + label {
color: red;
}
Con esta regla de CSS decimos que cualquier label que esté inmediatamente detrás de un input de tipo checkbox tendrá el color del texto rojo.
Pseudo-clase :checked
Y con el selector de la pseudo-clase :checked podemos modificar los estilos del label cuando el input está checkeado. Solo hay que añadir el selector :checked al input para, por ejemplo, cambiar el color del texto del label :
input[type="checkbox"]:checked + label {
color: blue;
}
Con esta regla de CSS decimos que cualquier label que esté inmediatamente detrás de un input de tipo checkbox que esté checkeado tendrá el color del texto azul.
En este punto podemos dar estilos a los label de los checkbox checkeados, a sus pseudo-elementos o a cualquier otro elemento que queramos poner dentro o a continuación de los label como pueden ser span , img , etc… mientras se mantengan detrás del input checkeado.
Hay que tener en cuenta que la idea de usar el label es por su propiedad de “zona de selección” para el input. Al asociar los label a sus input mediante el atributo for hacemos que cualquier elemento dentro del label sea clickable y haga que se marque o se desmarque el checkbox o el radio input asociado a ese label.
Pseudo-elementos :before y :after
Con los selectores de los pseudo-elementos :before y :after del label asociado a cada input podemos crear nuestro checkbox personalizado. Olvidamos los estilos anteriores y empezamos de cero.
:before
Con el :before creamos el recuadro del checkbox, primero para cuando no esta checkeado y después añadimos un color de borde diferente para cuando si lo está:
input[type="checkbox"] + label:before {
content: "";
width: 26px;
height: 26px;
float: left;
margin: 0.5em 0.5em 0 0
border: 2px solid #ccc;
background: #fff;
}
input[type="checkbox"]:checked + label:before {
border-color: #0fbf12;
}
:after
Con el :after creamos la marca del checkbox, pero solo para cuando esté checkeado, lo haremos, como ya hemos visto, con el selector :checked :
input[type="checkbox"]:checked + label:after {
content: "";
width: 12px;
height: 6px;
border: 4px solid #0fbf12;
float: left;
margin-left: -1.95em;
border-right: 0;
border-top: 0;
margin-top: 1em;
transform: rotate(-55deg);
}
Ajustando la propiedad margin-left podemos tapar el input, pero también podemos ocultarlo y no influirá a la hora de checkearlo.
input[type="checkbox"] {
display: none;
}
Solo queda ajustar el texto para que cuadre con el checkbox , modificar el cursor con la propiedad pointer y ya que estamos pues creamos dos estilos, sin checkear (gris) y checkeado (verde):
input[type="checkbox"] + label {
font-weight: bold;
line-height: 3em;
color: #ccc;
cursor: pointer;
}
input[type="checkbox"]:checked + label {
color: #0fbf12;
}
Para los input de tipo radio sería exactamente igual, lo único que hay que tener en cuenta es que suelen ser redondos…
Esto se soluciona fácilmente añadiendo la propiedad border-radius al pseudoelemento :before :
input[type="radio"] + label:before {
content: "";
width: 26px;
height: 26px;
float: left;
margin: 0.5em 0.5em 0 0
border: 2px solid #ccc;
background: #fff;
border-radius: 100%;
}
Y la marca de checkeado también debería ser redonda, por lo que el pseudoelemento :after quedaría así:
input[type="radio"]:checked + label:after {
content: "";
width: 0;
height: 0;
border: 8px solid #0fbf12;
float: left;
margin-left: -1.8em;
margin-top: 0.8em;
border-radius: 100%;
}
Obviamente podemos añadir estilos para los estados :hover y :disabled aunque solo recomiendo el último ya que el :hover puede resultar confuso. Al checkearlo o des-checkearlo (como el puntero está sobre él) se activa el :hover y el usuario ya no sabe si está checkeado o no.
Demo
Dejo por aquí una demo donde se incluyen estilos para los input de tipo radio y checkbox. También hay estilos para el estado :disabled :
En Codepen podéis ver la demo a tamaño completo.
Tetris Arcade Game - Atari 1988
Mas Toggle Switches con CSS
Fenómenos Meteorológicos con PUG y SASS
Live Coding Videos
Selector de color
Fuentes de Google
Soporte por navegadores
Manipulación de imágenes
Editor de código
Validador de código
Gráficas en Javascript
Me ha encantado lo bien que lo explicas todo y que luego vengan los ejemplos visuales, me ha servido para mucho la verdad. Muchas gracias!
Para las etiquetas select y option también se podría hacer? Sobre todo me trae de cabeza el bg azul al clicar sobre la opción. Por si te animas hacer un post de ello, seguro nos ayudas mucho más. Slds
Hola Bea, me alegro de que el artículo te haya servido, esa es la intención. A veces pienso que me excedo explicando algunas cosas, pero lo escribo pensando en como me gustaría encontrarlo a mi.
Para lo del
selecty eloptionque comentas, algo se puede hacer para darles algún estilo con CSS pero está más limitado que en losinput, ya que ellabelque usamos con losinputen elselectaplica solo alselect, no a cada uno de losoption. Y lo del color azul al pasar por encima de cada opción… me suena que solo con CSS no se podía quitar. Seguramente con Javascript se podrá hacer algo más, habrá que investigarlo.Gracias por tu comentario Bea!
Aupa!