2023-12-23
Crear un "interruptor" en HTML y CSS
HTML
La idea es crear un elemento que contenga un input del tipo checkbox. La estructura en HTML queda así:
<label class="switch"> <input type="checkbox"> <span class="slider"></span> </label>
Podemos ver que tenemos una label que dentro contiene el input y un span que no contiene nada. El objetivo es simple: el checkbox servirá para saber el estado (pulsado o no), pero no deberá ser mostrado; el span vacío será el que hará la visualización y "simulará" la posición del interruptor.
CSS
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
La estilo "switch" del label tendrá un tamaño de 60x34px y tendrá que tener una posición relativa para que luego podamos usar absoluta en el span. Lo mostramos como inline-block.
.switch input {
opacity: 0;
width: 0;
height: 0;
}
Establecemos un tamaño de 0x0px al input y le ponemos su opacity a 0 haciendo que el input no se vea.
.slider {
position: absolute;
cursor: pointer;
top:0;
left:0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
El span con estilo "slider" tendrá una posición absoluta dentro del "label" y ocupará todo el tamaño (las propiedades top, left, right y bottom a cero se encargan de eso. También le indicaremos que se vea el puntero cuando pasamos el ratón por encima.
Añadimos una transición para cuando cambiamos los estilos no sea brusco.
Con lo que hemos hecho hasta ahora solo veremos un rectángulo de color gris del tamaño de 60x34px
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
Con ":before" añadimos creamos un recuadro dentro del slider que simulará el botón. Igualmente le asignamos la posición de manera absoluta y le asignamos un tamaño y color diferente al del fondo del slider.
Con esto ya tenemos la base de nuestro interruptor.
Ahora tenemos que hacer que cambie la forma según el estado del checkbox. Hasta ahora solo hemos hecho la parte de cuando está inactivo.
input:checked + .slider {
background-color: #2196F3;
}
Esta regla coge el primer elemento que sigue al input cuando está activo, este será el .slider. Con esta regla solo cambiamos el color de fondo del slider y tan solo eso, tendremos que hacer que nuestro símil de interruptor se mueva:
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
Hemos de hacer que cuando el input este activo el "slider:before" cambie de posición, usamos para ello transform y translateX.
Y ya tenemos nuestro interruptor en funcionamiento.
Si quisiéramos hacer que nuestro interruptor tuviera los border redondos tan solo tendríamos que poner las reglas:
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
Tan solo una última consideración. Los tamaños se han elegido bien calculados para que cada elemento esté bien ubicado. Si modificamos el tamaño del botón en la regla "switch" deberemos modificar también el tamaño del "slider" así como sus posiciones absolutas y transformaciones que hemos hecho.
JavaScript
Por si solo el input checked no vale de nada, lo interesante es darle alguna funcionalidad y para ello hemos de recurrir a JavaScript.
Un ejemplo útil puede ser usando AJAX de la siguiente manera:
<script>
function toggleCheckbox(element) {
var xhr = new XMLHttpRequest();
if(element.checked){
xhr.open("GET", "/update?relay="+element.id+"&state=1", true);
}
else {
xhr.open("GET", "/update?relay="+element.id+"&state=0", true);
}
xhr.send();
}
</script>
Esta función es un ejemplo para usar con un ESP32 o similar, donde lo que hacemos es que al cambiar el estado del input enviamos una petición GET con los parámetros relay+id del check y un booleano state para encender o apagar el relé.
Obviamente tenemos que modificar el HTML para que se llame a la función toggleCheckbox() :
<label class="switch"> <input type="checkbox" onchange="toggleCheckbox(this)" id="id"> <span class="slider"></span> </label>
Resultado:
Interruptor cuadrado:
Interruptor redondo:
Referencias
Tutorial de como encender y apagar relés con un ESP8266
w3schools - How TO - Toggle Switch