Styled Checkboxes/Radio buttons

by Scott Kaye

HTML

<label>
    <input type="checkbox"> This is a label
</label>

<label>
    <input type="checkbox" checked> This is a label
</label>

<label>
    <input type="radio" checked name="thing"> This is a label
</label>

<label>
    <input type="radio" checked name="thing"> This is a label
</label>

SCSS

label.wrapped-toggle {
    > input {
        display: none;
    }
	
	display: inline-block;
	vertical-align: middle;
	width: 20px;
	height: 20px;
	background: #ccc;
	position: relative;
	
	&[data-type=radio] {
		border-radius: 50%;
	}
	
	&.checked {
		background: red;
		box-shadow: inset 0 0 0 2px #000;
		
		&::before {
			content: "\2713";
			text-align: center;
			color: #fff;
			display: block;
			font-size: 0.8em;
		}
		
		&[data-type=radio]::before {
			content: "";
			position: absolute;
			width: 50%;
			height: 50%;
			top: 25%;
			left: 25%;
			background: #fff;
			border-radius: 50%;
		}
	}
}

JavaScript

console.clear();
$(function() {
    function makeToggle($el, customClass) {
        $el = $($el);
		
		// Protect against multiple calls on the same object
		if ($el.data("MakeToggle") !== undefined) {
			return;
		}
		
        var $box = $(document.createElement("label"))
            .attr("data-type", $el.prop("type"))
            .addClass("wrapped-toggle");
			
		if (typeof(customClass) === "string") {
			$box.addClass(customClass);
		}
			
		// wrap() clones $box, however we only care about the new instance
        $box = $el.wrap($box).parent();
		
		function change() {
			$box.toggleClass("checked", $(this).prop("checked"));
		}

		change.call($el);
		$el.data("MakeToggle", change.bind($el));
    }
	
	$(document.body).on("change", "input[type=checkbox],input[type=radio]", function() {
		// Handle radio buttons with the same name
		$("input[name='" + $(this).prop("name") + "']")
			.not(this)
			.add(this)
			.each(function() {
				// Update "linked"
				var toggle = $(this).data("MakeToggle");
				typeof(toggle) === "function" && toggle();
			});
	});

    $("input[type=checkbox],input[type=radio]").each(function() {
        makeToggle(this);
    });
});