Cómo diseñar una casilla de verificación usando CSS

Resuelto Salman Virk asked hace 14 años • 45 respuestas

Estoy intentando diseñar una casilla de verificación usando lo siguiente:

<input type="checkbox" style="border:2px dotted #00f;display:block;background:#ff0000;" />
Expandir fragmento

Pero el estilo no se aplica. La casilla de verificación todavía muestra su estilo predeterminado. ¿Cómo le doy el estilo especificado?

Salman Virk avatar Nov 11 '10 02:11 Salman Virk
Aceptado

ACTUALIZAR:

La siguiente respuesta hace referencia al estado de las cosas antes de la disponibilidad generalizada de CSS 3. En los navegadores modernos (incluido Internet Explorer 9 y posteriores) es más sencillo crear reemplazos de casillas de verificación con su estilo preferido, sin usar JavaScript.

Aquí hay algunos enlaces útiles:

  • Crear casillas de verificación de formulario personalizadas con solo CSS
  • Generador de casillas de verificación CSS sencillo
  • Cosas que puedes hacer con el truco de la casilla de verificación
  • Implementación de casillas de verificación personalizadas y botones de opción con CSS3
  • Cómo diseñar una casilla de verificación con CSS

Vale la pena señalar que la cuestión fundamental no ha cambiado. Aún no puede aplicar estilos (bordes, etc.) directamente al elemento de casilla de verificación y hacer que esos estilos afecten la visualización de la casilla de verificación HTML. Sin embargo, lo que ha cambiado es que ahora es posible ocultar la casilla de verificación real y reemplazarla con un elemento de estilo propio, usando nada más que CSS. En particular, debido a que CSS ahora tiene un :checkedselector ampliamente compatible, puede hacer que su reemplazo refleje correctamente el estado marcado de la casilla.


RESPUESTA ANTIGUA

Aquí hay un artículo útil sobre cómo diseñar casillas de verificación . Básicamente, ese escritor descubrió que varía enormemente de un navegador a otro, y que muchos navegadores siempre muestran la casilla de verificación predeterminada sin importar cómo la diseñe. Entonces realmente no hay una manera fácil.

No es difícil imaginar una solución alternativa en la que usaría JavaScript para superponer una imagen en la casilla de verificación y hacer clic en esa imagen provocaría que se marcara la casilla de verificación real. Los usuarios sin JavaScript verían la casilla de verificación predeterminada.

Editado para agregar: aquí hay un buen script que hace esto por usted ; oculta el elemento de casilla de verificación real, lo reemplaza con un intervalo con estilo y redirige los eventos de clic.

Jacob Mattison avatar Nov 10 '2010 20:11 Jacob Mattison

Puedes lograr un efecto de casilla de verificación personalizado bastante interesante usando las nuevas habilidades que vienen con las pseudoclases :aftery . :beforeLa ventaja de esto es que no necesita agregar nada más al DOM, solo la casilla de verificación estándar.

Tenga en cuenta que esto sólo funcionará para navegadores compatibles. Creo que esto está relacionado con el hecho de que algunos navegadores no le permiten configurar :afterelementos :beforede entrada. Lo que desafortunadamente significa que por el momento sólo se admiten navegadores WebKit. Firefox + Internet Explorer seguirán permitiendo que las casillas de verificación funcionen, pero sin estilo, y es de esperar que esto cambie en el futuro (el código no utiliza prefijos de proveedores).

Esta es solo una solución de navegador WebKit (Chrome, Safari, navegadores móviles)

Ver ejemplo de violín

$(function() {
  $('input').change(function() {
    $('div').html(Math.random());
  });
});
/* Main Classes */
.myinput[type="checkbox"]:before {
  position: relative;
  display: block;
  width: 11px;
  height: 11px;
  border: 1px solid #808080;
  content: "";
  background: #FFF;
}

