How to create an on/off switch with Javascript/CSS?

I want to have a sliding switch. On the left would be Off and on the right would be On. When the user toggles the switch, I want the 'slider' portion to slide to the other side and indicate it is off. I could then have a callback that takes as input the state of the toggle switch so I can act accordingly.

Any idea how to do this?


Solution 1:

check out this generator: On/Off FlipSwitch

you can get various different style outcomes and its css only - no javascript!

Solution 2:

You mean something like IPhone checkboxes? Try Thomas Reynolds' iOS Checkboxes script:

Once the files are available to your site, activating the script is very easy:

...

$(document).ready(function() {
  $(':checkbox').iphoneStyle();
});

Results:

Solution 3:

Using plain javascript

<html>

  <head>

     <!-- define on/off styles -->
     <style type="text/css">
      .on  { background:blue; }
      .off { background:red; }
     </style>

     <!-- define the toggle function -->
     <script language="javascript">
        function toggleState(item){
           if(item.className == "on") {
              item.className="off";
           } else {
              item.className="on";
           }
        }
     </script>
  </head>

  <body>
     <!-- call 'toggleState' whenever clicked -->
     <input type="button" id="btn" value="button" 
        class="off" onclick="toggleState(this)" />
  </body>

</html>

Using jQuery

If you use jQuery, you can do it using the toggle function, or using the toggleClass function inside click event handler, like this:

$(document).ready(function(){
    $('a#myButton').click(function(){
        $(this).toggleClass("btnClicked");
    });
});

Using jQuery UI effects, you can animate transitions: http://jqueryui.com/demos/toggleClass/

Solution 4:

Initial answer from 2013

If you don't mind something related to Bootstrap, an excellent (unofficial) Bootstrap Switch is available.

Classic 2013 Switch

It uses radio types or checkboxes as switches. A type attribute has been added since V.1.8.

Source code is available on Github.

Note from 2018

I would not recommend to use those kind of old Switch buttons now, as they always seemed to suffer of usability issues as pointed by many people.

Please consider having a look at modern Switches like those.

Modern 2018 Switch

Solution 5:

You can achieve this using HTML and CSS and convert a checkbox into a HTML Switch.

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