Como você cria um botão de alternância?

98

Quero criar um botão de alternância em html usando css. Eu quero que quando você clicar nele, ele permaneça empurrado para dentro e quando você clicar nele novamente, ele saia.

Se não houver maneira de fazer isso apenas usando css. Existe uma maneira de fazer isso usando jQuery?

Donny V.
fonte
Escrevi um tutorial sobre como criar interruptores liga / desliga apenas com CSS3, sem necessidade de JS. Aqui você pode ver a demonstração
Felix Hagspiel

Respostas:

87

A boa maneira semântica seria usar uma caixa de seleção e, em seguida, estilizá-la de maneiras diferentes, se estiver marcada ou não. Mas não há boas maneiras de fazer isso. Você tem que adicionar extensão extra, div extra e, para uma aparência realmente agradável, adicionar algum javascript.

Portanto, a melhor solução é usar uma pequena função jQuery e duas imagens de fundo para definir o estilo dos dois status diferentes do botão. Exemplo com um efeito para cima / baixo dado por bordas:

$(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, você pode adicionar imagens de fundo que representam botão para cima e botão para baixo e tornar a cor de fundo transparente.

alexmeia
fonte
17
Aqui está um JS fiddle com este código para que você possa testá-lo ao vivo ... jsfiddle.net/LmULE
Evan
FYI: Eu fiz a mesma coisa que este post, apenas usando o Google Dart steelpinjata.com/2014/03/20/toggle-buttons-in-dart . Nota: funciona no Chromium, mas pode ser compilado para JavaScript e funcionará em outros navegadores modernos. O IE não conta como um navegador ;-)
Serge Merzliakov,
50

O JQuery UI simplifica a criação de botões de alternância. Basta colocar isso

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

em sua página e, em seguida, em seu corpo onLoadou $.ready()(ou alguns literais de objeto init()funcionam se você está construindo um site ajax ...) solte algum JQuery como:

$("#myToggleButton").button()

é isso aí. (não se esqueça do < label for=...>porque JQueryUI usa isso para o corpo do botão de alternância.)

A partir daí, você apenas trabalha com ele como qualquer outro input="checkbox"porque esse é o que o controle subjacente ainda é, mas a IU do JQuery apenas o faz parecer um botão de alternância bonito na tela.

bkdraper
fonte
Dado que o OP adicionou a tag jquery, esta é uma ótima resposta. O jqueryUI dado pode ser usado para fornecer um estilo congruente.
Joe Johnston
28

aqui está um exemplo 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
fonte
19

Em combinação com esta resposta, você também pode usar esse tipo de estilo, que é como o alternador de configurações móveis.

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');
    });
});

Poderia ser bem mais bonita, mas dá ideia.
Uma vantagem é que pode ser animado com jquery e / ou CSS3
Fiddler

Pierre de LESPINAY
fonte
7

Se você quiser um botão adequado, precisará de algum javascript. Algo assim (precisa de algum trabalho no estilo, mas você entendeu). Não me incomodaria em usar jquery para algo tão 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>
macaco faz
fonte
4

Você pode apenas usar toggleClass()para rastrear o estado. Em seguida, você verifica se o elemento botão tem a classe, assim:

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

E eu uso o buttonelemento para botões por razões semânticas.

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

Você pode usar um elemento âncora ( <a></a>) e usar um: active e um: link para alterar a imagem de fundo para ativar ou desativar. Apenas um pensamento.

Editar: O método acima não funciona muito bem para alternar. Mas você não precisa usar jquery. Escreva uma função javascript onClick simples para o elemento, que altera a imagem de fundo apropriadamente para fazer com que pareça que o botão foi pressionado, e defina um sinalizador. Então, no próximo clique, a imagem e a bandeira são revertidas. Igual a

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;
}
}

E o html assim <div id="toggleDiv" onclick="toggle()">Some thing</div>

anand.trex
fonte
3

Não acho que usar JS para criar um botão seja uma boa prática. E se o navegador do usuário desativar o JavaScript?

Além disso, você pode apenas usar uma caixa de seleção e um pouco de CSS para fazer isso. E é fácil recuperar o estado de sua caixa de seleção.

Este é apenas um exemplo, mas você pode estilizá-lo como quiser.

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 isto ajude

Titouan de Bailleul
fonte
2

Eu estaria inclinado a usar uma classe em seu css que altera o estilo ou a largura da borda quando o botão é pressionado, dando a aparência de um botão de alternância.

Galuego
fonte
1

Experimente esta parte:

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);
Peter
fonte
0

Você pode usar a pseudoclasse "ativa" (ela não funcionará no IE6, no entanto, para elementos que não sejam links)

a:active
{
    ...desired style here...
}
Pilsetnieks
fonte
0

Aqui está um exemplo / variante (mais detalhes descritos) de ToggleButton usando jQuery com <label for="input">implementação.

Primeiro, vamos criar um contêiner para o nosso ToggleButton usando HTML clássico <input>e<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>

Em seguida, definiremos a função para alternar nosso botão. Nosso botão, na verdade, é o usual <label>que iremos estilizar para representar a alternância de valores.

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)
}

A função é implementada de forma reutilizável. Você pode usá-lo para mais de um, dois ou até três ToggleButtons que você criou.

... e finalmente ... para que funcione como esperado, devemos ligar a função de alternância a um evento (evento de "mudança") de nosso <label>botão improvisado (será um clickevento porque não estamos alterando checkboxdiretamente, então nenhum changeevento pode ser disparado para <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
    });

});

Com CSS podemos definir backgorund-imageou alguns borderpara representar a mudança no valor enquanto <label>faremos o trabalho para nós em alterar o valor de uma caixa de seleção;).

Espero que isso ajude alguém.

Paul T. Rawkeen
fonte
+ esta implementação parece estar funcionando corretamente em dispositivos móveis também, bec. A implementação do CCS proposta acima pelo TDeBailleul não estava funcionando corretamente no Android (navegador padrão Android 2.3.5; Opera Mobile no mesmo sistema estava OK).
Paul T. Rawkeen
Além disso, em vez de .addClass()/ .removeClass()você pode usar .toggleClass(), mas o método descrito define explicitamente ações para checked/ uncheckedvalores.
Paul T. Rawkeen
0

Experimentar;

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

E certifique-se no

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

Lembre-se de que quando você está codificando isso, apenas somename e someidpode mudar na tag de entrada, caso contrário, não funciona.

ЯegDwight
fonte
0

Eu também estava procurando uma resposta, e queria consegui-la com CSS. Encontrei solução por CSS NINJA. É uma boa iniciação <input type="checkbox">e alguns css Live demo ! Embora não esteja funcionando no IE 8, você pode implementar o selectivizr ! e correção CSS quando as utilizações opacitypara filterfazê-lo funcionar no IE.

EDITAR 2014:

para os novos botões de alternância, eu uso a solução encontrada no blog do Lea Verou visualmente semelhante à caixa de seleção do iOS

Aivaras
fonte