Download our free how-to guide for setting up your new Drupal site and using our themes

Horizontal User Login Block - Using CSS and jQuery

There are many ways to style and reorganize the user login block, especially with the power that Drupal 6 provides themers. As you probably know, the user login block displays vertically by default. A few of our themes require that the user login block be displayed horizontally to better fit the look and feel of the theme. I set out to find a way to achieve this without editing any *.tpl files. By just editing the theme’s CSS I was able to get the results we were looking for and have complete control over the styling of the user login block. I also learned some neat tricks using jQuery to help with the display of the labels for the input fields.

Horizontal user login block

Adding the necessary scripts

In this example using Drupal 6 I am going to show you how to style the user login block to be horizontal rather than vertical and also incorporate the use of the jQuery overlabel script. This makes your input labels be displayed in the input forms themselves and hide when there is text in them and display when they are empty (check out an example). This makes for a nice clean horizontal user login block and requires no custom programming.

Being that Drupal 6 ships with jQuery there is no need to download it. All we need is to download the jQuery overlabel file and add it to our theme’s directory. Be sure to remove the “_.txt” from the end of this file so it is named “jquery.overlabel.js”.

We then need to create a script.js file if there already isn’t one in your theme’s directory. Create and open the script.js file and add this bit of code to use the jQuery overlabel script on your user login input fields.


$(document).ready(function() {
$("#header-top label").overlabel();
});

In the code you see above, “#header-top label”, refers to the region I am loading my user login block. In this case I am loading it in the “header-top” region. You can change this to suit your needs but for this example my CSS will also be referencing this region, so change as needed.

Horizontal user login block

Editing the .info file

Now we need to call the jQuery overlabel through your theme’s .info file. Open the .info file and add these two lines:

scripts[] = script.js
scripts[] = jquery.overlabel.js

This will make sure that when you are viewing your site with your theme the “script.js” and “jquery.overlabel.js” files will be loaded and ready for use. You may need to clear your cached data so your theme loads these files correctly. To be sure navigate to this page “/admin/settings/performance” and click the button that says “Clear cached data”. Once the cache has been cleared check the source code for the page and make sure these two files are loading now.

Now that we have the necessary jQuery scripts in place we need to place the user login block in the appropriate region. I chose to place my user login block in the “header-top” region. Once it’s in place go ahead and log out of your site so the user login block is displayed in the appropriate region. Now we can begin our styling as needed.

CSS Magic

There’s a bit of CSS code below so I recommend copying it to your theme and editing there to make it fit your theme better. Again, the CSS is targeting the user login block when placed in the “header-top” region. So rename the divs as needed to fit your site.


html.js #header-top #block-user-0,
#header-top #block-user-0 {
display: block;
height: 4em;
margin: 0;
padding: 0;
position: relative;
width: 500px;
}
#header-top #block-user-0 {
height: 6em;
margin-top: -35px;
}
#header-top #block-user-0 .content {
padding: 0;
margin: -10px 0 0 0;
}
#header-top #block-user-0 h2.title {
display: none;
}
#header-top #block-user-0 #edit-pass-wrapper {
display: block;
float: left;
margin-left: 10px;
margin-right: 10px;
}
#header-top #block-user-0 #user-login-form {
margin: 0;
padding: 0;
}
html.js #header-top #block-user-0 #user-login-form label {
color: #4e4e4e;
font-size: 85%;
font-weight: normal;
margin-left: 7px;
position: absolute;
text-align: left;
}
#header-top #block-user-0 #user-login-form label {
position: static;
margin-left: 2px;
text-align: left;
}
#header-top #block-user-0 #user-login-form input.form-text {
border: 1px solid #ccc;
padding: 1px;
width: 115px;
}
#header-top #block-user-0 #edit-name-wrapper {
display: block;
float: left;
}
html.js #header-top #block-user-0 #user-login-form input.form-submit,
#header-top #block-user-0 #user-login-form input.form-submit {
clear: none;
float: right;
margin: 12px 0 0 0;
}
#header-top #block-user-0 #user-login-form input.form-submit {
clear: none;
margin: 30px 0 0 0;
}
html.js #header-top #block-user-0 .item-list,
#header-top #block-user-0 .item-list {
float: none;
margin: 2px 0 -15px 0;
padding: 5px 0 0 0;
text-align: left;
width: auto;
}
#header-top #block-user-0 .item-list {
float: right;
margin: -17px 105px -15px 0;
}
#header-top #block-user-0 .item-list ul {
margin: 0;
padding: 0;
}
#header-top #block-user-0 .item-list li {
margin: 0;
padding: 0 0 0 20px;
list-style: none;
font-size: 77%;
}

