Custom Radio Buttons with jQuery

January 13th | By | Back to Blog

I think every front-end developer had to deal with the situation when a certain design for a website or application includes a special design for general form elements like select boxes, checkboxes and radio buttons.

Form elements are native browser elements that look different on every OS, therefore its much more complex to design them with plain CSS rules, even if you wanted to. Browsers naturally do not support CSS properties for form elements other than margin, padding, fonts, colors and a handful of others. Any further design you might think-of has to be solved with JavaScript.

Well that is exactly what I am going to share with you here, creating a custom design radio button. Don’t expect for something crazy, we’re going to keep things simple, but feel free to take it further and design it anyway you like.

So, let’s get started, go ahead and create a plain HTML page with links to the style.css file and the jQuery library.

<link type="text/css" rel="stylesheet" href="style.css"/>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>

HTML

<form>
   <p class="radio">	
	<input type="radio" id="male" name="gender" value="male"/>
	<label for="male">Male</label>
	<input type="radio" id="female" name="gender" value="female"/>
	<label for="female">Female</label>
   </p>
</form>

Not much going on over there, very straight forward, mind that the input’s ID attribute and the label ‘for’ attributes are referencing each other, this will insure that clicking on the label itself will trigger the radio button change event.

CSS

p.radio { 
	font: normal 12px arial; 
}
p.radio input { 
	margin: 0; 
	padding: 0; 
	float: left; 
}
p.radio label { 
	display: block; 
	float: left; 
	margin-right: 15px; 
	cursor: pointer;
}
p.radio span.radio-container { 
	position: relative; 
	float: left; 
	margin-right: 3px; 
}
p.radio span.radio-container span.radio { 
	display: block; 
	width: 17px; 
	height: 18px;  
	background: url(radio.png) no-repeat top left; 
}
p.radio span.radio-container span.radio.selected { 
	background-position: top right; 
}
p.radio span.radio-container input { 
	position: absolute; 
	top: 0; 
	left: 0; 
	opacity: 0; 
	filter: alpha(opacity=0); 
	z-index: 101; 
	cursor: pointer; 
}

Lets explain a bit whats going on in there: we are going to to initiate the plugin on every radio button inside a p.radio so we have to make sure we assign that class to the wrapping p element.

The more interesting stuff are the span.radio-container and the span.radio elements. The span.radio-container will be a container that will hold the original radio button and the substitute span.radio that will be our designed radio button.

Also mind that we hide the original radio button by assigning opacity:0, the filter alpha thing is for IE8.

Last thing to make sure is to prepare the new radio button graphic and assign it as a background image, in this situation I prepared a sprite image and once the radio will be on active mode it will flip the image position.

jQuery

$(function(){
	
	$.fn.fancyRadio = function(){
		return $(this).each(function(){
			var p = $(this),
				container = $('<span class="radio-container"/>'),
				radio = $('<span class="radio"/>');

			p.find('input[type="radio"]').wrap(container);
			p.find('span.radio-container').append(radio);
			p.find('input:checked').parent()
									.find('span.radio').addClass('selected');

			p.find('input[type="radio"]').on('click',function(){
				p.find('span.selected').removeClass('selected');
				$(this).parent().find('span.radio').addClass('selected');
			});
		});
	};
	
	$('p.radio').fancyRadio();
});

So first we’re extending jQuery by creating a new function called fancyRadio, this function will be assigned to all p.radio elements, that’s the return.each() part for.

We’re creating a few variables that will reference the main HTML elements we want to work with, p will be the p.radio element, container is a new span element that will be injected to the DOM, radio will be the new designed radio button.

We then find the real radio element and wrap it with the container, and then we approach the container from the DOM and append to it the designed radio span. If there is already a selected radio option we’ll sync it with the substitute span by adding it the ‘selected’ class.

Lastly, we’ll trigger a click event handler for every radio button inside our p.radio element. Once its clicked it will remove or add a selected class to the new span.radio element, last thing is to call that function: $(‘p.radio’).fancyRadio();

Check out a demo here.