¿Cómo se crea un botón de alternancia?

98

Quiero crear un botón de alternancia en html usando css. Lo quiero para que cuando haga clic en él, se mantenga presionado y luego cuando haga clic en él nuevamente, salga.

Si no hay forma de hacerlo, simplemente use css. ¿Hay alguna forma de hacerlo usando jQuery?

Donny V.
fuente
Escribí un tutorial sobre cómo crear interruptores de encendido / apagado solo con CSS3, no se necesita JS. Aquí puede ver la demostración
Felix Hagspiel

Respuestas:

87

La buena forma semántica sería usar una casilla de verificación y luego diseñarla de diferentes maneras si está marcada o no. Pero no hay buenas formas de hacerlo. Tienes que agregar espacio adicional, div adicional y, para una apariencia realmente agradable, agregar algo de javascript.

Entonces, la mejor solución es usar una pequeña función jQuery y dos imágenes de fondo para diseñar los dos estados diferentes del botón. Ejemplo con un efecto arriba / abajo dado por bordes:

$(document).ready(function() {
  $('a#button').click(function() {
    $(this).toggleClass("down");
  });
});
a {
  background: #ccc;
  cursor: pointer;
  border-top: solid 2px #eaeaea;
  border-left: solid 2px #eaeaea;
  border-bottom: solid 2px #777;
  border-right: solid 2px #777;
  padding: 5px 5px;
}

a.down {
  background: #bbb;
  border-top: solid 2px #777;
  border-left: solid 2px #777;
  border-bottom: solid 2px #eaeaea;
  border-right: solid 2px #eaeaea;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="button" title="button">Press Me</a>

Obviamente, puede agregar imágenes de fondo que representen el botón hacia arriba y hacia abajo, y hacer que el color de fondo sea transparente.

alexmeia
fuente
17
Aquí hay un violín JS con este código para que pueda probarlo en vivo ... jsfiddle.net/LmULE
Evan
FYI: Hice lo mismo que en esta publicación, solo usando Google Dart steelpinjata.com/2014/03/20/toggle-buttons-in-dart . Nota: funciona en Chromium, pero se puede compilar en JavaScript y funcionará en otros navegadores modernos. IE no cuenta como navegador ;-)
Serge Merzliakov
50

JQuery UI simplifica la creación de botones de alternancia. Solo pon esto

<label for="myToggleButton">my toggle button caption</label>
<input type="checkbox" id="myToggleButton" />

en su página y luego en su cuerpo onLoado su $.ready()(o algunos objetos literales init()funcionan si está construyendo un sitio ajax ...) suelte algo de JQuery así:

$("#myToggleButton").button()

Eso es. (no olvides el< label for=...> porque JQueryUI lo usa para el cuerpo del botón de alternancia ..)

A partir de ahí, simplemente trabajas con él como cualquier otro input="checkbox"porque eso es lo que sigue siendo el control subyacente, pero la interfaz de usuario de JQuery simplemente lo aplica para que parezca un bonito botón de alternancia en la pantalla.

bkdraper
fuente
Dado que el OP agregó la etiqueta jquery, esta es una gran respuesta. Dado que jqueryUI podría usarse para proporcionar un estilo congruente.
Joe Johnston
28

aquí hay un ejemplo usando pure css:

  .cmn-toggle {
    position: absolute;
    margin-left: -9999px;
    visibility: hidden;
  }
  .cmn-toggle + label {
    display: block;
    position: relative;
    cursor: pointer;
    outline: none;
    user-select: none;
  }
  input.cmn-toggle-round + label {
    padding: 2px;
    width: 120px;
    height: 60px;
    background-color: #dddddd;
    border-radius: 60px;
  }
  input.cmn-toggle-round + label:before,
  input.cmn-toggle-round + label:after {
    display: block;
    position: absolute;
    top: 1px;
    left: 1px;
    bottom: 1px;
    content: "";
  }
  input.cmn-toggle-round + label:before {
    right: 1px;
    background-color: #f1f1f1;
    border-radius: 60px;
    transition: background 0.4s;
  }
  input.cmn-toggle-round + label:after {
    width: 58px;
    background-color: #fff;
    border-radius: 100%;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
    transition: margin 0.4s;
  }
  input.cmn-toggle-round:checked + label:before {
    background-color: #8ce196;
  }
  input.cmn-toggle-round:checked + label:after {
    margin-left: 60px;
  }
