6

I need to represent a toggle button in HTML. My intention is to do it with a normal input submit button and styling. Any recommendations on how to style a toggle button that is understandable and works more or less in all browsers?

Pablo Fernandez
  • 279,434
  • 135
  • 377
  • 622

3 Answers3

9

Since you're representing a single control with a true/false state, you really want to use a checkbox as the underlying form element to maintain compatibility with downlevel browsers, screen readers and so on. One approach here is to associate a label control with the checkbox, and then using a combination of CSS and jQuery to make the actual checkbox itself 'invisible', render the label as a button, and modify the label's border property as the checkbox is checked or unchecked.

This code works in Chrome, Safari, Opera, Firefox and IE (thanks to a conditional-comment hack since IE treats hidden form elements differently to other browsers). If you submit the enclosing form you get ordinary HTML checkbox behaviour in the resulting form submission.

   <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
      <title>jQuery Toggle Button </title>

     <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>

      <style type="text/css">
           /* Style the label so it looks like a button */
           label {
                border: 2px outset #cccccc;
                background-color: #cccccc;
                position: relative;
                z-index: 3;
                padding: 4px;
           }
           /* CSS to make the checkbox disappear (but remain functional) */
           label input {
                position: absolute;
                visibility: hidden;
           }
      </style>
      <!--[if IE]>
      /* Conditional styles applied in IE only to work around cross-browser bugs */
       <style>
            label input#myCheckbox {
                visibility: visible;
                z-index: 2;
           }
       </style>
      <![endif]-->

      <script type="text/javascript">
           $(function() {
                $("#toggleCheckbox").click(function() {
                     $(this).closest("label").css({ borderStyle: this.checked ? 'inset' : 'outset' });
                });
           });
      </script>

 </head>
 <body>
      <form action="http://www.w3schools.com/html/html_form_action.asp" method="get">
           <label for="toggleCheckbox">
                <input type="checkbox" name="toggled" id="toggleCheckbox" value="1" />
                Toggled?</label>
           <input type="submit" name="verb" value="Submit Form" />
      </form>
 </body>
 </html>
Dylan Beattie
  • 53,688
  • 35
  • 128
  • 197
  • 2
    This approach is not keyboard-friendly, the labels can not have focus themselves and can not be tabbed through and toggled with the keyboard when their respective checkbox is hidden. – grr Jul 25 '12 at 11:28
  • @grr: this is commonly called "tab stop". you can prevent it: http://stackoverflow.com/a/1561097/1160540 – vahanpwns Feb 11 '14 at 21:21
2

Well i was trying to implement a slider in html using css and javascript. Found few references but they were not completely helpful. So find below my implementation. Part of it is taken from somewhere else in the web tho i dont remember from where. Anyway here it goes: 1>This slider is based on a button that you click.

1>HTML code

<div class="SwitchBtn" >                    
    <input type="checkbox" class = "SwitchBtn_Check" id = "checkboxForSwitch" style = "display:none;"/>
    <div class = "transitionSwitch">
        <input type = "button" class = "SwitchBtn_Btn off" id="buttonForSwitch" name = "TurnOn" onclick = "toggleStandBy()" />              
        <div class = "slider_label off" id = "labelForSwitch" >
            <div class = "SwitchBtn_active" id= "btnAct" ><span class = "switchOn">On</span></div>
            <div class = "SwitchBtn_inactive" id= "btnInact" ><span class = "switchOff">Off</span></div>
        </div>
    </div>              
</div>

2>CSS code

/* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Related to switch button start@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */

.SwitchBtn{
position: relative;         /*this is very important or else precentage used in its child nodes will take effect of the next parent which has anything other than static*/      
overflow: hidden;
height:44.56px;
width:148.10px;


-webkit-box-shadow: 0 0 0 2px rgb(145, 149, 155);       
-moz-box-shadow: 0 0 0 2px rgb(145, 149, 155);
box-shadow: 0 0 0 2px rgb(145, 149, 155);
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
-webkit-user-select:none; 
-moz-user-select:none;  
}

.transitionSwitch{          

overflow: hidden;   
margin-left: 0;
width:100%;
height: 100%;


-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
-moz-transition: margin 0.3s ease-in 0s; 
-webkit-transition: margin 0.3s ease-in 0s;
transition: margin 0.3s ease-in 0s;
}

.SwitchBtn_Check:checked+ .transitionSwitch{            
margin-left:50%;
}

.slider_label{
position:absolute;
width:150%;
height:100%;        

overflow: hidden;
margin-left:-50%;

-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;

-webkit-box-shadow: 0 0 0 2px rgb(145, 149, 155);           
-moz-box-shadow: 0 0 0 2px rgb(145, 149, 155);
box-shadow: 0 0 0 2px rgb(145, 149, 155);

}

.switchOn
{
position:relative;
top:5.57px;             /*vvvsma half of vvsma i.e. 11.14px*/
left:11.14px;           /*vvsma half of vsma i.e. 22.28px*/

}

.switchOff
{
    position:relative;
    top:5.57px;
    left:11.14px;


}

