How do you create a toggle button?

Viewed 276754

I want to create a toggle button in html using css. I want it so that when you click on it , it stays pushed in and than when you click it on it again it pops out.

If theres no way of doing it just using css. Is there a way to do it using jQuery?

18 Answers

The good semantic way would be to use a checkbox, and then style it in different ways if it is checked or not. But there are no good ways do to it. You have to add extra span, extra div, and, for a really nice look, add some javascript.

So the best solution is to use a small jQuery function and two background images for styling the two different statuses of the button. Example with an up/down effect given by borders:

$(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>

Obviously, you can add background images that represent button up and button down, and make the background color transparent.

If you want a proper button then you'll need some javascript. Something like this (needs some work on the styling but you get the gist). Wouldn't bother using jquery for something so trivial to be honest.

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

You could use an anchor element (<a></a>), and use a:active and a:link to change the background image to toggle on or off. Just a thought.

Edit: The above method doesn't work too well for toggle. But you don't need to use jquery. Write a simple onClick javascript function for the element, which changes the background image appropriately to make it look like the button is pressed, and set some flag. Then on next click, image and flag is is reverted. Like so

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

And the html like so <div id="toggleDiv" onclick="toggle()">Some thing</div>

Pure CSS with a minimalist approach

All you need is a checkbox with a background as the slider. The result is keyboard and screen reader accessible.

input {
  -webkit-appearance: none;
  appearance: none;
  padding: 16px 30px;
  border-radius: 16px;
  background: radial-gradient(circle 12px, white 100%, transparent calc(100% + 1px)) #ccc -14px;
  transition: 0.3s ease-in-out;
}

:checked {
  background-color: dodgerBlue;
  background-position: 14px;
}
<input type="checkbox">

See also

How to add the text "ON" and "OFF" to toggle button

I would be inclined to use a class in your css that alters the border style or border width when the button is depressed, so it gives the appearance of a toggle button.

The following approach relies on html-css only, no js of any kind is needed.

The css and the HTML snippet is as simple as this:

#mycbid
{
  display:none;
}

#mycbid:checked + #mylabelid
{
  background: grey;
  border: inset;
}

#mylabelid
{
  background: lightgray;
  border: outset;
}
<input type="checkbox" id="mycbid">
  <label for="mycbid" id="mylabelid">Text of the label</label>

Explication:

Under the hood the checkbox will not be displayed but still it can be set as checked or unchecked so it will be possible to use it more or less as usual.

When the checkbox is checked its status "triggers" the css rules under #mycbid:checked + #mylabelid and the label will be styled accordingly with it. This css selector is in fact the key of everything: in fact it selects the sibling of the checkbox (that is the label it self). The label redirects the click to the checkbox thanks to the for attribute, even if the checkbox is not shown.

When the checkbox is not checked its status "triggers" the css rules under #mylabelid and the label will be styled accordingly with it.

Of course it is possible to style the label in may different ways.

You can use the "active" pseudoclass (it won't work on IE6, though, for elements other than links)

a:active
{
    ...desired style here...
}

Here is a "square corners" version of @Mori's excellent minimalist CSS-only answer:

enter image description here

.switch {
  appearance: none;
  height: 30px;
  width: 52px;
  background-image: linear-gradient(to bottom, transparent 0 22px, dodgerBlue 22px), 
                    linear-gradient(to right, white 0 22px, dodgerBlue 22px 60px);
  transition: 0.2s ease-in-out;
  background-position: 4px 4px;
}
.switch:checked {
  background-position: 26px 4px;
}
<input type="checkbox" class="switch">

and a round one with two blue sides (no disabled gray side):

.switch {
  appearance: none;
  padding: 16px 30px;
  border-radius: 16px;
  background: radial-gradient(circle 12px, white 100%, transparent calc(100% + 1px)) dodgerBlue -14px;
  transition: 0.3s ease-in-out;
}

.switch:checked {
  background-position: 14px;
}
<input type="checkbox" class="switch">

Related