<div class="switch">
  <input id="cmn-toggle-1" class="cmn-toggle cmn-toggle-round" type="checkbox">
  <label for="cmn-toggle-1"></label>
</div>

suhailvs
fuente
19

En combinación con esta respuesta, también puede usar este tipo de estilo que es como alternador de configuraciones móviles.

alternadores

HTML

<a href="#" class="toggler">&nbsp;</a>
<a href="#" class="toggler off">&nbsp;</a>
<a href="#" class="toggler">&nbsp;</a>

CSS

a.toggler {
    background: green;
    cursor: pointer;
    border: 2px solid black;
    border-right-width: 15px;
    padding: 0 5px;
    border-radius: 5px;
    text-decoration: none;
    transition: all .5s ease;
}

a.toggler.off {
    background: red;
    border-right-width: 2px;
    border-left-width: 15px;
}

jQuery

$(document).ready(function(){
    $('a.toggler').click(function(){
        $(this).toggleClass('off');
    });
});

Podría ser mucho más bonito, pero da la idea.
Una ventaja es que se puede animar con jquery y / o CSS3
Fiddler

Pierre de LESPINAY
fuente
7

Si desea un botón adecuado, necesitará algo de javascript. Algo como esto (necesita algo de trabajo en el estilo pero entiendes la esencia). No me molestaría en usar jquery para algo tan trivial para ser honesto.

<html>
<head>
<style type="text/css">
.on { 
border:1px outset;
color:#369;
background:#efefef; 
}

.off {
border:1px outset;
color:#369;
background:#f9d543; 
}
</style>

<script language="javascript">
function togglestyle(el){
    if(el.className == "on") {
        el.className="off";
    } else {
        el.className="on";
    }
}
</script>

</head>

<body>
<input type="button" id="btn" value="button" class="off" onclick="togglestyle(this)" />
</body>
</html>
mono hacer
fuente
4

Puede usarlo toggleClass()para rastrear el estado. Luego verifica si el elemento del botón tiene la clase, así:

$("button.toggler").click( function() {
    $me = $(this);
    $me.toggleClass('off');
    if($me.is(".off")){
        alert('hi');
    }else {
        alert('bye');
    }
});

Y uso el buttonelemento para botones por razones semánticas.

<button class="toggler">Toggle me</button>
tim
fuente
3

Podrías usar un elemento de anclaje (<a></a> ) y usar un enlace: activo y: para cambiar la imagen de fondo para activar o desactivar. Solo un pensamiento.

Editar: el método anterior no funciona demasiado bien para alternar. Pero no es necesario utilizar jquery. Escriba una función simple de javascript onClick para el elemento, que cambie la imagen de fondo de manera apropiada para que parezca que el botón está presionado, y establezca alguna bandera. Luego, en el siguiente clic, se revierte la imagen y la bandera. Al igual que

var flag = 0;
function toggle(){
if(flag==0){
    document.getElementById("toggleDiv").style.backgroundImage="path/to/img/img1.gif";
    flag=1;
}
else if(flag==1){
    document.getElementById("toggleDiv").style.backgroundImage="path/to/img/img2.gif";
    flag=0;
}
}

Y el html así <div id="toggleDiv" onclick="toggle()">Some thing</div>

anand.trex
fuente
3

No creo que usar JS para crear un botón sea una buena práctica. ¿Qué pasa si el navegador del usuario desactiva JavaScript?

Además, puede usar una casilla de verificación y un poco de CSS para hacerlo. Y es fácil recuperar el estado de su casilla de verificación.

Este es solo un ejemplo, pero puede diseñarlo como desee.

http://jsfiddle.net/4gjZX/

HTML

<fieldset class="toggle">
  <input id="data-policy" type="checkbox" checked="checked" />
  <label for="data-policy">
  <div class="toggle-button">
    <div class="toggle-tab"></div>
  </div>
  Toggle
  </label>
</fieldset>

CSS

