The first time I went through the login process of WordPress, I told myself I would probably have to take some time to customize a bit that page. That was, well, four or five years ago.
I’m not telling that WordPress default login is useless, ulgy or badly crafted; I’m merely stating that it could get some improvement. If you’re working on a fully custom design like, like myself these days, you might find disturbing to have a login page totally ruining your graphical coherency. I have this nice dark blue and blood red design, my client wants to log himself in, boom, blank white page with orange links and blue buttons. Well, we’re gonna get rid of that.
Firsts statements
As usual, WordPress provides us with a built-in method to include a login form pretty much everywhere we want, called wp_login_form
. But don’t rush out there to learn the Codex page by heart, we won’t be using this method here, and here’s why.
There’s a lot of ways to customize WordPress’ login page, but almost every page example I found are just basic CSS modifications passed through actions in functions.php
. Problem is, this won’t allow us to change anything in the structure of the page, just its display. And that’s not what I want to do. I want to be able to choose where my elements will be placed, I want my inputs to have default values. There’s a fairly simple way to do this.
Fear the Core
We could just break out the chainsaw and hack through the wp-login.php
file, but leaving WordPres’ Core is a good habit to keep. So we’re just going to add a tiny page to the Core, which we’ll put in WordPress’ root folder: wp-log-in.php
. Now we need our visitors/clients to get to that page when they try to identify themselves; that we will do by adding the following code in our theme’s functions.php
file:
function alter_login_link( $url ) { if ( strpos( $url, 'logout' ) === false ) return preg_replace( "/(wp-login.php)/", "wp-log-in.php", $url ); else return $url; } add_filter( 'site_url', 'alter_login_link' );
Every time the site_url
method is called, except when logging out, « wp-login.php » is replaced by « wp-log-in.php », loading our custom page instead of the default WordPress page. We want to have a logout exception simply because wp-login.php
doesn’t only handle the login form but is part of the whole loggin/out process. Better leave that as it is!
Designing our own login page
Now this up to you and to what you want or don’t want to be in your page. I’ll give my own current experiment as a working base. Looks like this:
Changes made: get rid of the title link, « go back to blog » link, input labels, and added input default values. Added some jQuery to restore default values when the form is out of focus.
Page structure
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="fr-FR"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>WordPress › Log in</title> <meta name='robots' content='noindex,nofollow' /> </head> <body class="login"> <div id="nav"> <a href="/wp-login.php?action=register">Register</a> | <a href="/wp-login.php?action=lostpassword" title="Get a new password">Lost password?</a> </div> <div id="login"> <form name="loginform" id="loginform" action="/wp-login.php" method="post"> <p><input type="text" name="log" id="user_login" class="input" value="username" size="20" tabindex="10" /></p> <p><input type="password" name="pwd" id="user_pass" class="input" value="password" size="20" tabindex="20" /></p> <p class="submit"> <input type="submit" name="wp-submit" id="wp-submit" class="button-primary" value="Identify" tabindex="100" /> <input type="hidden" name="redirect_to" value="/wp-admin/" /> <input type="hidden" name="testcookie" value="1" /> </p> <p class="forgetmenot"> <label for="rememberme"><input name="rememberme" type="checkbox" id="rememberme" value="forever" tabindex="90" /> Remember me</label> </p> </form> <script type="text/javascript"> function wp_attempt_focus() { setTimeout( function() { try { d = document.getElementById('user_login'); d.focus(); d.select(); } catch(e) {} }, 200); } wp_attempt_focus(); if ( typeof wpOnload=='function' ) wpOnload(); </script> </div> <script type='text/javascript' src='/wp-includes/js/jquery/jquery.js?ver=1.7.2'></script> </body> </html>
Stylesheet
html, body { height : 100%; margin : 0; overflow : hidden; padding : 0; } body.login { background : url(/wp-content/themes/default/images/bg__blur.jpg) top center no-repeat #030712; background-size : 100% 100%; font-family : sans-serif; font-size : 12px; height : 100%; line-height : 1.4em; } #login { width : 320px; padding : 0; margin : 125px auto 0 auto; } body.login div#login h1 a { background-image : url(/wp-admin/images/wordpress-logo-rl.png); display : block; height : 125px; opacity : 0.75; overflow : hidden; padding-bottom : 0; text-indent : -9999px; width : 326px; } body.login div#login h1 a:hover { opacity : 1; } body.login form { background : transparent; border : 0; box-shadow : 0 0 0; padding : 0 25px; } body.login form p { margin : 0; } body.login form .input, body.login input[type="text"] { background : rgba(57, 72, 90, 0.15); border : 0; border-radius : 3px; box-shadow : 0 0 2px rgba(0, 0, 0, 0.5) inset, 0 1px 0 rgba(255, 255, 255, 0.15); color : #ccc; font-family : sans-serif; font-size : 12px; font-weight : normal; line-height : 1; margin : 6px 0; outline : 0; padding : 10px 16px; width : 245px; } body.login label { color : #ddd; } body.login label:hover { color : #fff; } body.login form .forgetmenot { float : none; margin : 5px 0 0 0; text-align : center; } body.login form .submit { margin-top : 15px; text-align : center; } body.login #nav { background : transparent; border-radius : 3px; color : rgba(255, 255, 255, 0.15); font-size : small; margin : 0; padding : 8px 16px; position : absolute; right : 5px; text-align : center; text-shadow : 0 0 0; top : 5px; } body.login #nav a { color : rgba(255, 255, 255, 0.15); text-shadow : 0 1px 0 rgba(0, 0, 0, 0.15); text-decoration : none; } body.login #nav a:hover { color : #fff; } body.login #nav a:active { color : #c30e0e; } body.login #wp-submit { background-image: linear-gradient(top, rgb(227,30,30) 50%, rgb(212,26,26) 50%); background-image: -o-linear-gradient(top, rgb(227,30,30) 50%, rgb(212,26,26) 50%); background-image: -moz-linear-gradient(top, rgb(227,30,30) 50%, rgb(212,26,26) 50%); background-image: -webkit-linear-gradient(top, rgb(227,30,30) 50%, rgb(212,26,26) 50%); background-image: -ms-linear-gradient(top, rgb(227,30,30) 50%, rgb(212,26,26) 50%); background-image: -webkit-gradient(linear,left bottom,left top,color-stop(0.5, rgb(212,26,26)),color-stop(0.5, rgb(227,30,30))); border : 0; border-radius : 3px; box-shadow : 0 0 2px rgba(0, 0, 0, 0.75), 0 1px 1px rgba(255, 255, 255, 0.5) inset, 0 -1px 1px rgba(255, 255, 255, 0.2) inset; color : #ddd; cursor : pointer; float : none; font-weight : bold; padding : 8px 36px; text-shadow : 0 1px 0 rgba(0, 0, 0, 0.35); } body.login #wp-submit:hover { box-shadow : 0 0 3px rgba(0, 0, 0, 0.85), 0 1px 1px rgba(255, 255, 255, 0.5) inset, 0 -1px 1px rgba(255, 255, 255, 0.2) inset; color : #fff; text-shadow : 0 1px 0 rgba(0, 0, 0, 0.75); } body.login #wp-submit:active { background : rgb(212, 26, 26); box-shadow : 0 0 5px rgba(0, 0, 0, 0.85) inset; text-shadow : 0 -1px 0 rgba(0, 0, 0, 0.75); }
jQuery
jQuery(window).load(function() { jQuery('#user_login, #user_pass').each(function(){ jQuery(this).prop('alt', jQuery(this).val()); }); jQuery('#user_login, #user_pass').focus(function() { if ( jQuery(this).val() == jQuery(this).prop('alt') ) jQuery(this).val(''); }); jQuery('#user_login, #user_pass').blur(function() { if ( jQuery(this).val() == '' ) jQuery(this).val(jQuery(this).prop('alt')); }); });
Stylesheet and jQuery code can be put in separate files or inside the page. This example should be fully W3C valid for HTML 5 and CSS 3 except the submit button due to the use of background-image
gradient that needs multi browser variants. I usually don’t use these variants for box-shadow
, border-radius
and classic CSS 3 properties that most browsers support anyway.
Have fun with your login pages!