This bit of CSS will get your user login block to transform into a horizontal login rather than vertical. You may need to tweak the margins and padding to suit your theme but this should get you most of the way there. It also accounts for the lack of javascript so it degrades nicely and displays the labels for the input fields above rather than inside the input fields in case javascript is disabled.

Horizontal user login block

So whether your user has javascript enabled or disabled they will see the horizontal user login block and still be able to log in to the site without problems.

OpenID

Another bit of CSS you may want to add is the styling for the OpenID portion of the user login. Things look a little off if the OpenID module is enabled and not styled to fit this new look for the horizontal user login block, so it takes some more CSS to make it look good again. Add this CSS to style the OpenID options in the user login block correctly.

Horizontal user login block


/* OpenID */
#header-top #block-user-0 #edit-openid-identifier {
display: block;
text-align: left;
}
#header-top #block-user-0 #user-login-form input#edit-openid-identifier.form-text {
margin-top: 1px;
padding: 1px 1px 1px 20px;
width: 130px;
}
#header-top #block-user-0 #user-login-form input#edit-openid-identifier.form-text {
padding: 1px 1px 1px 20px;
width: 130px;
float: left;
margin: 0 10px 0 0;
}
#header-top #block-user-0 #edit-openid-identifier-wrapper {
float: left;
width: 160px;
}
#header-top #block-user-0 #edit-openid-identifier-wrapper .description {
font-size: 77%;
text-align: left;
}
html.js #header-top #block-user-0 #edit-openid-identifier-wrapper label {
padding: 0 0 0 20px;
}
#header-top #block-user-0 #edit-openid-identifier-wrapper label {
padding: 0;
margin: 0;
}
#header-top #block-user-0 #user-login-form li.openid-link,
#header-top #block-user-0 #user-login li.openid-link {
background: none;
}
#header-top #block-user-0 #edit-openid-identifier-wrapper .description a,
#header-top #block-user-0 .item-list li a {
text-decoration: none;
}
#header-top #block-user-0 #edit-openid-identifier-wrapper .description a:hover,
#header-top #block-user-0 .item-list li a:hover {
text-decoration: underline;
}

IE Fixes..

Just like anything good on the web, IE comes along and ruins it. Here are a few fixes to get your horizontal user login block looking and working correctly in IE7 and IE6.

IE6

Add this bit of CSS to your IE6 stylesheet.


#header-top #block-user-0 .item-list {
position: relative;
}
#header-top #block-user-0 .item-list li {
padding: 0 0 0 10px;
}

IE7

Add this bit of CSS to your IE7 stylesheet.


#header-top #block-user-0 .item-list {
position: relative;
}
#header-top #block-user-0 .item-list li {
padding: 0 0 0 10px;
}

Again, this code is targeting the user login block when displayed in the “header-top” region. So change that as needed throughout the scripts and CSS files so it fits your theme correctly. You may want to display the user logon block in other regions so that is key to making it look and function correctly.

Conclusion

This is just one example of taking a default Drupal block and molding it to your needs, and the attention to detail and polishing we provide for our themes. Just wanted to share this bit of information because I know it would work well for a lot of people (wish I would have found jQuery overlabel earlier!) and it’s quite easy to modify to fit your needs.

It’s good to know the user login block can be so flexible, especially since it’s used so much and in so many different instances it needs to be flexible. The power of CSS really does the work here and it’s a bit cleaner with the addition of the jQuery overlabel script. This example can be used in many many different ways so feel free to rip it apart and mold it to your theme and your needs. Enjoy!

Edit: Here is another option if you want to use a module instead of downloading the jQuery overlabel script - http://drupal.org/project/compact_forms.

I've experienced issues using jQuery overlabel when the browser pre-fills the username and/or password. Because the label is actually on top of the input field rather than inside it, it stays there when the input value is changed by anything but user input.

Annoyingly, browser pre-fillers don't seem to reliably trigger any element events, thus making it very hard to work around this bug reliably.

I've noticed that issue too but I felt it was minor enough to not really worry about. Like when you have your username/password saved in your browser and view the site it prefills in those fields and still shows text over it.