.toggle label {
  color: #444;
  float: left;
  line-height: 26px;
}
.toggle .toggle-button {
  margin: 0px 10px 0px 0px;
  float: left;
  width: 70px;
  height: 26px;
  background-color: #eeeeee;
  background-image: -webkit-gradient(linear, left top, left bottom, from(#eeeeee), to(#fafafa));
  background-image: -webkit-linear-gradient(top, #eeeeee, #fafafa);
  background-image: -moz-linear-gradient(top, #eeeeee, #fafafa);
  background-image: -o-linear-gradient(top, #eeeeee, #fafafa);
  background-image: -ms-linear-gradient(top, #eeeeee, #fafafa);
  background-image: linear-gradient(top, #eeeeee, #fafafa);
  filter: progid:dximagetransform.microsoft.gradient(GradientType=0, StartColorStr='#eeeeee', EndColorStr='#fafafa');
  border-radius: 4px;
  -webkit-border-radius: 4px;
  -moz-border-radius: 4px;
  border: 1px solid #D1D1D1;
}
.toggle .toggle-button .toggle-tab {
  width: 30px;
  height: 26px;
  background-color: #fafafa;
  background-image: -webkit-gradient(linear, left top, left bottom, from(#fafafa), to(#eeeeee));
  background-image: -webkit-linear-gradient(top, #fafafa, #eeeeee);
  background-image: -moz-linear-gradient(top, #fafafa, #eeeeee);
  background-image: -o-linear-gradient(top, #fafafa, #eeeeee);
  background-image: -ms-linear-gradient(top, #fafafa, #eeeeee);
  background-image: linear-gradient(top, #fafafa, #eeeeee);
  filter: progid:dximagetransform.microsoft.gradient(GradientType=0, StartColorStr='#fafafa', EndColorStr='#eeeeee');
  border: 1px solid #CCC;
  margin-left: -1px;
  margin-top: -1px;
  border-radius: 4px;
  -webkit-border-radius: 4px;
  -moz-border-radius: 4px;
  -webkit-box-shadow: 5px 0px 4px -5px #000000, 0px 0px 0px 0px #000000;
  -moz-box-shadow: 5px 0px 4px -5px rgba(0, 0, 0, 0.3), 0px 0px 0px 0px #000000;
  box-shadow: 5px 0px 4px -5px rgba(0, 0, 0, 0.3), 0px 0px 0px 0px #000000;
}
.toggle input[type=checkbox] {
  display: none;
}
.toggle input[type=checkbox]:checked ~ label .toggle-button {
  background-color: #2d71c2;
  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d71c2), to(#4ea1db));
  background-image: -webkit-linear-gradient(top, #2d71c2, #4ea1db);
  background-image: -moz-linear-gradient(top, #2d71c2, #4ea1db);
  background-image: -o-linear-gradient(top, #2d71c2, #4ea1db);
  background-image: -ms-linear-gradient(top, #2d71c2, #4ea1db);
  background-image: linear-gradient(top, #2d71c2, #4ea1db);
  filter: progid:dximagetransform.microsoft.gradient(GradientType=0, StartColorStr='#2d71c2', EndColorStr='#4ea1db');
}
.toggle input[type=checkbox]:checked ~ label .toggle-button .toggle-tab {
  margin-left: 39px;
  -webkit-box-shadow: -5px 0px 4px -5px #000000, 0px 0px 0px 0px #000000;
  -moz-box-shadow: -5px 0px 4px -5px rgba(0, 0, 0, 0.3), 0px 0px 0px 0px #000000;
  box-shadow: -5px 0px 4px -5px rgba(0, 0, 0, 0.3), 0px 0px 0px 0px #000000;
}​

Espero que esto ayude

Titouan de Bailleul
fuente
2

Me inclinaría a usar una clase en su CSS que altera el estilo del borde o el ancho del borde cuando se presiona el botón, por lo que da la apariencia de un botón de alternancia.

Galwegian
fuente
1

Prueba este bit:

input type="button" 
                           data-bind="css:{on:toggleButton, off:toggleButton!=true},value:toggleButton,click: function() { $data.toggleButton(!($data.toggleButton()))}" />

in viewModel
self.toggleButton = ko.observable(false);
Pedro
fuente
0

Puede usar la pseudoclase "activa" (aunque no funcionará en IE6 para elementos que no sean enlaces)

a:active
{
    ...desired style here...
}
pilsetnieks
fuente
0

Aquí está uno de los ejemplos / variantes (más detalles descritos) de ToggleButton usando jQuery con <label for="input"> implementación.

Primero crearemos un contenedor para nuestro ToggleButton usando HTML clásico <input>y<label>

<span>
  <input type="checkbox" value="1" name="some_feature_to_select" id="feature_cb" style="display: none;"> <!-- We can hide checkbox bec. we want <label> to be a ToggleButton, so we don't need to show it. It is used as our value holder -->
  <label for="feature_cb" id="label_for_some_feature">
    <img alt="Stylish image" src="/images/icons/feature.png">
  </label>
</span>

A continuación, definiremos la función para alternar nuestro botón. Nuestro botón en realidad es el habitual, <label>que diseñaremos para representar el cambio de valor.

function toggleButton(button) {

var _for = button.getAttribute('for'); // defining for which element this label is (suppose element is a checkbox (bec. we are making ToggleButton ;) )
var _toggleID = 'input#'+_for; // composing selector ID string to select our toggle element (checkbox)
var _toggle = $( _toggleID ); // selecting checkbox to work on
var isChecked = !_toggle.is(':checked'); // defining the state with negation bec. change value event will have place later, so we negating current state to retrieve inverse (next).

if (isChecked)
    $(button).addClass('SelectedButtonClass'); // if it is checked -> adding nice class to our button (<label> in our case) to show that value was toggled
else
    $(button).removeClass('SelectedButtonClass'); // if value (or feature) was unselected by clicking the button (<label>) -> removing .SelectedButtonClass (or simply removing all classes from element)
}

La función se implementa de forma reutilizable. Puede usarlo para más de uno, dos o incluso tres ToggleButtons que haya creado.

... y finalmente ... para que funcione como se esperaba, debemos vincular la función de alternancia a un evento (evento de "cambio") de nuestro <label>botón improvisado (será un clickevento porque no estamos alterando el checkboxdirectamente, por lo que no hay changeevento puede ser despedido <label>).

$(document).ready(function(){

    $("#some_feature_label").click(function () {
        toggleButton(this); // call function with transmitting instance of a clicked label and let the script decide what was toggled and what to do with it
    });

    $("#some_other_feature_label").click(function () {
        toggleButton(this); // doing the same for any other feature we want to represent in a way of ToggleButton
    });

});

Con CSS podemos definir backgorund-imageo algunos borderpara representar el cambio de valor mientras<label> que hará el trabajo por nosotros al alterar el valor de una casilla de verificación;).

Espero que esto ayude a alguien.

Paul T. Rawkeen
fuente
+ esta implementación parece funcionar correctamente también en dispositivos móviles, bec. La implementación de CCS propuesta anteriormente por TDeBailleul no funcionaba correctamente en Android (navegador predeterminado de Android 2.3.5; Opera Mobile en el mismo sistema estaba bien).
Paul T. Rawkeen
Además, en lugar de .addClass()/ .removeClass()puede usar .toggleClass(), pero el método descrito define explícitamente acciones para checked/ uncheckedvalores.
Paul T. Rawkeen
0

Tratar;

<li>Text To go with Toggle Button<span class = 'toggle'><input type = 'checkbox' class = 'toggle' name = 'somename' id = 'someid' /></span></li>

Y asegúrate de

<head><link rel = 'stylesheet' src = 'theme.css'> (from jqtouch - downloadable online)
      <link rel = 'text/javascript' src = 'jquery.js'> (also from jqtouch)
</head>

Recuerde cuando está codificando esto, solo somename y someidpuede cambiar en la etiqueta de entrada, de lo contrario no funciona.

ЯegDwight
fuente
0

En lo que respecta a la búsqueda de la respuesta también, y quería lograrlo con CSS. Encontré una solución por CSS NINJA ¡Es una buena impulsión <input type="checkbox">y una demostración en vivo de css ! Aunque no funciona en IE 8, ¡podría implementar selectivizr ! y arreglar CSS donde se usa opacityparafilter que funcione en IE.

EDITAR 2014:

para los nuevos botones de alternancia, utilizo una solución que se encuentra en el blog de Lea Verou visualmente similar a la casilla de verificación de iOS

Aivaras
fuente