.SwitchBtn_active{  
position:absolute;
width:50%;
height:100%;    
vertical-align:center;
left:0;
font-weight: normal;
font-family: Avenir, Tahoma, Arial, Verdana;
color: #FCF9F9;
font-size: 26.21px;
text-indent:10px;       

background-image: -moz-linear-gradient(top, #7EA3D5 0%, #5C89C7 50%, #3966B0 51%, #3764AF 100%);
background-image: -webkit-linear-gradient(top, #7EA3D5 0%, #5C89C7 50%, #3966B0 51%, #3764AF 100%);
background-image: -o-linear-gradient(top, #7EA3D5 0%, #5C89C7 50%, #3966B0 51%, #3764AF 100%);
background-image: linear-gradient(top, #7EA3D5 0%, #5C89C7 50%, #3966B0 51%, #3764AF 100%);

-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;     
}

.SwitchBtn_inactive
{   
width:50%;
height:100%;
vertical-align:center;
position:absolute;
right:0;        
font-weight: normal;
font-family: Avenir, Tahoma, Arial, Verdana;
color: #291818;
font-size: 26.21px;
text-indent:45px;


-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;

background-image: -moz-linear-gradient(top, rgb(236,236,237) 0%, rgb(208,209,211) 50%, rgb(185,187,189) 51%, rgb(190,191,194) 100%);
background-image: -webkit-linear-gradient(top, rgb(236,236,237) 0%, rgb(208,209,211) 50%, rgb(185,187,189) 51%, rgb(190,191,194) 100%);
background-image: -o-linear-gradient(top, rgb(236,236,237) 0%, rgb(208,209,211) 50%, rgb(185,187,189) 51%, rgb(190,191,194) 100%);
background-image: linear-gradient(top, rgb(236,236,237) 0%, rgb(208,209,211) 50%, rgb(185,187,189) 51%, rgb(190,191,194) 100%);

}

.SwitchBtn_Btn{

width:50%;
height:100%;
position:absolute;
z-index:1;  
margin-left:0;  

-webkit-box-shadow: 0 0 0 0.5px rgb(145, 149, 155);         
-moz-box-shadow: 0 0 0 0.5px rgb(145, 149, 155);
box-shadow: 0 0 0 0.5px rgb(145, 149, 155);

background-image: -moz-linear-gradient(top, rgb(236,236,237) 0%, rgb(208,209,211) 50%, rgb(185,187,189) 51%, rgb(190,191,194) 100%);
background-image: -webkit-linear-gradient(top, rgb(236,236,237) 0%, rgb(208,209,211) 50%, rgb(185,187,189) 51%, rgb(190,191,194) 100%);
background-image: -o-linear-gradient(top, rgb(236,236,237) 0%, rgb(208,209,211) 50%, rgb(185,187,189) 51%, rgb(190,191,194) 100%);
background-image: linear-gradient(top, rgb(236,236,237) 0%, rgb(208,209,211) 50%, rgb(185,187,189) 51%, rgb(190,191,194) 100%);

-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px; 

}

/* @@@@@@@@@@@@@@@@@@@@@@@Related to switch button End@@@@@@@@@@@@@@@@ */

3>Javascript Code a>The below example is with respect to Ajax

function toggleStandBy()
{       


        var xmlhttp;
        if(window.XMLHttpRequest)
            xmlhttp = new XMLHttpRequest();
        else
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");

        xmlhttp.onreadystatechange = function()
        {

            if (xmlhttp.readyState==4 && xmlhttp.status==200)
            {       

                if(xmlhttp.responseText == "1")             
                {
                        document.getElementById('checkboxForSwitch').checked = !document.getElementById('checkboxForSwitch').checked;
                }

            }

        }   
        xmlhttp.open("POST","http://192.168.1.x/sample.php",true);
        xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
        if(document.getElementById('buttonForSwitch').name == "TurnOn")
        {   
            document.getElementById('buttonForSwitch').name = "TurnOff";
            xmlhttp.send("state=1");
        }
        else if(document.getElementById('buttonForSwitch').name == "TurnOff")
        {           
            document.getElementById('buttonForSwitch').name = "TurnOn";
            xmlhttp.send("state=0");
        }
}

a>The below is a simple example

function toggleStandBy()
{    
     if(document.getElementById('buttonForSwitch').name == "TurnOn")
     {  
          document.getElementById('buttonForSwitch').name = "TurnOff";
            }
      else if(document.getElementById('buttonForSwitch').name == "TurnOff")
      {         
                document.getElementById('buttonForSwitch').name = "TurnOn";
       }
    document.getElementById('checkboxForSwitch').checked = !document.getElementById('checkboxForSwitch').checked;

   } 

The images of how the button appears is as below

Off button On button Toggle slide

The appearance changes a tiny winy bit based on the browser.(Obviously dont get expect it to look completely proper on IE. If you remove gradient and put normal colors it will work in IE as well OR "just add background-color: property along with background-image: in CSS and since IE takes background-color: and does not support background-image: your reqd background color will be shown without the need for any particular browser sepcification implementations")

Kasper van den Berg
  • 8,951
  • 4
  • 48
  • 70
ebdo
  • 157
  • 3
  • 14
0

All browsers you say? In that case, however you choose to represent it visually, be sure to use aria-pressed so the toggle state is exposed to the accessibility API (and thus assistive technology). One nice thing about this is that you can then use this attribute in a CSS selector such as

button[aria-pressed="true"] {
    border: 2px solid #000;
}

That will save you having to come up with a class name - there's a standard one!

n.b. strictly speaking, the aria-pressed attribute should only be used with <button> elements, or elements with role=button

brennanyoung
  • 6,243
  • 3
  • 26
  • 44