If it's too much of an annoyance you can always remove the jQuery overlabel file and tweak the CSS a little for the label field.

This is cool. Few things :

1. I got it to works on my custom zen-based theme but not on marina_acquia, which the label is on top of the field, but it's gone when click on the field (when entering username or password).

2.How about getting the "Create new account" and "Request new password" in a row as well ?

This is an excellent article. I too noticed the text overwriting the boxes but was able to move them where I wanted them. However, I can't seem to get rid of the "discs" that indicate a list item. I have tried everything I can think of but I have no idea how to override the system CSS that makes them appear. Help is appreciated.

Hi PONKABONK, to remove the list styling applied by default on the list items you may need to add this bit of code to your CSS:

#block-user-0 .item-list li {
list-style: none;
list-style-image: none;
}

Could also try adding an "!important" after your CSS element to make it the top level CSS factor.

#block-user-0 .item-list li {
list-style: none !important;
list-style-image: none !important;
}

That should do the trick. If not, there is something on a higher level in the CSS that is controlling the display of your list items and needs a higher level div in front of the div you are calling here in the CSS. Hope that helps!

Thanks Jeremy. Surprisingly, I was doing everything as you suggested already. However, having you verify that helped a great deal. The bullet I was seeing was an artifact from the Garland theme I'm modifying and was actually a background image to the list. Once I figured that out I was able to override it in the CSS. Thanks a bunch!

-Mike

What would one need to do for Drupal 5?

Obviously themes in Drupal 5 do not contain info files, so where does the appropriate information above go?

Thanks!

Hey Chad, the best place to call the javascript file in Drupal 5 is through your template.php file.

drupal_add_js($theme_path . '/jquery.overlabel.js');
$vars['scripts'] = drupal_get_js();

This bit of code goes in the template.php in the "page" area. Might need to download a solid template.php theme and see how they do it but ideally it should be added to the template.php file.

You can also add it to the page.tpl.php if you can't figure out how to get it added to the template.php but give the other method a try first.

Any ideas how to make the "tab" and "enter" keys to work?

nevermind... it was my install, works like a charm :)

Thanks, this saved me mucho time.

Has anyone worked out how to right-align this in Acquia Slate? If I float it, i end up with the links on a second line.

Thanks

@Jerome, here is code that will right-align the user login block when placed in the #header-top region:

#header-top #block-user-0 {
float: right;
}

Hope this helps.

This is an excellent article and very easy to follow! I only have a passing acquaintance with CSS, but I managed to tweak it to work on the theme I'm using.

Very nice article indeed. I did horizontal drupal login block with links. Very simple clean code that just uses css. You just need to add a block.

http://www.dashplanet.com/webmasters/drupal-cms/customizing-the-drupal-l...

Problem with contact module... I've applied this to the Sky theme and enabled the contact module. The 'contact' link is displayed as a primary link. Whenever I go to the contact page (and this does not occur on any other page, nor is it affected by changing the order of the primary links), the login block is screwed up. The name input box is above the password input and buttons.

Looking at the page source of the contact page I think this is because the contact form creates an element called "edit-name-wrapper" before the login block, so the login block gets and element called "edit-name-1-wrapper".

So where the css has
#page-title #block-user-0 #edit-name-wrapper{
display: block;
float: left;
}

I added this just below it
#page-title #block-user-0 #edit-name-1-wrapper{
display: block;
float: left;
}

This seems to work, but I'm not a CSS expert - is there a better way to handle this?

Hi, thanks for this, great help.

I am having an issue with the text staying in the fields when a user/i go to type in them, there seemingly is no way to delete them.

Probably a simple fix?

Guess I could just run them light grey so they sit in the background alittle cleaner, but i would rather find a way to make them remove on touch/type.

Thanks

In response to comment #1

The best work around I have found so far to remove the overlabel when a browser auto-fills the username/password is to call the jQuery with the following code:

$(window).load(function() {
$("#header-top label").overlabel();
});

Basically what it does it wait until the whole page has been loaded before executing the jQuery script.

It's not perfect because the browser will auto-fill, then the jQuery is loaded and it overlabels the text, then it removes the overlabel within about a second.

If anyone has a better solution to this issue I would really like to hear about it.

Hi. Great tutorial!

I added a 'remember me' option to my login (Persistent Login Module) but it doesn't seem to appear in my login block (after applying this tutorial). It is however being shown in /user login page.