Code an Awesome Registration Form with the Exotico UI Set

Vandelay Design may receive compensation from companies, products, and services covered on our site. For more details, please refer to our Disclosure page.

Today we’ll learn a few CSS tricks you can use to code your UI elements and keep them as awesome as they were in the PSDs.

I know, things are much easier when you have a good design, so we’ll use Exotico UI this time.

We’ll use inputs, progress bars, and buttons this time. If you want to see any other element coded, you can let us know via comments.

That said, let’s start the fun part.

Demo and Download!

This is the final result we’ll get. You can download demo files or just check the online demo and see how it works!

Preview of registration Form with the Exotico UI Set

Step #1 – Export PSD Elements

For this example, we’ll use CSS gradients. If you want a “safer” version just open your 2.psd and you’ll easily find those input buttons and the progress bars. Those fancy buttons are in the 3.psd file.

In my case I just used the psd to pick the colors, font styles.

Exporting the PSD elements

Step #2 – jQuery UI & HTML

We’ll use jQuery UI to generate our progress bar. It would be far easier this way since we just pass a value to it and it’ll automatically create the visible / hidden portion. Also, jQuery UI has binding options that allow us to do certain actions when the value of the progress bar is changed (it would be useful to update the amount of text).

Since our focus here is the CSS and elements, we’ll use a form based on a Nettuts+ tutorial, with a few adjustments, especially for the HTML elements, jQuery version, code tweaks, and of course, the styling.

jQuery UI can be quite heavy, so we can generate a custom jQuery UI bundle including only UI Core, Progressbar and Effects this time.
Starting the code, this is our basic HTML:

<!DOCTYPE html>
		<link rel="stylesheet" type="text/css" href="jqueryui1.8/development-bundle/themes/base/jquery.ui.core.css">
		<link rel="stylesheet" type="text/css" href="jqueryui1.8/development-bundle/themes/base/jquery.ui.theme.css">
		<link rel="stylesheet" type="text/css" href="jqueryui1.8/development-bundle/themes/base/jquery.ui.progressbar.css">
		<link rel="stylesheet" type="text/css" href="custom.css">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<title>Exotico Progress Bar</title>
		<script type="text/javascript" src="jqueryui1.8/development-bundle/jquery-1.7.2.js"></script>
		<script type="text/javascript" src="jqueryui1.8/development-bundle/ui/jquery.ui.core.js"></script>
		<script type="text/javascript" src="jqueryui1.8/development-bundle/ui/jquery-ui-1.8.20.custom.js"></script>

The important part here is to order js and CSS calls accordingly. Then we’ll need to add our form HTML. This will come right after opening the body tag:

<div class="ex-form ui-helper-clearfix ui-corner-all">
	<h1>Exotico form</h1>
	<div id="progress"></div><label id="amount">0%</label>
	<form action="#" method="GET">
		<div id="panel1" class="form-panel">
		  <h2>Personal Details</h2>
			<fieldset class="ui-corner-all">
					<span class="title">Name:</span>
					<span class="input"><input type="text"></span>
					<span class="title">Email:</span>
					<span class="input"><input type="text"></span>
					<span class="title">Password:</span>
					<span class="input"><input type="password"></span>
					<span class="title">Confirm Password:</span>
					<span class="input"><input type="password"></span>
		<div id="panel2" class="form-panel ui-helper-hidden">
		  <h2>Social Data</h2>
			<fieldset class="ui-corner-all">
					<span class="title">Twitter:</span>
					<span class="input"><input type="text"></span>
					<span class="title">Facebook:</span>
					<span class="input"><input type="text"></span>
				<div class="label">
					<label class="title" for="text">Bio:</label>
					<div class="input textarea">
						<textarea rows="3" cols="25" name="text" id="text"></textarea>
		<div id="thanks" class="form-panel ui-helper-hidden">
		  <h2>Registration Complete</h2>
			<fieldset class="ui-corner-all">
			<p>Thanks for registering!</p>
		<button id="next">Next <span>?</span></button><button id="back" disabled="disabled"><span>?</span> Back</button>

The best way (IMHO) to code forms is to include the input tag inside the label tag. There are a few reasons why I do so:

  • Saves you from using the “for” element, which is not the best option for accessibility (many screen readers can’t assign the label with the proper input, causing misunderstandings)
  • It’s easier to float / clear floats
  • It’ll allow us to easily add that gradient border effect (surprise!)

