Animated Form Switching with jQuery

In this tutorial we will create a simple animated form switch with three very common forms. The idea is not to leave the page when the user goes to another […]

In this tutorial we will create a simple animated form switch with three very common forms. The idea is not to leave the page when the user goes to another form but instead make the new form appear within the same container, expanding or contracting to the dimensions of the new form.

We will ensure that the form switch works as well when JavaScript is disabled in which case we will simply jump to the other’s form page.

So, let’s begin by creating and styling the three forms.

Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.

The Markup

We will create three different forms, a login form, a registration form and a password reminder form with just one input field. They will all have different sizes and numbers of inputs.

First, we will create a wrapper for all three forms.

<div id="form_wrapper" class="form_wrapper">
<!-- We will add our forms here -->
</div>

Then we will add each form element to the wrapper and insert the necessary input fields. Each form is going to have a heading and a bottom box with the submit button. The registration form, which will be our first form, will have two columns that will float next to each other:

<form class="register">
	<h3>Register</h3>
	<div class="column">
		<div>
			<label>First Name:</label>
			<input type="text" />
		</div>
		<div>
			<label>Last Name:</label>
			<input type="text" />
		</div>
		<div>
			<label>Website:</label>
			<input type="text" value="http://"/>
		</div>
	</div>
	<div class="column">
		<div>
			<label>Username:</label>
			<input type="text"/>
		</div>
		<div>
			<label>Email:</label>
			<input type="text" />
		</div>
		<div>
			<label>Password:</label>
			<input type="password" />
		</div>
	</div>
	<div class="bottom">
		<div class="remember">
			<input type="checkbox" />
		</div>
		<input type="submit" value="Register" />
		<a href="index.html" rel="login" class="linkform">
			You have an account already? Log in here
		</a>
		<div class="clear"></div>
	</div>
</form>

Now we will add the login form. This form is going to be the one shown when the user visits the site. That’s why we will give it another special class “active”:

<form class="login active">
	<h3>Login</h3>
	<div>
		<label>Username:</label>
		<input type="text" />
	</div>
	<div>
		<label>Password: 
			<a href="forgot_password.html" rel="forgot_password" class="forgot linkform">
				Forgot your password?
			</a>
		</label>
		<input type="password" />
	</div>
	<div class="bottom">
		<div class="remember"><input type="checkbox" />
			<span>Keep me logged in</span>
		</div>
		<input type="submit" value="Login"></input>
		<a href="register.html" rel="register" class="linkform">
			You don't have an account yet? Register here
		</a>
		<div class="clear"></div>
	</div>
</form>

And finally, we will add the password reminder form:

<form class="forgot_password">
	<h3>Forgot Password</h3>
	<div>
		<label>Username or Email:</label>
		<input type="text" />
	</div>
	<div class="bottom">
		<input type="submit" value="Send reminder"></input>
		<a href="index.html" rel="login" class="linkform">
			Suddenly remebered? Log in here
		</a>
		<a href="register.html" rel="register" class="linkform">
			You don't have an account? Register here
		</a>
		<div class="clear"></div>
	</div>
</form>

The link elements that point to another form will all share the class “linkform” and in order for us to know which form to show when a user clicks the link, we will add the reference into the “rel” attribute. For example, the link “You don’t have an account? Register here” will have a rel attribute value of “register” since we want to show the registration form when we click on the link.

As you might have noticed, the “href” attribute will point to the static HTML page with the respective form. The link from the previous example will point to the index.html which contains our login form. This link will come into use, when JavaScript is disabled.

Now, let’s spice these forms up using some neat CSS3 properties.

The CSS

Let’s start with the form wrapper. We will give it a white background color, which will be the color we see, when the form is switching:

.form_wrapper{
	background:#fff;
	border:1px solid #ddd;
	margin:0 auto;
	width:350px;
	font-size:16px;
	-moz-box-shadow:1px 1px 7px #ccc;
	-webkit-box-shadow:1px 1px 7px #ccc;
	box-shadow:1px 1px 7px #ccc;
}

The heading of each form will have the following style:

.form_wrapper h3{
	padding:20px 30px 20px 30px;
	background-color:#444;
	color:#fff;
	font-size:25px;
	border-bottom:1px solid #ddd;
}

We want the forms not be displayed initially, but we will add a class that tells us that the form is active and should be visible:

.form_wrapper form{
	display:none;
	background:#fff;
}
form.active{
	display:block;
}

We will define now the width for each form. In our JavaScript function we will animate the form wrapper to the respective dimension:

form.login{
	width:350px;
}
form.register{
	width:550px;
}
form.forgot_password{
	width:300px;
}

The columns in the registration form will be floating next to each other:

.form_wrapper .column{
	width:47%;
	float:left;
}

The links in all our forms will have the following style:

.form_wrapper a{
	text-decoration:none;
	color:#777;
	font-size:12px;
}
.form_wrapper a:hover{
	color:#000;
}

Label elements have an inline style by default. We want our labels to be block elements:

.form_wrapper label{
	display:block;
	padding:10px 30px 0px 30px;
	margin:10px 0px 0px 0px;
}

We will style the inputs with some nice CSS3 properties, giving them a gradient as background and some neat box shadow:

.form_wrapper input[type="text"],
.form_wrapper input[type="password"]{
	border: solid 1px #E5E5E5;
	margin: 5px 30px 0px 30px;
	padding: 9px;
	display:block;
	font-size:16px;
	width:76%;
	background: #FFFFFF;
	background: 
		-webkit-gradient(
			linear, 
			left top, 
			left 25, 
			from(#FFFFFF), 
			color-stop(4%, #EEEEEE), 
			to(#FFFFFF)
		);
	background: 
		-moz-linear-gradient(
			top, 
			#FFFFFF,
			#EEEEEE 1px, 
			#FFFFFF 25px
			);
	-moz-box-shadow: 0px 0px 8px #f0f0f0;
	-webkit-box-shadow: 0px 0px 8px #f0f0f0;
	box-shadow: 0px 0px 8px #f0f0f0;
}
.form_wrapper input[type="text"]:focus,
.form_wrapper input[type="password"]:focus{
	background:#feffef;
}

The bottom part of each form will be similar to the heading background:

.form_wrapper .bottom{
	background-color:#444;
	border-top:1px solid #ddd;
	margin-top:20px;
	clear:both;
	color:#fff;
	text-shadow:1px 1px 1px #000;
}

The link elements will have the following style:

.form_wrapper .bottom a{
	display:block;
	clear:both;
	padding:10px 30px;
	text-align:right;
	color:#ffa800;
	text-shadow:1px 1px 1px #000;
}
.form_wrapper a.forgot{
	float:right;
	font-style:italic;
	line-height:24px;
	color:#ffa800;
	text-shadow:1px 1px 1px #fff;
}
.form_wrapper a.forgot:hover{
	color:#000;
}

We will make the wrapper for the remember me checkbox float:

.form_wrapper div.remember{
	float:left;
	width:140px;
	margin:20px 0px 20px 30px;
	font-size:11px;
}
.form_wrapper div.remember input{
	float:left;
	margin:2px 5px 0px 0px;
}

The submit button will have a very subtle inset shadow, nothing special:

.form_wrapper input[type="submit"] {
	background: #e3e3e3;
	border: 1px solid #ccc;
	color: #333;
	font-family: "Trebuchet MS", "Myriad Pro", sans-serif;
	font-size: 14px;
	font-weight: bold;
	padding: 8px 0 9px;
	text-align: center;
	width: 150px;
	cursor:pointer;
	float:right;
	margin:15px 20px 10px 10px;
	text-shadow: 0 1px 0px #fff;
	-moz-border-radius: 3px;
	-webkit-border-radius: 3px;
	border-radius: 3px;
	-moz-box-shadow: 0px 0px 2px #fff inset;
	-webkit-box-shadow: 0px 0px 2px #fff inset;
	box-shadow: 0px 0px 2px #fff inset;
}
.form_wrapper input[type="submit"]:hover {
	background: #d9d9d9;
	-moz-box-shadow: 0px 0px 2px #eaeaea inset;
	-webkit-box-shadow: 0px 0px 2px #eaeaea inset;
	box-shadow: 0px 0px 2px #eaeaea inset;
	color: #222;
}

And that’s all the style! Let’s add some Rock’n Roll with jQuery!

The JavaScript

The idea is to animate to the size of the new form and to switch to it, i.e. show it. So, first we will cache some elements:

//the form wrapper (includes all forms)
var $form_wrapper	= $('#form_wrapper'),

//the current form is the one with class "active"
$currentForm	= $form_wrapper.children('form.active'),
	
//the switch form links
$linkform		= $form_wrapper.find('.linkform');

We’ll get the width and height of each form to store it for later when we want to animate to it:

							
$form_wrapper.children('form').each(function(i){
	var $theForm	= $(this);
	//solve the inline display none problem when using fadeIn/fadeOut
	if(!$theForm.hasClass('active'))
		$theForm.hide();
	$theForm.data({
		width	: $theForm.width(),
		height	: $theForm.height()
	});
});

Now, we will call the function that sets the dimension of the wrapper to the one of the current form:


setWrapperWidth();

When we click a “switch link”, we want to hide the current form, since we know that we’ll switch to another one. We’ll animate the form wrapper’s width and height to the width and height of the new form. After the animation is done, we show the new form:

$linkform.bind('click',function(e){
	var $link	= $(this);
	var target	= $link.attr('rel');
	$currentForm.fadeOut(400,function(){
		//remove class "active" from current form
		$currentForm.removeClass('active');
		//new current form
		$currentForm= $form_wrapper.children('form.'+target);
		//animate the wrapper
		$form_wrapper.stop()
					 .animate({
						width	: $currentForm.data('width') + 'px',
						height	: $currentForm.data('height') + 'px'
					 },500,function(){
						//new form gets class "active"
						$currentForm.addClass('active');
						//show the new form
						$currentForm.fadeIn(400);
					 });
	});
	e.preventDefault();
});

The function that sets the width to the wrapper simply sets its css properties. We want to ensure that the wrapper has the right width and height set when we load the page.

function setWrapperWidth(){
	$form_wrapper.css({
		width	: $currentForm.data('width') + 'px',
		height	: $currentForm.data('height') + 'px'
	});
}

For the demo we disabled the submit buttons. If you use them, you will need to check which form is being submitted and give the class “active” to the form you want to switch to, i.e. show:

$form_wrapper.find('input[type="submit"]')
			 .click(function(e){
				e.preventDefault();
			 });	

And that’s it! We really hope you enjoyed the tutorial and find it useful!

Manoela Ilic

Manoela is the main tinkerer at Codrops. With a background in coding and passion for all things design, she creates web experiments and keeps frontend professionals informed about the latest trends.

Stay in the loop: Get your dose of frontend twice a week

👾 Hey! Looking for the latest in frontend? Twice a week, we'll deliver the freshest frontend news, website inspo, cool code demos, videos and UI animations right to your inbox.

Zero fluff, all quality, to make your Mondays and Thursdays more creative!

Feedback 40

Comments are closed.
  1. Fantastic effect… we can put it to use at several places.. and thank you for writing such a good tutorial..

  2. Hi, try to adapt this tuto, but it’s pretty hard for me to put my php code.
    can you help me ?
    thx

  3. Hi ML,

    Great, i like it, but let me see how the usage, mean what can i do to send the data? and how to add new (1) or more form?

    Thanks,

  4. After implementing this tutorial, I noticed that the animation does not work in IE. Has anyone else experienced this issue? Any ideas on how to fix this?

  5. Well thanks alot for this tutorial , i just have one simple problem , i would to implement Onsubmit button to each form . How i can do that? Thanks

  6. This is great. The problem i had with ie and other browsers was that the animation does not start with the first page load. but does work on subsequent once. Thank a lot Mary Lou

  7. It is very cool and amazing ;]

    Thank you.

    Now big question, how to activate buttons ?

    Is there a License somewhere ?

  8. To enable submit buttons delete following

    /*
    for the demo we disabled the submit buttons
    if you submit the form, you need to check the
    which form was submited, and give the class active
    to the form you want to show
    */
    $form_wrapper.find(‘input[type=”submit”]’)
    .click(function(e){
    e.preventDefault();
    });

  9. Hi Mary Lou – great tutorial! I have one quick question. Trying to call the forms up from a link elsewhere in the document doesn’t seem to work. I’ve added a linl like this:
    Register“. When I set the register form active, it shows, but when I click the link, nothing shows. In fact it appears to change the link, itself.

    Any help is appreciated!

  10. Best Login form.I think this is entirely different from others .nice work,great
    achievement,thanks for your hard work.

  11. Could you please specify or point to a php/anything that could activate the login/register button?

    thanks

  12. How do i make my sql and make users sign in and register and it will save to the database?
    Thanks!
    Send me an email to:Su-ha-yb@hotmail.com

  13. Hey MaryLou,

    How would I switch between forms with radio buttons instead of links?
    I’ve tried everything I can think of but I’m new to java/jquery so any help would be really appreciated.

    thank you

    Craig

  14. I’ve a question, who could i change the orange border, that appears if an Input-field is focused?

    thx hauke

    &Thx for the Tut.

  15. hi beautiful clean form! I always use mailchimp – where can I find a way to send data frim this form to my maiclhimp form?
    I know it is not css or html that will send data . There is no book telling you where to go for the anser 🙂 thanks for your time and help!