.myinput[type="checkbox"]:after {
  position: relative;
  display: block;
  left: 2px;
  top: -11px;
  width: 7px;
  height: 7px;
  border-width: 1px;
  border-style: solid;
  border-color: #B3B3B3 #dcddde #dcddde #B3B3B3;
  content: "";
  background-image: linear-gradient(135deg, #B1B6BE 0%, #FFF 100%);
  background-repeat: no-repeat;
  background-position: center;
}

.myinput[type="checkbox"]:checked:after {
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAQAAABuW59YAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAB2SURBVHjaAGkAlv8A3QDyAP0A/QD+Dam3W+kCAAD8APYAAgTVZaZCGwwA5wr0AvcA+Dh+7UX/x24AqK3Wg/8nt6w4/5q71wAAVP9g/7rTXf9n/+9N+AAAtpJa/zf/S//DhP8H/wAA4gzWj2P4lsf0JP0A/wADAHB0Ngka6UmKAAAAAElFTkSuQmCC'), linear-gradient(135deg, #B1B6BE 0%, #FFF 100%);
}

.myinput[type="checkbox"]:disabled:after {
  -webkit-filter: opacity(0.4);
}

.myinput[type="checkbox"]:not(:disabled):checked:hover:after {
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAQAAABuW59YAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAB2SURBVHjaAGkAlv8A3QDyAP0A/QD+Dam3W+kCAAD8APYAAgTVZaZCGwwA5wr0AvcA+Dh+7UX/x24AqK3Wg/8nt6w4/5q71wAAVP9g/7rTXf9n/+9N+AAAtpJa/zf/S//DhP8H/wAA4gzWj2P4lsf0JP0A/wADAHB0Ngka6UmKAAAAAElFTkSuQmCC'), linear-gradient(135deg, #8BB0C2 0%, #FFF 100%);
}

.myinput[type="checkbox"]:not(:disabled):hover:after {
  background-image: linear-gradient(135deg, #8BB0C2 0%, #FFF 100%);
  border-color: #85A9BB #92C2DA #92C2DA #85A9BB;
}

.myinput[type="checkbox"]:not(:disabled):hover:before {
  border-color: #3D7591;
}

/* Large checkboxes */
.myinput.large {
  height: 22px;
  width: 22px;
}

.myinput.large[type="checkbox"]:before {
  width: 20px;
  height: 20px;
}

.myinput.large[type="checkbox"]:after {
  top: -20px;
  width: 16px;
  height: 16px;
}

/* Custom checkbox */
.myinput.large.custom[type="checkbox"]:checked:after {
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGHRFWHRBdXRob3IAbWluZWNyYWZ0aW5mby5jb23fZidLAAAAk0lEQVQ4y2P4//8/AyUYwcAD+OzN/oMwshjRBoA0Gr8+DcbIhhBlAEyz+qZZ/7WPryHNAGTNMOxpJvo/w0/uP0kGgGwGaZbrKgfTGnLc/0nyAgiDbEY2BCRGdCDCnA2yGeYVog0Aae5MV4c7Gzk6CRqAbDM2w/EaQEgzXgPQnU2SAcTYjNMAYm3GaQCxNuM0gFwMAPUKd8XyBVDcAAAAAElFTkSuQmCC'), linear-gradient(135deg, #B1B6BE 0%, #FFF 100%);
}

.myinput.large.custom[type="checkbox"]:not(:disabled):checked:hover:after {
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGHRFWHRBdXRob3IAbWluZWNyYWZ0aW5mby5jb23fZidLAAAAk0lEQVQ4y2P4//8/AyUYwcAD+OzN/oMwshjRBoA0Gr8+DcbIhhBlAEyz+qZZ/7WPryHNAGTNMOxpJvo/w0/uP0kGgGwGaZbrKgfTGnLc/0nyAgiDbEY2BCRGdCDCnA2yGeYVog0Aae5MV4c7Gzk6CRqAbDM2w/EaQEgzXgPQnU2SAcTYjNMAYm3GaQCxNuM0gFwMAPUKd8XyBVDcAAAAAElFTkSuQmCC'), linear-gradient(135deg, #8BB0C2 0%, #FFF 100%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<table style="width:100%">
  <tr>
    <td>Normal:</td>
    <td><input type="checkbox" /></td>
    <td><input type="checkbox" checked="checked" /></td>
    <td><input type="checkbox" disabled="disabled" /></td>
    <td><input type="checkbox" disabled="disabled" checked="checked" /></td>
  </tr>
  <tr>
    <td>Small:</td>
    <td><input type="checkbox" class="myinput" /></td>
    <td><input type="checkbox" checked="checked" class="myinput" /></td>
    <td><input type="checkbox" disabled="disabled" class="myinput" /></td>
    <td><input type="checkbox" disabled="disabled" checked="checked" class="myinput" /></td>
  </tr>
  <tr>
    <td>Large:</td>
    <td><input type="checkbox" class="myinput large" /></td>
    <td><input type="checkbox" checked="checked" class="myinput large" /></td>
    <td><input type="checkbox" disabled="disabled" class="myinput large" /></td>
    <td><input type="checkbox" disabled="disabled" checked="checked" class="myinput large" /></td>
  </tr>
  <tr>
    <td>Custom icon:</td>
    <td><input type="checkbox" class="myinput large custom" /></td>
    <td><input type="checkbox" checked="checked" class="myinput large custom" /></td>
    <td><input type="checkbox" disabled="disabled" class="myinput large custom" /></td>
    <td><input type="checkbox" disabled="disabled" checked="checked" class="myinput large custom" /></td>
  </tr>
</table>
Expandir fragmento

Bono de violín flipswitch estilo Webkit

$(function() {
  var f = function() {
    $(this).next().text($(this).is(':checked') ? ':checked' : ':not(:checked)');
  };
  $('input').change(f).trigger('change');
});
body {
  font-family: arial;
}

.flipswitch {
  position: relative;
  background: white;
  width: 120px;
  height: 40px;
  -webkit-appearance: initial;
  border-radius: 3px;
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
  outline: none;
  font-size: 14px;
  font-family: Trebuchet, Arial, sans-serif;
  font-weight: bold;
  cursor: pointer;
  border: 1px solid #ddd;
}

.flipswitch:after {
  position: absolute;
  top: 5%;
  display: block;
  line-height: 32px;
  width: 45%;
  height: 90%;
  background: #fff;
  box-sizing: border-box;
  text-align: center;
  transition: all 0.3s ease-in 0s;
  color: black;
  border: #888 1px solid;
  border-radius: 3px;
}

.flipswitch:after {
  left: 2%;
  content: "OFF";
}

.flipswitch:checked:after {
  left: 53%;
  content: "ON";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>

<h2>Webkit friendly mobile-style checkbox/flipswitch</h2>
<input type="checkbox" class="flipswitch" /> &nbsp;
<span></span>
<br>
<input type="checkbox" checked="checked" class="flipswitch" /> &nbsp;
<span></span>
Expandir fragmento

Josh Mc avatar Jun 09 '2013 01:06 Josh Mc

Antes de comenzar (a partir de enero de 2015)

La pregunta y la respuesta originales tienen ahora ~5 años. Como tal, esto es una pequeña actualización.

En primer lugar, existen varios enfoques cuando se trata de diseñar casillas de verificación. El principio básico es:

  1. Deberá ocultar el control de casilla de verificación predeterminado cuyo estilo aplica su navegador y que no se puede anular de ninguna manera significativa mediante CSS.

  2. Con el control oculto, aún necesitarás poder detectar y alternar su estado marcado.

  3. El estado marcado de la casilla de verificación deberá reflejarse aplicando estilo a un nuevo elemento.

La solución (en principio)

Lo anterior se puede lograr de varias maneras, y a menudo escucharás que usar pseudoelementos CSS3 es la forma correcta. En realidad, no existe una forma realmente correcta o incorrecta, depende del enfoque más adecuado para el contexto en el que lo utilizarás. Dicho esto, prefiero uno.

  1. Envuelve tu casilla de verificación en un labelelemento. Esto significará que incluso cuando esté oculto, aún podrá alternar su estado marcado haciendo clic en cualquier lugar dentro de la etiqueta.

  2. Oculta tu casilla de verificación.

  3. Agregue un nuevo elemento después de la casilla de verificación al que le dará el estilo correspondiente. Debe aparecer después de la casilla de verificación para que pueda seleccionarse usando CSS y diseñarse según el :checkedestado. CSS no puede seleccionar "hacia atrás".

La solución (en código)

Mostrar fragmento de código

Refinamiento (usando iconos)

"¡Pero hey!" Te oigo gritar. ¿Qué pasa si quiero mostrar una pequeña marca o una cruz en la casilla? ¡Y no quiero usar imágenes de fondo!

Bueno, aquí es donde los pseudoelementos de CSS3 pueden entrar en juego. Estos admiten la contentpropiedad que le permite inyectar íconos Unicode que representan cualquiera de los estados. Alternativamente, puedes usar una fuente de íconos de fuentes de terceros, como font awesome (aunque asegúrate de configurar también el correspondiente font-family, por ejemplo, en FontAwesome)

label input {
  display: none; /* Hide the default checkbox */
}

/* Style the artificial checkbox */
label span {
  height: 10px;
  width: 10px;
  border: 1px solid grey;
  display: inline-block;
  position: relative;
}

/* Style its checked state...with a ticked icon */
[type=checkbox]:checked + span:before {
  content: '\2714';
  position: absolute;
  top: -5px;
  left: 0;
}
<label>
  <input type='checkbox'>
  <span></span>
  Checkbox label text
</label>
Expandir fragmento

SW4 avatar Jan 05 '2015 11:01 SW4

Hay una manera de hacer esto usando solo CSS. Podemos (ab)usar el labelelemento y darle estilo a ese elemento en su lugar. La advertencia es que esto no funcionará para Internet Explorer 8 y versiones inferiores.

.myCheckbox input {
  position: relative;
  z-index: -9999;
}

.myCheckbox span {
  width: 20px;
  height: 20px;
  display: block;
  background: url("link_to_image");
}

.myCheckbox input:checked + span {
  background: url("link_to_another_image");
}
<label for="test">Label for my styled "checkbox"</label>
<label class="myCheckbox">
  <input type="checkbox" name="test" />
  <span></span>
</label>
Expandir fragmento

Blake Pettersson avatar Aug 30 '2012 08:08 Blake Pettersson