So far all you’ve got is an ugly page with a lot of ugly elements. Let’s make them prettier.

Step #3 – Basic CSS

The very first thing to do is to go to subtlepatterns.com and grab a cool background image. I’ve used the “White Wall” for our demo, feel free to use any other image (including dark backgrounds since Exotico comes with black background styles also).


Our main form will be positioned in the middle of the screen, and the trick to get this done is to set a fixed width for your element and margin left and right as auto.

Another really cool trick that I like to use is the rgba background. RGB, as you may have seen before is Red, Green and Blue (which should be set from 0 to 255). The last parameter is the alpha channel, which ranges between 0 (totally transparent) and 1 (totally opaque). This effect is pretty cool since it allows a translucent background but different than simple opacity rule, it won’t set the content as transparent.

“But, what about IE?” You may be asking to yourself now, dear Padawan.

IE (earlier than 9) doesn’t support rgba as you may imagine. So we’ll use Microsoft filters to get it working. An important note here is that the filter we’ll use is the gradient filter, but with same start color and end color. This filter allows alpha channel, set by the first 2 digits of your color code. But be aware that they are the hexadecimal value of the opacity, so 20% is the same as #33. You’ll probably need to do some math to convert different values or use tools out there for this conversion.

Also, we’ll need a little default markup for h1, h2 elements:

body {
	background: url(bg.png);
	.ex-form {
		margin:0 auto;
		font-family:Arial, sans-serif;
		background: rgba(150, 150, 150, 0.2);
		zoom: 1;
		h1, h2 {
			font-family:Arial, sans-serif;
			color: #6e6a65;
			text-transform: uppercase;
			text-align: center;
		h2 {
			margin:30px 0 10px;

Our #amount element needs to be in the top of the progress bar, and preferably in the middle of it. So, let’s position it as absolute and correct the values for it a little bit:

#amount {
	position: absolute;
	margin: -19px 0 0 -30px;
	width: 100%;
	font-size: 10px;
	font-weight: bold;
	color: #677764;
	text-align: center;

Our fieldsets will have same effect as our main panel, with a fancy rgba background. This code should do the trick for it:

.form-panel fieldset {
	margin:0 auto 20px;
	padding:20px 0;
	border: none;
	background: rgba(255, 255, 255, 0.2);
	zoom: 1;

Our very last item is a simple thank you message. We can make that prettier with this CSS:

#thanks {
	#thanks p {
		color: #6e6a65;

Now there are a few other items missing, but they are a little more advanced. Let’s talk about them now.

Step #4 – CSS Jedi Master

For the Progress Bar we’ll use an inset shadow for the background, and a gradient overlay to show what has yet been loaded. Also, we’ll add border-radius to make the bar look a little better.

.ui-progressbar {
	background: #e5e4e3!important;
	border: medium none;
	border-radius: 15px;
	box-shadow: 0 1px 2px #aaa inset;
.ui-progressbar .ui-progressbar-value {
	background: -moz-linear-gradient( left, #98c8a9, #e9e1a8 );
	background: -webkit-linear-gradient( left, #98c8a9, #e9e1a8 );
	background: -o-linear-gradient( left, #98c8a9, #e9e1a8 );
	background: -khtml-linear-gradient( left, #98c8a9, #e9e1a8 );
	background: -ms-linear-gradient( left, #98c8a9, #e9e1a8 );
	background: linear-gradient( to right, #98c8a9, #e9e1a8 );

	border: none;
	border-radius: 15px;
	box-shadow: 0 1px 2px #999 inset;
To style our buttons we’ll use html characters arrows. Then we’ll style it making use of linear gradients, make the span element looks like a circle, and a final touch, the cross browser opacity hover style:
.ex-form button {
	padding: 15px 20px 14px;
	margin-left: 30px;
	color: #9ca1a2;
	text-transform: uppercase;
	font-size: 10px;
	font-weight: bold;
	border: 1px solid #fff;
	background: #fff;

	background: -moz-linear-gradient( top, #ffffff, #eaeced );
	background: -webkit-linear-gradient( top, #ffffff, #eaeced );
	background: -o-linear-gradient( top, #ffffff, #eaeced );
	background: -khtml-linear-gradient( top, #ffffff, #eaeced );
	background: -ms-linear-gradient( top, #ffffff, #eaeced );
	background: linear-gradient( to bottom, #ffffff, #eaeced );

	border-radius: 25px;
	box-shadow: 0 1px 2px #787878;

	cursor: pointer;
	.ex-form button:hover {
		opacity: 0.8;
		filter: alpha(opacity=80);
	.ex-form button span {
		position: relative;
		padding: 2px 5px;
		top: -1px;
		background: #FBF9F7;
		border: 1px solid #d9dee0;
		border-radius: 10px;

We need to adjust our right and left arrows a little bit just to make the icons look better:

#back {
	padding-left: 15px;
	#back span{
		left: -5px
#next {
	padding-right: 15px;
	#next span{
		right: -5px

Now comes the effect that I like most, the focus input with a gradient border. Actually since gradients as border colors are even less supported than gradient backgrounds we’ll use an alternative.

Our effect will use a span that contains the background, but the input fills the whole span so that background is not visible. When we focus the input it’ll reduce its size a little bit and add a little margin so it’ll looks like we’ve added a border to it.

Same thing I said before can be applied here, you can use a background image, but in our demo we’ll use CSS gradients.

.form-panel .input {
	float: left;
	padding: 3px;
	margin-bottom: 13px;
	border-radius: 12px;

	background: -moz-linear-gradient( top, #98c8a9, #e9e1a8 );
	background: -webkit-linear-gradient( top, #98c8a9, #e9e1a8 );
	background: -o-linear-gradient( top, #98c8a9, #e9e1a8 );
	background: -khtml-linear-gradient( top, #98c8a9, #e9e1a8 );
	background: -ms-linear-gradient( top, #98c8a9, #e9e1a8 );
	background: linear-gradient( to bottom, #98c8a9, #e9e1a8 );
	.form-panel input, .form-panel textarea {
		float: left;
		padding: 8px 13px;
		margin: -3px;
		width: 240px;
		height: 12px;
		line-height: 12px;
		font-size: 12px;
		color: #9A9895;
		border: 1px solid #D7D6D5;
		cursor: text;
		border-radius: 12px;
		box-shadow: 0 1px 2px #999 inset;
		.form-panel input:focus, .form-panel textarea:focus {
			padding: 5px 10px;
			margin: 0;
			border-color: #fff;
			box-shadow: none ;
			outline: 0 none transparent;
	.form-panel textarea {
		height: 60px;

As you may notice we included here the textareas rules also, so inputs and textareas will have same effect but textareas requires divs wrapping them.

The last item that completes our CSS is our panels styling and labels titles styling:

.form-panel label, .form-panel .label {
	width: 100%;
	clear: left;
	cursor: pointer;
	.form-panel .title {
		color: #6E6A65;

Step #5 – A fix for IE

Since IE doesn’t support CSS gradients, we used that gradient filter property. The bad thing is that we can’t change the gradient direction, and it has a few issues (like using it with opacity for our button) but the overall effect is quite good.

Also IE9 supports border radius but it doesn’t work well when you have filters on it. So we’ll disable it for inputs via conditional comments in the HTML:

<!--[if IE 9]>
	 <style type="text/css">
		.form-panel .input, .form-panel input, .form-panel textarea {
			border-radius: 0;

Step #6 – JS Touch

The JS actions will allow fading between panels, updating progress bar and also update the next / back disabled status. Main features here are the caching stuff, and the function instead of repeating same code twice:

$(function() {
	//caching stuff
	$progress = $("#progress"), $amount = $("#amount"), panels = [], panels[0] = "panel1", panels[1] = "panel2", panels[3] = "thanks", i = 0, $formPanel = $(".form-panel");
	//call progress bar constructor
		change: function() {
			//update amount label when value changes
			$amount.text($progress.progressbar("option", "value") + "%");
	//same function to reuse code
	function changepanel(n) {
		//hide current item
		//selects next item
		i = i + n;
		//hide next item

		(i != 0) ? $("#back").attr("disabled", null) : $("#back").attr("disabled", "disabled");
		(i != 2) ? $("#next").attr("disabled", null) : $("#next").attr("disabled", "disabled");

		$progress.progressbar("option", "value", (i * 50) );
	//set click handler for buttons
	$(".ex-form button").click(function(e) {
		//stop form submission

		//next or back?
		var n = ($(this).attr("id") != "back") ? 1 : -1;