I am available for freelance work - HIRE ME

Improving the Login Form Experience

posted by Matt Ward on Sep 1, 2011.

Login forms are a common element that appear on a large number of websites. In this article, we will be looking at how we can use a bit of CSS and jQuery to create an elegant, usable drop down form. We will also be looking at how to maintain usability by creating an alternative for users who do not have JavaScript enabled.

Over the past few months, it seems that pretty much every site I’ve been working on has required functionality that allows users to register and then log in, either to access certain content or to interact with the site in some way. As such, I’ve been working to determine the most usable solution to provide a seamless user experience.

In this article, I would like to look at one popular technique that I tend to favour for a number of different reasons. First, we’ll look at how to achieve it using a bit of jQuery. More importantly, however, we’ll also be considering how to develop the entire thing so that it degrades gracefully for users who may have JavaScript turned off, maintaining usability and preventing a poor experience for these users.

The Concept

The basic concept is to have a single login button in the top right hand corner of the page. It could be a single button that stands on its own, as we see on something like Twitter’s post log out page (shown below). Or, it could be part of a larger menu, as we see on a site like MediaLoot.

We van see the drop down menu on Twitter after we've logged out

We van see the drop down menu on Twitter after we've logged out

Either way, when the user clicks on the button a small but simple form appears directly below, allowing the user to log in.

What I like about this technique is its immediacy. The user indicates their desire to log in and is immediately presented with the interface to perform that action. There is no need to wait for another page to load. Also, with the Twitter page, focus is automatically given to the username field, meaning that the user can start typing without any additional clicks.

It’s little details like this—which work to reduce the amount of time it takes to perform a particular action—that really enrich the user experience. So, let’s look at how to do it.

The Markup

The first thing we’re going to need to make this work is a bit of HTML. Here’s what we’ll be starting with:

<ul> 
   <li><a href="#" id="loginButton">login</a></li> 
</ul>

Since we’re only using a single button in this example, it would be possible to use just a single link, but I generally tend to have the login button as part of a larger menu—perhaps featuring home, register, contact or other buttons. So, I am working from a simple unordered list. This will also provide some structural hooks that will come in handy later.

Obviously, this list will also be surrounded by the additional markup which forms the rest of the document. There’s no real reason to reproduce that here though.

The CSS

Next, we need to style it up with some CSS. Again, I’m not going to reproduce all the rules that are used to style the complete list, the button and the form inputs, since those are choices that are going to be made based on the specific design of a given site. What I do want to focus on are some of the more functional styles that we’ll need for the form element itself:

ul li{
   position: relative
}
ul li form{
   position: absolute;
   top: 33px;
   right: 0px;
   display: none;
}

First, we want to set the position of the list element to be relative. Why? Because we will actually be appending the login form into that element, right after the link itself. By setting the individual list element (the parent) to position:relative, we can then set the form element (the child) to position:absolute, allowing us to place the form relative to the button.

We can then set the top property to whatever value is required to ensure that the login form appears directly beneath the button (this is usually equal to the height of the button itself, including padding).

Lastly, we simply set the display property to none, as we only want the form to be revealed when the button his clicked.

Again, the properties I’ve listed here are only those necessary to control the behavior of our form. You will also likely want to style things like the background and text colours, or possibly even use some CSS3 properties like border-radius, box-shadow or text-shadow to really enhance the visual experience of the form (see the form button in the demo).

The jQuery

You may be wondering about this form I keep referencing. With the HTML and CSS we have thus far, there is no form. That’s also exactly what we want. We’re now going to create the form dynamically, using a bit of jQuery. Here is the code:

jQuery(document).ready(function(){
   var formHTML  = '<form id="loginform" method="post">'; 
   formHTML += '<input type="text" name="username" id="username" value="username" />';  
   formHTML += '<input type="password" name="userpass" id="userpass" value="password" /> '; 
   formHTML += '<button type="submit">Login</button>'; 
   formHTML += '</form>'; 
   jQuery("#loginButton").append(formHTML);
}

This code assumes that you already have jQuery linked into your document. Once the document has been loaded, we declare a variable named formHTML and fill it with the simple HTML that will make up our form. Then, we use the jQuery append() method to add the form into the list element, which now looks more or less like this:

<ul> 
   <li><a href="login.html" id="loginButton">login</a>
      <form id="loginform" method="post">'; 
         <input type="text" name="username" id="username" value="username" />  
         <input type="password" name="userpass" id="userpass" value="password" /> 
         <button type="submit">Login</button> 
      </form>			
   </li> 
</ul>

Of course, because of the CSS we added, you won’t actually see this form being dynamically added to the DOM, which is exactly the type of invisible behavior that we want. For the user, it will be as though the form was always there, just waiting to be revealed. Unfortunately, if you were to click the button at this point, nothing would happen. So we need to add the following code to our jQuery listener:

jQuery("#loginButton").click(function(){
   jQuery("#loginform").slideDown(250,function(){
      jQuery("#username").focus();
      jQuery('html').click(function() {
         jQuery("#loginform").slideUp(500,function(){
            jQuery('html').unbind('click');
            jQuery("#loginform").unbind('click');
            jQuery("#loginButton").toggleClass('clicked');				
         });
      });
      jQuery('#loginform').click(function(event){
         event.stopPropagation();
      });
   });
   jQuery(this).toggleClass('clicked');
});

There are a lot of nested functions in this, but what’s going on here is really simple. We’re telling jQuery that when the login button is clicked we want the login form (targeted by its ID) to slide down and become visible—with the animation taking 250 milliseconds. Once the animation is complete, we immediately add focus to the username field.

It is very common for elements like our form (or like modal or lightboxes) to close automatically whenever the user clicks anywhere else on the screen. The Twitter login form I mentioned above does this, and we’ll be emulating this behavior with the next few lines. Once the form has been revealed, we will apply another listener, which is triggered any time the document (html element) is clicked. The associated function will then slide the form back up to its hidden state, unbind the active listeners and toggle the clicked class (which we’ll get to).

There is, however, one problem with this: because the form itself is part of the DOM (obviously), if we click it for any reason, the form will close. Yes, that is bad for the user experience.

Fortunately, we can fix this using the stopPropagation() method. Basically, this stops the click listener we set for the html element from being applied to our form element, thus allowing us to click on it without also closing it. Beyond that, I’m not sure exactly how the method works. I’m just glad that it does.

Lastly, when the login button his clicked I also use the toggleClass() method to add the class of “clicked” . This allows us to apply different styles to the button when the form is open or active. This class is also toggled off when the form is closed.

The Fall Back

By this point, we should have a nice, functional drop down form that makes logging into the site a simple and easy process.

Unless, of course, the user has JavaScript disabled.

In that case, it’s not usable at all because the login form simply will not appear. In fact, it won’t even exist, because the script that we used to create it will not be executed. If we stopped here, it would be a definite UX fail.

We could use the noscript tag to inform users that JavaScript is required in order to use the site, but that doesn’t make for the best experience either. Instead, we can make a couple simple changes to our code to create a simple, usable fallback position that does not rely on JavaScript at all.

First, we’ll add an actual value to the href property in our button. This should link to a separate login page, which you will need to create (or use one that already exists). Our HTML will now look like this:

<ul> 
   <li><a href="index.html" id="loginButton">login</a></li> 
</ul>

When the user clicks on the login button, they will now be taken directly to the separate login page. It’s not as elegant as having the login form drop down on the same page, but it is still a perfectly usable alternative for users who don’t have JavaScript enabled.

The only hiccup here is that this link triggers for all users, meaning that even users who do have JavaScript enabled will be forwarded to the separate page, thus rendering all our hard work on the drop down useless. Fortunately, this is easy to fix too. Just insert the following line of code directly before the block that automatically generates the form.

jQuery("#loginButton").removeAttr("href");

The logic here is simple. If JavaScript is enabled, it will execute and remove the href attribute from the login button, thereby breaking the link and preventing it from sending the user to another page. The script can then continue as intended and generate the login form, revealing it whenever the button his clicked. If JavaScript disabled, the href (and our fallback) remains completely intact.

Using this technique, we have enhanced the login experience using jQuery, while still maintaining usability in situations where the our scripts cannot be executed.

Here's a simple screenshot of what the drop down will look like (with a few more styles)

Here's a simple screenshot of what the drop down will look like (with a few more styles)

Check out the demo

(Also, don’t forget to try turning of your JavaScript)

A Pure CSS Solution

For you purists out there, it would likely be possible to create a similar effect using pure CSS. I’ve played around with this, and while it is certainly possible to make the form appear on a hover, I have not found a way to make it appear on a click. A hover-based CSS solution also has the distinct drawback of requiring the persistence of the hover state; if the user moves the mouse away, the form disappears.

In my opinion, this hurts overall usability.

There are also touch-based devices to consider, which do not support hover functionality. Without this support, using hover to reveal the login form would also seriously effect usability on these devices.

For these reasons, I feel that using a JavaScript technique—with an appropriate fallback—provides the most usable experience. If anyone knows of a pure CSS, however, I’d love to hear about it!

Also, feel free to use any of the code that was discussed in this article or that appears in the demo for your own purposes.

Post A Comment

Also from Echo Enduring Media:

An Unfolding Tale

About the Author

Matt Ward is a digital artist who lances freely under the moniker of Echo Enduring Media, and specializes in graphics design, illustration and writing. He is also the Creative Director for Highland Marketing, a creative direct marketing company based out of Waterloo, Ontario. You can follow Matt on Twitter

Like this post? Help Promote it!

Comments

Sep 1, 2011

Luca Degasperi says:

Probably with the :target pseudo selector you can achieve a CSS only solution.

Sep 1, 2011

Matt Ward says:

Thanks for the suggestion.

Based on my understanding of the selector, it would not be functional in IE 8 or lower, which presents a usability problem in and of itself. Since it also seems to target the #element portion of the URL, I believe it will actually call another page load, right? Even if everything is cached, that may not be ideal.

Sep 1, 2011

Colin says:

Hey Matt,

Nice article, I definitely prefer this UX over having to go to a separate login page every time.

I did however have some undesired results when testing out the demo in FireFox 6.0.1. As soon as I click on a field it makes the entire fly out disappear.

Can anyone else replicate this behavior or is it just me?

Sep 1, 2011

Matt Ward says:

That’s odd. It sounds like the stopPropegation() method isn’t working. I’m not running FireFox 6 yet. Perhaps there is a change in their JavaScript engine that renders breaks the jQuery function?

Sep 1, 2011

MawnOh says:

For the complete Twitter look, go for http://twitter.github.com/bootstrap/

Sep 1, 2011

Jacob Gube says:

It wouldn’t reload the page because it’s just a fragment ID, just like using the .slideUp() method doesn’t trigger a page reload.

Sep 2, 2011

Miriam Rahamim says:

I personally dislike this type of login forms, It does not work on each browser, and if you move your mouse a bit the login form just disappear, I prefer steady and normal login form, one that dont play “hide and seek” :)

