How to Build a Custom Login Page Design for WordPress

If you are a heavy WordPress user then it’s likely you’re interested in deep customizations. There are a slew of plug-ins available, but some tasks are just easier to perform yourself. As an example, the login/register forms are often unfitting to match the template of most websites.

Speckyboy Custom WordPress Login Page

But thanks to a few genius developers there are simple guidelines to including your own custom styles. In this guide I’ll walk you through the process of designing a totally custom login page in WordPress. We have a small demo example up for the Speckyboy login.

Building a Custom WordPress Login Page

Attaching an External Stylesheet

The easiest way to create a custom design is to modify the standard WordPress template. So first we’ll need to create a CSS file and add it into the login page via some PHP code. WordPress allows you to add backend code into a functions.php library file, generally stored in your themes folder.

Where you store the CSS file doesn’t matter. I’ve titled it specky-custom-login.css and uploaded to /css/ in the root directory. Now if you don’t have a functions template file already then create a blank document and save as functions.php. Upload this to your active theme directory and you should see it appear in the admin editor area.

Now we just need some code to add the custom stylesheet we’ve created. However at the top of your functions file it’s common practice to include a bit of metadata. This would include the theme, author’s name, and other important information about the file. Below is an example section:

 * Custom Theme Functions
 * @package WordPress
 * @subpackage yourtheme
 * @author Jake Rocheleau
 * @copyright 2011

Make sure you close the PHP tag which we opened above. You may have other functions in this file already. But just in-case you’re starting fresh you need to open/close the PHP tags in-between all code you write here.

So now we need the code to append our style into the header. WordPress uses an internal function add_action() to implement such a feature. Check out the example below to see if you can follow along.

 * @desc attach custom admin login CSS file
function custom_login_css() { 

  echo '&lt;link rel="stylesheet" type="text/css" href="'.get_bloginfo('template_directory').'/css/specky-custom-login.css" />';

add_action('login_head', 'custom_login_css');

The add_action() method parses WordPress for an area named login_head. This coincides with the HTML head area of the login and registration page. Then the second parameter asks for a function to call, and in this case it looks for custom_login_css() which we just wrote. It outputs a stylesheet attachment which points to a ‘css’ folder in our theme directory. You can change this to whatever location your file is stored.

How to Edit WP Filters

Along with actions WordPress has created something called a filter. This can replace specific data in a template without requiring you to edit the file in question. This can be used to our advantage here by editing the login form header URL link. By default it points to

Beneath the code we just wrote add this block next. It will replace the filter for login_headerurl which inks the top page header over to WordPress.

  * @desc update logo URL to point towards DI
add_filter( 'login_headerurl', 'custom_login_header_url' );
function custom_login_header_url($url) {
  return '';

Instead we return a string value leading to an alternate website – generally this could be your website homepage. Just make sure your function name matches the 2nd value entered within the add_filter() command.

There are other similar filters you can perform from directly within your functions.php. I recommend the WordPress online filter reference which acts as a sort of documentation. But for now lets move onto the CSS aspect and code one awesome design.

Cascading New Styles

Now instead of deleting the default WordPress stylesheet, it’s easier to actually work off that as a template. You can find most of the original styles within /wp-admin/css/login.css. This is also how you can target some of the page elements – although I recommend using IDs at times where precedence takes over.

Since CSS is a cascading language only the properties with a more direct selector will be applied. This means body div { } is much too vague compared to body.login div#login { } and styles in the latter would generally override the former. But demo code is easier to understand, so I’ve included a bit of my styles below.

#loginform p label #user_login, #loginform p label #user_pass { 
font-weight: normal;
padding: 8px 9px;
font-size: 14px;
font-style: normal;
border-right-color: #dadada;
border-bottom-color: #dadada;
color: #999 !important;
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
outline: none;
text-shadow: 0px 1px 0px #fff;
background-color: #fff;
background: -webkit-gradient(linear, left top, left bottombottom, from(#f9f9f9), to(#ffffff)) !important;
background: -webkit-linear-gradient(top, #f9f9f9, #ffffff) !important;  
background: -moz-linear-gradient(top,  #f9f9f9,  #ffffff) !important;
background: -ms-linear-gradient(top, #f9f9f9, #ffffff) !important;
background: -o-linear-gradient(top, #f9f9f9, #ffffff);

#loginform p label #user_login:focus, #loginform p label #user_pass:focus, #loginform p label #user_login:hover, #loginform p label #user_pass:hover { 
	color: #777 !important;
	background: #fff !important;

#loginform p label #user_login:-webkit-autofill, #loginform p label #user_pass:-webkit-autofill {
	background-color: #fff !important;

You’ll notice I have targeted two(2) individual page entities. These correspond to the username and password input fields, respectively. For the backgrounds and hover effects I needed to apply !important to most of the properties. This keyword in CSS performs a manual override which forces that property to become active regardless of the cascading hierarchy.

Generally it’s best if you paw over the raw WordPress HTML code to find what you want to change. To start, the header logo is actually using a fitted background image. The easiest way to work around this is similar to how I’ve mapped out below.

#login h1 { display: block; position: relative; height: 99px; margin-top: 10px; }
#login h1 a { background: #fff url('../images/custom-logo.png') no-repeat top center; display: block; position: absolute; right: 35px; }

The h1 element is set to a relative position so it can hold the internal link. The anchor is what links the user to your site (or whatever URL you setup earlier) and also contains this background image. Remember where your CSS file is located because you’ll have to pull the image relative to your local directory.

Wrapping Up

There is an entire page full of customizations you can take from here. I recently stumbled onto a popular album of custom WordPress login pages on Flickr for some dire inspiration. Or alternatively share your thoughts right here in the Speckyboy discussion area. We would enjoy checking out your designs!