CheckDrag

by Apple Ilagan

HTML

<script src="http://draggabilly.desandro.com/draggabilly.pkgd.js"></script>
<h1>
    <label class="check-switch">
        <input type="checkbox" checked />
        <div class="track">
            <div class="knob"></div>
        </div>
    </label>
Check it
</h1>

<hr>

<p>Welcome, switchers. These are standard checkboxes styled to mimick a switch UI of our mobile forefathers. Defying reason, they are even <i>more</i> fun to toggle than a standard checkbox &mdash; even while using a mouse. Actually, mostly while using a mouse &hellip; the mobile performance still needs work.</p>

<hr>

<div id="main">
    <!-- Just a wrapper to demo font size inheritance -->
    <div style="font-size:.65em">
        <label class="check-switch">Pico<input type="checkbox" /><div class="track"><div class="knob"></div></div></label>
    </div>

    <!-- Just a wrapper to demo font size inheritance -->
    <div style="font-size:1.25em">
      <label class="check-switch">Nano<input type="checkbox" /><div class="track"><div class="knob"></div></div></label>
    </div>
  
    <!-- Just a wrapper to demo font size inheritance -->
    <div style="font-size:2em">
      <label class="check-switch">Jumbo<input type="checkbox" /><div class="track"><div class="knob"></div></div></label>
    </div>
</div>

CSS

/* Define active switch color */
$check-switch-color: hsla(120,95%,70%,1);


/* Hide our checkboxes */
.check-switch input[type="checkbox"] { 
	position: absolute;
	opacity: 0;
}

label.check-switch {
  clear: both;
  color: #999;
  display:inline-block;
 -webkit-tap-highlight-color: rgba(0,0,0,0);
}

/* Default Track */
.check-switch input[type="checkbox"] + .track {
	vertical-align: middle;
	width: 1.6588em;
  height:.95em;
	border: 1px solid rgba(0,0,0,.25);
	border-radius: 999px;
	background-color: rgba(0, 0, 0, 0.1);
	-webkit-transition-duration: .3s;
	-webkit-transition-property: background-color, box-shadow;
	box-shadow: inset 0 0 0 0px adjust-color($check-switch-color, $lightness: -30%, $alpha: -.25);
	margin: .5em 0 50px 0;
  cursor: pointer;
}

/* Default Track Checked */
.check-switch input[type="checkbox"]:checked + div {
  background-color: $check-switch-color;
	border: 1px solid adjust-color($check-switch-color, $lightness: -30%, $alpha: -.15);
	box-shadow: inset 0 0 0 .5em change-color($check-switch-color, $alpha: 0);
  
}

/* Default Knob */
.check-switch input[type="checkbox"] + div > div {
	left: 0;
	width: .95em;
  height: .95em;
	border-radius: inherit;
	background: #ffffff;
	-webkit-transition-timing-function: cubic-bezier(.54,1.85,.5,1);
	-webkit-transition-duration: 0.3s;
	-webkit-transition-property: transform, background-color, box-shadow;
	-moz-transition-timing-function: cubic-bezier(.54,1.85,.5,1);
	-moz-transition-duration: 0.3s;
	-moz-transition-property: transform, background-color;
	box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.3), 0px 0px 0 1px rgba(0, 0, 0, 0.2);
 	margin-top: 0;
}

/* Default Knob Checked */
.check-switch input[type="checkbox"]:checked + div > div {
  left: 0.699em;
	background-color: #fff;
	box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.3), 0 0 0 1px adjust-color($check-switch-color, $lightness: -35%, $alpha: -.5);
}

/* Fixes drag performance */
.check-switch .knob.is-dragging {
  -webkit-transition: none;
}


/* Demo page...

JavaScript

// OPTIONAL. Only adds drag support for the knob.

// Don't forget to add this external js
// http://draggabilly.desandro.com/draggabilly.pkgd.js

// Contributed by @desandro:
// use left/top for all positioning
Draggabilly.prototype.positionDrag = Draggabilly.prototype.setLeftTop;

$( function() {
  $('.knob').each( function( i, knob ) {
    var draggie = new Draggabilly( knob, {
      containment: true,
      axis: 'x'
    });
    draggie.on( 'dragMove', onDragMove );
    draggie.on( 'dragEnd', onDragEnd );
  
  });
});

function onDragMove( draggie ) {
  var $knob = $( draggie.element );
  var $label = $knob.parents('label');
  // on initial drag move
  if ( !draggie.hasDragged ) {
    draggie.movePotential = $knob.parent().width() - $knob.width();
    $label.on( 'click', onLabelClickDragging );
    draggie.input = $label.find('input')[0];
    draggie.hasDragged = true;
  }
  
  var isChecked = draggie.position.x > draggie.movePotential / 2;
  draggie.input.checked = isChecked;
}

// disable label clicks when dragging
function onLabelClickDragging( event ) {
  event.preventDefault();
}

function onDragEnd( draggie ) {
  // clear out Draggabilly's position setting
  draggie.element.style.left = '';
  delete draggie.hasDragged;  
  var $knob = $( draggie.element );
  var $label = $knob.parents('label');
  setTimeout( function() {
    $label.off( 'click', onLabelClickDragging );
  });
}