Though the great and comfy look and design of the form you presented is great, Personally I wouldn`t use it.

Thanks. :)

Sep 2, 2011

derek says:

im getting the same thing in firefox 5.0.1

the login menu closes when clicking the input

Sep 3, 2011

Gavin says:

This happens because the $(‘html’).click doesn’t care whether you are clicking somewhere outside of the form or not.

I’m about to post some revised code that may help.

Sep 3, 2011

Gavin says:

Odd. I replied to someone’s comment and it shows it as an actual comment?

Anyhoo.

Whilst your post is great, I noticed a few issues with it unfortunately.

* Your appending the form inside the loginButton element. This is causing the usability issue as the loginButton click event is firing when you focus on the form.
* As above, your html is now invalid.
* Usability – You shouldn’t be removing the href tag. Instead you simply should be cancelling the click event.
* Your html click event also wasn’t checking to see if you were clicking on the form elements or not. So it would have hidden the form before you could submit it.

To get around this, take a look at the source of: http://jsbin.com/osapof

Cheers

Sep 6, 2011

chris says:

its not working how it should be not in FF or any other browser

Sep 6, 2011

Jeremy P says:

I think it’s a really complicated way to do that, why create dynamically the form? why not just simply write it in the html, and on click event : if open > close it, else > open it. So, 3 lines of javascript, and no modification of the DOM. (and it’s work on FF6 )

Do you have any reason to create this form dynamically?

Sep 9, 2011

Pieter Beulque says:

Why break the link by removing the href attribute? I think that could cause some bad behavior in some browsers…

Why not use:

$().click(function () {
// Logic
return false;
}

Just my thoughts…

Sep 10, 2011

David Hancock says:

Nice article, however reporting the same problem here in the Chrome beta (v14).

Login form fades out on input click.

Sep 13, 2011

GU says:

Another way to impress your more-attentive (more-anal?) visitors: “Log in” is the verb, whereas “login” is a noun. So the button you click to log in should say, “Log in,” not “Login.” ;-)

Sep 19, 2011

ArleyM says:

It’s interesting that Twitter is the example – there’s one thing about that login that bugs me!

According to stats from Twitter, 72% of all tweets come from the web interface – this means that 72% of Twitter users are going to have to login semi regularly.

To me, it would make more sense if that l login form wasn’t hidden, but on the site – and like Gmail, the username is active so I can start typing as soon as I’m on there!

It’s a naggy little detail to save a lazy user like me one click, but since the whole purpose of that landing page is to sign up or login, it might be nice!

Sep 19, 2011

ArleyM says:

Heh, after posting that I checked the front page and realize the login isn’t hidden anymore. Maybe it doesn’t bug me as much as I thought since I didn’t notice!

Sep 25, 2011

mmoVZ says:

The concept is really good. I especially like the Twitter login, simly because it’s so easy to use. Should start implementing a login like the one shown on my site. Thanks for the heads up and tips!

Oct 4, 2011

Web Design in Worthing says:

Great article and I love the idea of the login panel. I think there may be a few holes in cross-browser compatibility but you have set a really good foundation for the approach.

Thanks again for a great article.

Jan 24, 2012

threadsfaisal says:

Great article and I love the idea of the login panel. I think there may be a few holes in cross-browser compatibility but you have set a really good foundation for the approach.

Thanks again for a great article.

Feb 13, 2012

Kzqai says:

Well, this article turned me off the site. Such a broken approach…

Leave a Comment

Links

Top Commenters

Thanks so much to these awesome people for joining in on the discussion!

Copyright © Echo Enduring Media 2009-2014