I have a button that when clicked, displays a message 'Copied!'. I've created a .hidden class and I'm using the classList property and add() method to apply it to the message. The hidden class contains a transition that fades the element out.
Currently, once the event runs, I can't get it to run again. The 'Copied!' message doesn't come up on a second click.
copied.addEventListener("click", function () {
copiedMsg.textContent = "Copied!";
copiedMsg.classList.add("hidden");
});
.hidden {
visibility: hidden;
opacity: 0;
transition: visibility 0s 2s, opacity 2s linear;
}
button.btn {
width: fit-content;
padding: 0.5em 1em;
}
.primary {
background: transparent;
border: 1px solid black;
box-shadow: 2px 2px 2px -2px black;
}
<button class="btn primary" id="copied"><i class="fas fa-copy"></i> Copy Snippet!</button> <span id="copiedMsg"></span>
copied.addEventListener("click", function () {
copiedMsg.textContent = "Copied!";
copiedMsg.classList.add("hidden");
setTimeout(function() {
copiedMsg.textContent = "";
copiedMsg.classList.remove("hidden");
}, 2000);// equal to 2s in your animation
});
I just added in the line:
copiedMsg.classList.remove("hidden");
and added a timeout to run the code.
copied.addEventListener("click", function() {
copiedMsg.classList.remove("hidden");
setTimeout(function() {
copiedMsg.textContent = "Copied!";
copiedMsg.classList.add("hidden");
}, 10)
});
.hidden {
visibility: hidden;
opacity: 0;
transition: visibility 0s 2s, opacity 2s linear;
}
button.btn {
width: fit-content;
padding: 0.5em 1em;
}
.primary {
background: transparent;
border: 1px solid black;
box-shadow: 2px 2px 2px -2px black;
}
<button class="btn primary" id="copied"><i class="fas fa-copy"></i> Copy Snippet!</button> <span id="copiedMsg"></span>
Explanation:
copiedMsg.classList.remove("hidden");
This removes the class hidden if it contains it.
setTimeout(function() {
copiedMsg.textContent = "Copied!";
copiedMsg.classList.add("hidden");
}, 10)
I wait one millisecond before I run the code, using the above line of code. I found that it didn't work otherwise.
You hide the span and then you never make it visible again. Try to remove hidden class first and fire the rest of the function.
Here's another take using the Animation web api. Despite what it says in MDN, it seems to run on chrome. That being said, likely not the best depending on the browsers you want to support.
This just loops over all the animations the element may have, and then removes the class after they all end.
copied.addEventListener("click", function() {
copiedMsg.textContent = "Copied!";
copiedMsg.classList.add("hidden");
Promise.all(copiedMsg.getAnimations().map(animation => animation.finished)).then(() => {
copiedMsg.textContent = '';
copiedMsg.classList.remove('hidden');
})
});
.hidden {
visibility: hidden;
opacity: 0;
transition: visibility 0s 2s, opacity 2s linear;
}
button.btn {
width: fit-content;
padding: 0.5em 1em;
}
.primary {
background: transparent;
border: 1px solid black;
box-shadow: 2px 2px 2px -2px black;
}
<button class="btn primary" id="copied"><i class="fas fa-copy"></i> Copy Snippet!</button> <span id="copiedMsg"></span>
I think there is something wrong with classList.add since in every event same class is added try toggle or something.
Related
I have a small carousel that plays automatically on page load, using HTML, CSS and JavaScript and definitely no jQuery.
To add a pause/play option there is a span with role="checkbox" followed by a label.
The label itself is hidden and has no content. The span has two pseudo elements. On first showing, the pseudo element shows the ⏸ character, controlled by a CSS ::after class. When clicked, the span has the class "is-clicked" added, at which point the ▶ character is displayed, controlled by another ::after class
It is focusable and can be activated with the keyboard by hitting the Enter key, but when I check with Lighthouse, I keep getting the "Focusable elements should have interactive semantics".
Why is this?
Here is the code:
/* detect keyboard users */
function handleFirstTab(e) {
if (e.key === 'Tab') { // the 'I am a keyboard user' key
document.body.classList.add('user-is-tabbing');
window.removeEventListener('keydown', handleFirstTab);
}
}
let checkboxEl = document.getElementById('checkbox');
let labelEl = document.getElementById('checkboxLabel');
labelEl.onclick = function handleLabelClick() {
checkboxEl.focus();
toggleCheckbox();
}
function toggleCheckbox() {
let isChecked = checkboxEl.classList.contains('is-checked');
checkboxEl.classList.toggle('is-checked', !isChecked);
checkboxEl.setAttribute('aria-checked', !isChecked);
}
checkboxEl.onclick = function handleClick() {
toggleCheckbox();
}
checkboxEl.onkeypress = function handleKeyPress(event) {
let isEnterOrSpace = event.keyCode === 32 || event.keyCode === 13;
if(isEnterOrSpace) {
toggleCheckbox();
}
}
.link {
height: auto;
border: 1px solid #000;
margin-bottom: 1rem;
width: 80%;
display: block;
}
#carousel-checkbox {
margin-bottom: 1rem;
height: 50px;
width: 100px;
display: inline-block;
}
#carousel-checkbox input {
display: none;
}
#carousel-checkbox label {
display: inline-block;
vertical-align: middle;
}
#carousel-checkbox #checkbox {
position: relative;
top: 0;
left: 30px;
padding: 0.5rem 1rem;
background: rgba(255,255,255, 0.5);
}
#carousel-checkbox #checkbox:hover {
cursor: pointer;
}
#carousel-checkbox #checkbox:focus {
border: 1px dotted var(--medium-grey);
}
#carousel-checkbox #checkbox::after {
content: "⏸";
font-size: 1.5rem;
color: var(--theme-dark);
}
#carousel-checkbox #checkbox.is-checked::after {
content: "▶";
}
<div class="link">A bit of text with a dummy link to demonstrate the keyboard tabbing navigation. </div>
<div id="carousel-checkbox"><span id="checkbox" tabindex="0" role="checkbox" aria-checked="false" aria-labelledby="checkboxLabel"></span><label id="checkboxLabel"></label></div>
<div class="link">Another link to another dummy link</div>
Why is this? Is it because the pseudo elements don't have a name attribute or something like that?
I have tried a different way, by dropping the pseudo elements and trying to change the span innerHTML depending on whether the class 'is-clicked' exists or not, but although I can get the pause character to display initially, it won't change the innerHTML to the play character when the span is clicked again.
Short Answer
This is a warning rather than an error, it is telling you to check that the item actually is interactive.
Now you have got the interactivity on the element so you can ignore that issue.
Long answer
Why not just use a <input type="checkbox"> and save yourself an awful lot of extra work?
You can hide a checkbox with a visually hidden class.
This then allows you to do the same trick with a pseudo element as the visual representation of the state.
I have made several changes to your example that mean you don't have to worry about capturing keypresses etc. and can just use a click handler so your JS is far simpler.
Notice the trick with the label where I add some visually hidden text within it so the label is still visible (so we can still use psuedo elements!).
I then use #checkbox1 ~ label to access the label with CSS so we can change the state.
The final thing to notice is how I changed the content property slightly. This is because some screen readers will try and read out pseudo elements so I added alt text that was blank. Support isn't great at just over 70%, but it is worth adding for browsers that do support it.
Example
The below hopefully illustrates a way of achieving what you want with a checkbox.
There may be a few errors as I just adapted your code so please do not just copy and paste!
note: a checkbox should not work with Enter, only with Space. If you want it to work with both it should instead be a toggle switch etc. so that would be a completely different pattern.
let checkboxEl = document.getElementById('checkbox1');
let labelEl = document.querySelector('#checkboxLabel');
function toggleCheckbox() {
let isChecked = checkboxEl.classList.contains('is-checked');
checkboxEl.classList.toggle('is-checked', !isChecked);
checkboxEl.setAttribute('aria-checked', !isChecked);
}
checkboxEl.onclick = function handleClick() {
toggleCheckbox();
}
.link {
height: auto;
border: 1px solid #000;
margin-bottom: 1rem;
width: 80%;
display: block;
}
#carousel-checkbox {
margin-bottom: 1rem;
height: 50px;
width: 100px;
display: inline-block;
}
.visually-hidden {
border: 0;
padding: 0;
margin: 0;
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 - a 0 height clip, off to the bottom right of the visible 1px box */
clip: rect(1px, 1px, 1px, 1px); /*maybe deprecated but we need to support legacy browsers */
clip-path: inset(50%); /*modern browsers, clip-path works inwards from each corner*/
white-space: nowrap; /* added line to stop words getting smushed together (as they go onto seperate lines and some screen readers do not understand line feeds as a space */
}
#carousel-checkbox label {
display: inline-block;
vertical-align: middle;
}
#carousel-checkbox #checkbox1 {
position: relative;
top: 0;
left: 30px;
padding: 0.5rem 1rem;
background: rgba(255,255,255, 0.5);
}
#carousel-checkbox #checkbox1 ~label:hover {
cursor: pointer;
}
#carousel-checkbox #checkbox1:focus ~ label {
border: 1px dotted #333;
}
#carousel-checkbox #checkbox1 ~label::after {
content: "⏸" / "";
font-size: 1.5rem;
color: #000;
}
#carousel-checkbox #checkbox1.is-checked ~label::after {
content: "▶" / "";
}
<div class="link">A bit of text with a dummy link to demonstrate the keyboard tabbing navigation. </div>
<div id="carousel-checkbox">
<input type="checkbox" id="checkbox1" class="visually-hidden">
<label for="checkbox1" id="checkboxLabel">
<span class="visually-hidden">Pause animations</span>
</label>
</div>
<div class="link">Another link to another dummy link</div>
In the end, I gave up on using a checkbox, due to the difficulties with iPad/iOS not responding to checkbox events. Whilst it worked in codepen on iOS it wouldn't work on the actual site. So I switched to a button.
Here is the code, which is fully accessible with no 'interactive semantics' warnings, shown with some dummy slides. The animation is based on having only three slides. If you wanted more or less, then the timings would have to be adjusted accordingly. All I need now is to style the pause button.
let element = document.getElementById("pause");
function toggleButton() {
element.classList.toggle("paused");
if (element.innerHTML === "⏸") {
element.innerHTML = "▶";
}
else {
element.innerHTML = "⏸";
}
}
element.onclick = function handleClick() {
toggleButton();
}
#carousel {
height: auto;
max-width: 1040px;
position: relative;
margin: 4rem auto 0;
}
#carousel > * {
animation: 12s autoplay6 infinite linear;
position: absolute;
top: 0;
left: 0;
opacity: 0.0;
}
#carousel .one {
position: relative;
}
.homeSlides {
height: 150px;
width: 400px;
background-color: #ff0000;
}
.homeSlides.two {
background-color: #0fff00;
}
.homeSlides.three {
background-color: #e7e7e7;
}
#keyframes autoplay6 {
0% {opacity: 0.0}
4% {opacity: 1.0}
33.33% {opacity: 1.0}
37.33% {opacity: 0.0}
100% {opacity: 0.0}
}
#carousel > *:nth-child(1) {
animation-delay: 0s;
}
#carousel > *:nth-child(2) {
animation-delay: 4s;
}
#carousel > *:nth-child(3) {
animation-delay: 8s;
}
#carousel-button {
position: relative;
height: 100%;
width: auto;
}
#carousel-button button {
position: absolute;
top: -3.5rem;
right: 5rem;
padding: 0 0.5rem 0.25rem;;
background: #fff;
z-index: 98;
font-size: 2rem;
cursor: pointer;
}
body.user-is-tabbing #carousel-button button:focus {
outline: 1px dotted #333;
}
body:not(.user-is-tabbing) #carousel-button button:focus {
outline: none;
}
#carousel-button button:hover {
cursor: pointer;
}
#carousel-button ~ #carousel * {
animation-play-state: running;
}
#carousel-button button.paused ~ #carousel * {
animation-play-state: paused;
}
<div id="carousel-button"><button id="pause" class="">⏸</button>
<div id="carousel">
<div class="homeSlides one">This is div one</div>
<div class="homeSlides two">This is div two</div>
<div class="homeSlides three">This is div three</div>
</div>
</div>
I've been trying to create the following animation:
(1) I have a button consisting of a white 100x100 box on top of a black 100x100 box.
(2) Clicking on the button makes the white box disappear into the black box.
(see the result here)
// html
<div class="button">
<div class="white u-on-top"></div>
<div class="black"></div>
</div>
// css
.button {
width: 100px;
height: 100px;
margin: 10px;
position: relative;
display: inline-block;
.white {
width: 100%;
height: 100%;
background: #fff;
border: 1px solid #000;
position: absolute;
transition: .5s;
}
.black {
width: 100%;
height: 100%;
background: #000;
border: 1px solid #000;
}
}
.u-on-top {
z-index: 1;
}
.u-at-bottom {
z-index: -1;
}
// javascript
var btn = document.querySelector(".button");
var btnState = false;
btn.addEventListener("click", () => {
var btnw = btn.querySelector(".white");
if (!btnState) {
btnw.style.transform = "scale(0)";
btnState = true;
} else {
btnw.style.transform = "scale(1)";
btnState = false;
}
})
(3) What I've unsuccessfully been trying to do is to also make the black box disappear into the white box when clicked on.
So:
clicking on the white box makes it disappear into the black box
clicking on the black box makes it disappear into the white box
clicking on the white box makes it disappear into the black box
And so on...
My idea was to obtain the effect by modifying the z-index of the boxes when clicked on, using the utility classes u-on-top and u-at-bottom (eg the black box is brought to the top after the white box disappears), but I got some weird results.
You can try to adjust some transition, the trick is to add a delay to z-index so it changes after the scale effect. I have also change the JS code and reduced the CSS:
var btnW = document.querySelector(".white");
var btnB = document.querySelector(".black");
var btnState = false;
btnW.addEventListener("click", () => {
btnB.classList.remove('hide');
btnW.classList.add('hide');
btnW.classList.remove('u-on-top');
btnB.classList.add('u-on-top');
})
btnB.addEventListener("click", () => {
btnW.classList.remove('hide');
btnB.classList.add('hide');
btnB.classList.remove('u-on-top');
btnW.classList.add('u-on-top');
})
.button {
width: 100px;
height: 100px;
margin: 10px;
position: relative;
display: inline-block;
cursor: pointer;
}
.button>div {
width: 100%;
height: 100%;
border: 1px solid #000;
position: absolute;
transition: transform 0s, z-index 0s 0.5s;
z-index:0;
}
.button .white {
background: #fff;
}
.button .black {
background: #000;
}
.button>div.hide {
transform:scale(0);
transition: transform .5s, z-index 0s 0.5s;
}
.button>div.u-on-top {
z-index:1;
}
<div class="button">
<div class="white u-on-top"></div>
<div class="black"></div>
</div>
When hover over a div (Selector), a dropdown is displayed. When clicking in an element, a JS function is called and several tasks are performed. That's OK. My problem is that I want the dropdown to disappear after the click, but cannot use .style.display= "none" for example, since I want it to apperar when hovering again over Selector.
I'm not familiar with JQuery, so feel more comfortable with plain JS.
function TheJSFunction(What) {
//alert (What);
// First try: remove classes to dropdown, and then add class 'dropdown-content' (vis: hidden and opacity 0):
// document.getElementById("dc").className = '';
// document.getElementById("dc").classList.add('dropdown-content');
// Second try: set opacity to 0 (or visibility to hidden)
// But then dropdown is not displayed again when hovering over Selector:
//document.getElementById("dc").style.opacity = 0;
}
.Selector {
display: inline;
float: left;
padding: 8px;
background: #282828;
color: #ffffff;
width: 300px;
text-align: center;
}
.Selector:hover {
background-color: #800000;
transition: all 0.5s ease;
}
.dropdown-content {
visibility: hidden;
opacity: 0;
position: absolute;
background-color: #ff8080;
margin-top: 8px;
margin-left: -8px;
width: 316px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.4);
z-index: 1;
}
.Selector:hover .dropdown-content {
visibility: visible;
opacity: 1;
transition: all 0.5s ease;
}
.dropdown-content .DD_content {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
cursor: pointer;
}
.dropdown-content .DD_content:hover {
background-color: #ffb3b3;
transition: all 1s ease;
}
<div class="Selector">Lizards
<div class="dropdown-content" id="dc">
<div class="DD_content" onclick="TheJSFunction('New');">New Specie</div>
<div class="DD_content" onclick="TheJSFunction('Edit');">Edit record</div>
</div>
</div>
you can add onmouseover to div
<div class="Selector" onmouseover="reset()">Lizards
<div class="dropdown-content" id="dc">
<div class="DD_content" onclick="TheJSFunction('New');">New Specie</div>
<div class="DD_content" onclick="TheJSFunction('Edit');">Edit record</div>
</div>
</div>
then add a function to reset opacity to 100
function reset() {
document.getElementById("dc").style.opacity = 100;
}
To do this effectively, you will need to do a bit of JS to do that. You could either add a class or set the visibility property on click, wait for onmouseout event and then remove the class/property to reset it. This should work even for touch devices.
Example code:
var dropdown = document.querySelector(".dropdown-content");
dropdown.addEventListener("click", function() {
dropdown.style.visibility = "hidden";
});
dropdown.addEventListener("mouseout", function() {
dropdown.style.visibility = "";
});
EDIT:
As a bonus, you could easily just toggle the property in the same line. As these things cause a DOM reflow, it should mean that if it is controlled via CSS selectors it should not show back up. So simply just...
function ClickHandler(element) {
element.style.visibility = "none";
element.style.visibility = "";
}
You need to add an event listener to override the opacity specified in the 'TheJSFunction' function
document.getElementsByClassName('Selector')[0].addEventListener("mouseover", function(){
document.getElementById("dc").style.opacity=1;
});
I'm trying to make a box shadow property only visible during scrolling. I'm using HTML, CSS and JS.
I want the shadow to appear with a small transition when scrolling then disappear when stopped.
So far I have been using this code:
<head>
<title>website</title>
<link href="style.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="script.js"></script>
</head>
<body>
<div id="mySidenav" class="sidenav" onscroll="scrollShadow()"></div>
css
.sidenav {
height: 100%;
width: 280px;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: skyblue;
overflow-x: hidden;
transition: 0.5s;
padding-top: 10px;
}
js
function scrollShadow() {
document.getElementsByClassName("sidenav").style.boxShadow = "3px 0px 10px black";
}
Would love any help!
Instead of setting the style attribute, which is harder to manage (especially if you have more than one element you want to affect), you could set a class on body and style the elements with CSS.
(function iife() {
var body = document.body;
var timer;
window.addEventListener('scroll', function onScroll() {
clearTimeout(timer);
body.classList.add('scrolling');
timer = setTimeout(function removeClass() {
body.classList.remove('scrolling');
}, 150);
}, false);
})();
*, *:before, *:after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
#container {
width: 100vw;
height: 5000px;
background: lightgrey;
transition: background 5s;
}
.scrolling #container {
background: red;
}
#fix {
position: fixed;
top: 50px;
left: 50px;
height: 120px;
width: 20px;
background: white;
transition: all 300ms ease 0s;
}
.scrolling #fix {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.35);
transform: translateY(-3px);
}
<div id="container">
<div id="fix"></div>
</div>
u can use jquery scroll method as
<script>
$(function(){
$(window).scroll(function(){
if($(window).scrollTop()>=40){
/*do something */
scrollShadow();
}
});
});
function scrollShadow() {
document.getElementsByClassName("sidenav").style.boxShadow = "3px 0px 10px black";
}
</script>
I would first ensure that you refrain from adding CSS inside JS, it just shouldn't live there. You can achieve what you want by adding a class to the body which is then targeted inside your CSS. Finally, there's no native way of knowing if the user has stopped scrolling. The only way is to define a timeout which will remove the class unless the user scrolls, whereby the original timeout is cancelled and a new timeout is defined. It's also best to make sure that the window is completely loaded else you'll be targeting elements that aren't there yet. This example below should be what you need:
window.addEventListener('load', function(){
var timeout = null;
var body = document.querySelector('body');
var scrollClass = 'scrolled';
window.addEventListener('scroll', function(){
clearTimeout(timeout);
body.classList.add(scrollClass);
timeout = setTimeout(function(){
body.classList.remove(scrollClass);
}, 250);
});
});
body {
height: 2000px;
}
.sidenav {
height: 100%;
width: 280px;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: skyblue;
overflow-x: hidden;
padding-top: 10px;
transition: box-shadow 500ms ease-in-out;
}
.scrolled .sidenav{
box-shadow: 3px 0px 10px #000;
}
<div class="sidenav"></div>
This should achieve what you want.
Tom
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?
check out this generator: On/Off FlipSwitch
you can get various different style outcomes and its css only - no javascript!
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:
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/
Initial answer from 2013
If you don't mind something related to Bootstrap, an excellent (unofficial) Bootstrap Switch is available.
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.
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>
Outline: Create two elements: a slider/switch and a trough as a parent of the slider. To toggle the state, switch the slider element between an "on" and an "off" class. In the style for one class, set "left" to 0 and leave "right" the default; for the other class, do the opposite:
<style type="text/css">
.toggleSwitch {
width: ...;
height: ...;
/* add other styling as appropriate to position element */
position: relative;
}
.slider {
background-image: url(...);
position: absolute;
width: ...;
height: ...;
}
.slider.on {
right: 0;
}
.slider.off {
left: 0;
}
</style>
<script type="text/javascript">
function replaceClass(elt, oldClass, newClass) {
var oldRE = RegExp('\\b'+oldClass+'\\b');
elt.className = elt.className.replace(oldRE, newClass);
}
function toggle(elt, on, off) {
var onRE = RegExp('\\b'+on+'\\b');
if (onRE.test(elt.className)) {
elt.className = elt.className.replace(onRE, off);
} else {
replaceClass(elt, off, on);
}
}
</script>
...
<div class="toggleSwitch" onclick="toggle(this.firstChild, 'on', 'off');"><div class="slider off" /></div>
Alternatively, just set the background image for the "on" and "off" states, which is a much easier approach than mucking about with positioning.
You can take a look at Shield UI's Switch widget. It is as easy to use as this:
<input id="switch3" type="checkbox" value="" />
<script>
jQuery(function ($) {
$("#switch3").shieldSwitch({
onText: "Yes, save it",
ffText: "No, delete it",
cls: "large"
});
});
</script>