CSS es un lenguaje que nos permite hacer maravillas visuales. Pero aún así hay algunos elementos que no podemos editar vía CSS. Unos de ellos son los checkboxes y los radios.

Un ejemplo:

<input type="checkbox" value="verde" id="input-verde" name="coloresPreferidos">
<label for="input-verde">verde</label>

<input type="checkbox" value="rojo" id="input-rojo" name="coloresPreferidos">
<label for="input-rojo">rojo</label>

<!-- Más... -->

¿Qué colores te gustan?

<input type="radio" value="verde" id="input-verde" name="colorfavorito">
<label for="input-verde">verde</label>

<input type="radio" value="rojo" id="input-rojo" name="colorfavorito">
<label for="input-rojo">rojo</label>

<!-- Más... -->

¿Cuál te gusta más?

Como os habréis fijado, es imposible estilizarlos (cambiar los colores, el fondo, etc). Pero con CSS3 podemos ocultarlos (con la propiedad clip por accesibilidad), y usar los pseudoelementos de la etiqueta <label> para mostrar los diferentes estados del <input>. En IE 6, 7 y 8, que no soportan la pseudoclase :checked, mostraremos la casilla por defecto.

Así que vamos allá:

/*
* Ocultarlo siendo accesible
*/
.custom-radio, .custom-checkbox {
clip: rect(1px 1px 1px 1px);
clip: rect(1px, 1px, 1px, 1px);
position: absolute;
}

/*
* Dejar espacio a la 'label' para posicionar el checkbox hecho con pseudoelementos
*/
.custom-radio + label, .custom-checkbox + label {
position: relative;
padding-left: 16px;
}
/*
* El pseudoelemento que emulará el input
*/
.custom-radio + label:before, .custom-checkbox + label:before {
content: "";
display: inline-block;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
font-weight: bold;
font-size: 10px;
width: 13px;
height: 13px;
line-height: 11px;
text-align: center;
position: absolute;
left: 0;
top: 50%;
margin-top: -6.5px;
background: white;
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffffff), color-stop(100%, #dddddd));
background-image: -webkit-linear-gradient(#ffffff, #dddddd);
background-image: -moz-linear-gradient(#ffffff, #dddddd);
background-image: -o-linear-gradient(#ffffff, #dddddd);
background-image: linear-gradient(#ffffff, #dddddd);
zoom: 1;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffff, endColorstr=#dddddd);
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#dddddd')";
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
border-radius: 3px;
border: 1px solid #aaa;
}
/*
* Fondo para cuando se pasa el ratón por encima
*/
.custom-radio + label:hover:before, .custom-checkbox + label:hover:before {
background: #fafafa;
}

/*
* Fondo para cuando se está haciendo click
* Con filtros para ie9
*/
.custom-radio + label:active:before, .custom-checkbox + label:active:before {
background: #f2f2f2;
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #dddddd), color-stop(100%, #ffffff));
background-image: -webkit-linear-gradient(#dddddd, #ffffff);
background-image: -moz-linear-gradient(#dddddd, #ffffff);
background-image: -o-linear-gradient(#dddddd, #ffffff);
background-image: linear-gradient(#dddddd, #ffffff);
zoom: 1;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#dddddd, endColorstr=#ffffff);
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr='#dddddd', endColorstr='#ffffff')";
}

/*
* Redondear el botón "radio"
* Sobreescribimos el border-radius: 3px general
*/
.custom-radio + label:before {
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
-ms-border-radius: 50%;
-o-border-radius: 50%;
border-radius: 50%;
}
/*
* Mostrar un punto cuando está seleccionado el "radio"
* Usamos box-shadow para simular un fondo gris, mientras que dejamos un pequeño
* espacio para el punto negro (#444), que es el fondo
*/
.custom-radio:checked + label:before {
background: #444;
-webkit-box-shadow: 0 0 0 3px #eeeeee inset;
-moz-box-shadow: 0 0 0 3px #eeeeee inset;
box-shadow: 0 0 0 3px #eeeeee inset;
}

/*
* Estilos focus para la gente que navega con el teclado, etc
*/
.custom-radio:focus + label:before,
.custom-checkbox:focus + label:before {
outline: 1px dotted;
}

/* Mostrar la "X" cuando está chequeada (sólo el checkbox).
* Podríamos usar una fuente de iconos para mostrar un tic
*/
.custom-checkbox:checked + label:before {
content: "X";
}


/*
* Sólo para IE 6, 7 y 8 (no soportado)
*/
@media \0screen\,screen\9 {
.custom-radio,
.custom-checkbox {
clip: auto;
position: static;
}

.custom-radio + label,
.custom-checkbox + label {
padding-left: 0;
}

.custom-radio + label:before,
.custom-checkbox + label:before {
display: none;
}
}

El resultado es el siguiente (añadiendo a los input la clase custom-radio o custom-checkbox dependiendo del atributo type):

¿Cuál te gusta más?

¿Qué colores te gustan?