{"id":178,"date":"2006-06-11T22:37:13","date_gmt":"2006-06-11T20:37:13","guid":{"rendered":"http:\/\/www.maratz.com\/blog\/archives\/2006\/06\/11\/fancy-checkboxes-and-radio-buttons\/"},"modified":"2016-10-01T00:21:11","modified_gmt":"2016-09-30T23:21:11","slug":"fancy-checkboxes-and-radio-buttons","status":"publish","type":"post","link":"http:\/\/www.maratz.com\/blog\/archives\/2006\/06\/11\/fancy-checkboxes-and-radio-buttons\/","title":{"rendered":"Fancy custom checkboxes and radio buttons with CSS and JavaScript"},"content":{"rendered":"<p>After all these years, people still ask how to style custom checkboxes and radio buttons in forms while keeping everything accessible. At my studio <a href=\"https:\/\/www.creativenights.com\/\">Creative Nights<\/a>, we\u2019ve used the following few lines of CSS and JavaScript for more than 10 years now that covers outdated browser versions too (Safari label behaviour fix included)<\/p>\n<p><a href=\"http:\/\/webdesign.maratz.com\/lab\/fancy-checkboxes-and-radio-buttons\/demo.html\"><img loading=\"lazy\" src=\"http:\/\/www.maratz.com\/blog\/wp-content\/uploads\/2006\/06\/fancycheckbox.jpg\" alt=\"\" title=\"See the demo\" width=\"660\" height=\"330\" \/><\/a><\/p>\n<p>For those in a hurry, you can go straight to the vanilla JavaScript <a href=\"http:\/\/webdesign.maratz.com\/lab\/fancy-checkboxes-and-radio-buttons\/demo.html\">Fancy checkboxes demo page<\/a>. A simple <a href=\"http:\/\/webdesign.maratz.com\/lab\/fancy-checkboxes-and-radio-buttons\/jquery.html\">jQuery version<\/a> is also available.<\/p>\n<h2>The structure<\/h2>\n<p>Each radio button and\/or checkbox input element should be surrounded with <code>&#60;label><\/code> tags. Here\u2019s an example: <\/p>\n<pre><code>&#60;label class=\"label_check\" for=\"sample-check\">\r\n    &#60;input name=\"sample-check\" id=\"sample-check\" value=\"1\" type=\"checkbox\" \/>\r\n    Sample Label\r\n&#60;\/label>\r\n\r\n&#60;label class=\"label_radio\" for=\"sample-radio\">\r\n    &#60;input name=\"sample-radio\" id=\"sample-radio\" value=\"1\" type=\"radio\" \/>\r\n    Sample Label\r\n&#60;\/label><\/code><\/pre>\n<h2>The presentation<\/h2>\n<p>We want to remove the original inputs away from view (far away to the left) and place a background image for each label instead. The new graphical radio buttons and checkboxes can still be toggled, while clicking \/ space-pressing the corresponding label will also toggle them to on or off. See the CSS sample:<\/p>\n<pre><code>.has-js .label_check,\r\n.has-js .label_radio { padding-left: 34px; }\r\n.has-js .label_radio { background: url(radio-off.png) no-repeat; }\r\n.has-js .label_check { background: url(check-off.png) no-repeat; }\r\n.has-js label.c_on { background: url(check-on.png) no-repeat; }\r\n.has-js label.r_on { background: url(radio-on.png) no-repeat; }\r\n.has-js .label_check input,\r\n.has-js .label_radio input { position: absolute; left: -9999px; }<\/code><\/pre>\n<h2>The behavior<\/h2>\n<p>Finally, some JavaScript trickery to handle the className switching. As labels in Safari are not clickable, a few extra Safari specific lines are required.<\/p>\n<pre><code>var d = document;\r\nvar safari = (navigator.userAgent.toLowerCase().indexOf('safari') != -1) ? true : false;\r\nvar gebtn = function(parEl,child) { return parEl.getElementsByTagName(child); };\r\nonload = function() {\r\n    \r\n    var body = gebtn(d,'body')[0];\r\n    body.className = body.className && body.className != '' ? body.className + ' has-js' : 'has-js';\r\n    \r\n    if (!d.getElementById || !d.createTextNode) return;\r\n    var ls = gebtn(d,'label');\r\n    for (var i = 0; i &#60; ls.length; i++) {\r\n        var l = ls[i];\r\n        if (l.className.indexOf('label_') == -1) continue;\r\n        var inp = gebtn(l,'input')[0];\r\n        if (l.className == 'label_check') {\r\n            l.className = (safari && inp.checked == true || inp.checked) ? 'label_check c_on' : 'label_check c_off';\r\n            l.onclick = check_it;\r\n        };\r\n        if (l.className == 'label_radio') {\r\n            l.className = (safari && inp.checked == true || inp.checked) ? 'label_radio r_on' : 'label_radio r_off';\r\n            l.onclick = turn_radio;\r\n        };\r\n    };\r\n};\r\nvar check_it = function() {\r\n    var inp = gebtn(this,'input')[0];\r\n    if (this.className == 'label_check c_off' || (!safari && inp.checked)) {\r\n        this.className = 'label_check c_on';\r\n        if (safari) inp.click();\r\n    } else {\r\n        this.className = 'label_check c_off';\r\n        if (safari) inp.click();\r\n    };\r\n};\r\nvar turn_radio = function() {\r\n    var inp = gebtn(this,'input')[0];\r\n    if (this.className == 'label_radio r_off' || inp.checked) {\r\n        var ls = gebtn(this.parentNode,'label');\r\n        for (var i = 0; i &#60; ls.length; i++) {\r\n            var l = ls[i];\r\n            if (l.className.indexOf('label_radio') == -1)  continue;\r\n            l.className = 'label_radio r_off';\r\n        };\r\n        this.className = 'label_radio r_on';\r\n        if (safari) inp.click();\r\n    } else {\r\n        this.className = 'label_radio r_off';\r\n        if (safari) inp.click();\r\n    };\r\n};<\/code><\/pre>\n<p>Also, be sure to check out the previous post about <a href=\"\/blog\/archives\/2006\/06\/07\/preload-images-with-javascript\/\">how to preload images with JavaScript<\/a>.<\/p>\n<h2>Demo<\/h2>\n<p><a href=\"http:\/\/webdesign.maratz.com\/lab\/fancy-checkboxes-and-radio-buttons\/demo.html\">Fancy checkboxes demo page<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Get rid of the standard OS form controls<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[3,18,11,17,8],"tags":[54,55,52,53],"_links":{"self":[{"href":"http:\/\/www.maratz.com\/blog\/wp-json\/wp\/v2\/posts\/178"}],"collection":[{"href":"http:\/\/www.maratz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.maratz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.maratz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.maratz.com\/blog\/wp-json\/wp\/v2\/comments?post=178"}],"version-history":[{"count":15,"href":"http:\/\/www.maratz.com\/blog\/wp-json\/wp\/v2\/posts\/178\/revisions"}],"predecessor-version":[{"id":2802,"href":"http:\/\/www.maratz.com\/blog\/wp-json\/wp\/v2\/posts\/178\/revisions\/2802"}],"wp:attachment":[{"href":"http:\/\/www.maratz.com\/blog\/wp-json\/wp\/v2\/media?parent=178"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.maratz.com\/blog\/wp-json\/wp\/v2\/categories?post=178"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.maratz.com\/blog\/wp-json\/wp\/v2\/tags?post=178"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}