From our sponsor: Meco is a distraction-free space for reading and discovering newsletters, separate from the inbox.
Hi guys! I’m back with another CSS tutorial! After button switches and drop-down lists, let’s create some forms. In particular, we will be creating login forms.
Nowadays, almost every web service, application, game etc. allows (or even requires) user subscription, which means they all need some kind of form for users to register and sign in.
With this in mind, I tried to create a few different login forms, some of which are inspired by design concepts on the web. The aim was to give some particularity to each of them.
A few things before starting:
- You won’t see any vendor prefixes in the CSS snippets, but you will, of course, find them in the files.
- The goal of the tutorial is to show the potential of CSS, particularly CSS3, that’s why the rendering could be altered on IE8-. If you plan to support these browsers, be sure to make fallbacks.
- I didn’t use any attribute on the
form
tag asaction
,method
since I’m focusing on the design. - I personally use the box-model where [width] = [element-width] + [padding] + [borders]. I activate it with the following snippet:
*, *:after, *:before { box-sizing: border-box; }
A word about user-friendliness
You need forms for many occasions where interaction between the user and your application or website is necessary: login, comments, contact, feedback, and more. If you mess with a form, you mess with your user.
With that in mind, there are a couple things you can do to make your forms better, more user-friendly. Let’s make a little round up together, shall we?
- Labels: Labels are important. I am not talking about the label tag, I am talking about an indication about the point of a field. Let’s make things clear: all fields are the same. It is because they have labels the user knows what to write in which field. Use labels, or icons, or whatever is needed to make the user understand what he has to do.
- Fields:: The nicer your inputs are, the more pleasant they are to look at, the happier your user will be. Make space around and in your inputs. Don’t make the field wedge its content. Inputs should be big enough to show their average whole content. Don’t make tiny little fields forcing users to navigate in them with arrow keys.
- Labels + fields: Make links between the inputs and their label. Use the
for
attribute on labels. Clicking on a textarea is easy, even on a mobile device. Clicking on a checkbox however can be tricky, especially when it comes to mobile navigation. Making the label clickable makes your user’s life easier. Use it. Make inputs large enough for the mobile view, where the label might not be clickable. - States: CSS allows the targeting of an element according to its current state: hovered, focused, active, default, etc. It’s important to show the user he’s hovering something clickable, or focusing something he can fill.
- Submit button: The submit button is the last step for your user to complete the form and interact with your application. It should be visible. Remember “call-to-action”. Don’t use the default style for a submit button, make something pretty! And don’t never ever use “Submit”. It’s indistinct. If it’s a login form, use “Sign in” or “Log in”. If it’s a comment form, use something like “Post comment”. Tell the user what action will be performed.
- HTML5 inputs and attributes: HTML5 provides a lot of useful new attributes and inputs in order to make forms nicer and easier to fill. Use those attributes and inputs when needed, with fallbacks of course. More about this on Wufoo.
Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.
Now we have covered the basics, let’s create some forms my friends!
Example 1
As I said earlier, I tried to make every form different from the others with its own particularity. This one relies on its submit button, kind of “out of the screen”, and rounded.
The Markup
<form class="form-1"> <p class="field"> <input type="text" name="login" placeholder="Username or email"> <i class="icon-user icon-large"></i> </p> <p class="field"> <input type="password" name="password" placeholder="Password"> <i class="icon-lock icon-large"></i> </p> <p class="submit"> <button type="submit" name="submit"><i class="icon-arrow-right icon-large"></i></button> </p> </form>
Okay, so this first example is pretty minimal, meaning we won’t use any labels. But, we of course need to tell our user what they have to write in those fields, so we use … icons. Those are the little <i/>
tags.
Note: as usual, I will not cover here how to use an icon font like FontAwesome. If you’d like to learn more about it, you can check out the examples on their website.
Basically, we have two containers wrapping an input and an icon. The submit button is in its own container, and we use a <button/>
instead of an <input/>
with an icon inside.
We will also employ placeholders to make things even more clear for supported browsers. More information on the browser support for the placeholder attribute can be found on CanIUse.com.
The CSS
We will start by giving some styles to the form element itself. The form is the main wrapper for our demos, so we give it a width and center it with the margin declaration.
.form-1 { /* Size & position */ width: 300px; margin: 60px auto 30px; padding: 10px; position: relative; /* For the submit button positioning */ /* Styles */ box-shadow: 0 0 1px rgba(0, 0, 0, 0.3), 0 3px 7px rgba(0, 0, 0, 0.3), inset 0 1px rgba(255,255,255,1), inset 0 -3px 2px rgba(0,0,0,0.25); border-radius: 5px; background: linear-gradient(#eeefef, #ffffff 10%); } .form-1 .field { position: relative; /* For the icon positioning */ }
Important: we set it to position relative in order to place the submit button absolutely. We do the same for the .field
containers to place the icons absolutely as well.
Speaking of icons, let’s deal with it now.
.form-1 .field i { /* Size and position */ left: 0px; top: 0px; position: absolute; height: 36px; width: 36px; /* Line */ border-right: 1px solid rgba(0, 0, 0, 0.1); box-shadow: 1px 0 0 rgba(255, 255, 255, 0.7); /* Styles */ color: #777777; text-align: center; line-height: 42px; transition: all 0.3s ease-out; pointer-events: none; }
We add a subtle line on the right side of the icon by setting a right border and a box shadow.
Since we are going to play with their color for the :hover
and :focus
states, we give them a smooth transition.
Adding “pointer-events: none” will allow to actually click on the area of the icon and focus the input that lies beneath (we are actually clicking on the input).
Now we need to give some styles to the inputs:
.form-1 input[type=text], .form-1 input[type=password] { font-family: 'Lato', Calibri, Arial, sans-serif; font-size: 13px; font-weight: 400; text-shadow: 0 1px 0 rgba(255,255,255,0.8); /* Size and position */ width: 100%; padding: 10px 18px 10px 45px; /* Styles */ border: none; /* Remove the default border */ box-shadow: inset 0 0 5px rgba(0,0,0,0.1), inset 0 3px 2px rgba(0,0,0,0.1); border-radius: 3px; background: #f9f9f9; color: #777; transition: color 0.3s ease-out; } .form-1 input[type=text] { margin-bottom: 10px; }
We make sure that neither the icon nor the input button overlap the text by giving the inputs a decent padding. And we set a bottom margin to the first input to prevent the second one to collapse.
Before going any further, let’s not forget to set some styles for both, the hover and the focus state.
.form-1 input[type=text]:hover ~ i, .form-1 input[type=password]:hover ~ i { color: #52cfeb; } .form-1 input[type=text]:focus ~ i, .form-1 input[type=password]:focus ~ i { color: #42A2BC; } .form-1 input[type=text]:focus, .form-1 input[type=password]:focus, .form-1 button[type=submit]:focus { outline: none; }
Two things here: we use the sibling selector (~
) to change the color of the icons when interacting with the inputs: light blue for hover, darker blue for focus. And we remove the outline for Chrome.
The last thing we have to style is the submit button. For some ugly overlapping reasons (what an awful property z-index is), I had to wrap it into a container to make things work. We could probably remove this container but it would require some annoying CSS trickery, and this is not the point.
.form-1 .submit { /* Size and position */ width: 65px; height: 65px; position: absolute; top: 17px; right: -25px; padding: 10px; z-index: 2; /* Styles */ background: #ffffff; border-radius: 50%; box-shadow: 0 0 2px rgba(0,0,0,0.1), 0 3px 2px rgba(0,0,0,0.1), inset 0 -3px 2px rgba(0,0,0,0.2); }
Things are fairly simple here: we create a circle element and put it on top of our form, slightly out of it on the right side. Box shadows accentuate this overlapping effect.
Problem: box shadows accentuate this overlapping effect, but they can also destroy it. Indeed, we can see the shadow on the frame of the form (the spacing between the fields and the right padding of the form).
Basically, we can hide those shadows with some kind of masks with the same background color of the form. This is a job for a pseudo-element!
.form-1 .submit:after { /* Size and position */ content: ""; width: 10px; height: 10px; position: absolute; top: -2px; left: 30px; /* Styles */ background: #ffffff; /* Other masks trick */ box-shadow: 0 62px white, -32px 31px white; }
There are three shadows to cover since our circular element is at the intersection of the spacing between the fields and the right padding of the form.
We place the first one on the top of the circular element. And with the box-shadow property, we can fake the two other masks. I think, this is something pretty hard to explain, so I suggest you open your developer tool and disable the box-shadow line on .submit:after
to see what’s going on.
Last but not least, our actual submit button:
.form-1 button { /* Size and position */ width: 100%; height: 100%; margin-top: -1px; /* Icon styles */ font-size: 1.4em; line-height: 1.75; color: white; /* Styles */ border: none; /* Remove the default border */ border-radius: inherit; background: linear-gradient(#52cfeb, #42A2BC); box-shadow: inset 0 1px 0 rgba(255,255,255,0.3), 0 1px 2px rgba(0,0,0,0.35), inset 0 3px 2px rgba(255,255,255,0.2), inset 0 -3px 2px rgba(0,0,0,0.1); cursor: pointer; }
Finally, the style for the hover, focus (e.g. when tabbing through) and active (pressed) state of the button:
.form-1 button:hover, .form-1 button[type=submit]:focus { background: #52cfeb; transition: all 0.3s ease-out; } .form-1 button:active { background: #42A2BC; box-shadow: inset 0 0 5px rgba(0,0,0,0.3), inset 0 3px 4px rgba(0,0,0,0.3); }
Fairly simple: a plain color for hover and focus. But wait, there’s more! Since we use a gradient on the default state, and gradients can’t be transitioned to, the browser first disables the gradient then applies the background color. This particular behavior causes a white flash when you hover over or focus the button, which, in my opinion, is pretty cool. It looks like a brief light reflection!
Example 2
This one is far less minimal and provides some new options: a “Sign in with Twitter” button and a “Show password” toggle. This will involve some JavaScript.
The Markup
<form class="form-2"> <h1><span class="log-in">Log in</span> or <span class="sign-up">sign up</span></h1> <p class="float"> <label for="login"><i class="icon-user"></i>Username</label> <input type="text" name="login" placeholder="Username or email"> </p> <p class="float"> <label for="password"><i class="icon-lock"></i>Password</label> <input type="password" name="password" placeholder="Password" class="showpassword"> </p> <p class="clearfix"> <a href="#" class="log-twitter">Log in with Twitter</a> <input type="submit" name="submit" value="Log in"> </p> </form>??
Here we will use a title. I went for a h1
but you could basically use whatever you want. We also use labels, connected to their inputs with a for
attribute.
The CSS
Let’s start by giving some general styles to the whole form:
.form-2 { /* Size and position */ width: 340px; margin: 60px auto 30px; padding: 15px; position: relative; /* Styles */ background: #fffaf6; border-radius: 4px; color: #7e7975; box-shadow: 0 2px 2px rgba(0,0,0,0.2), 0 1px 5px rgba(0,0,0,0.2), 0 0 0 12px rgba(255,255,255,0.4); }
We will create a semi-transparent border by applying some box shadows.
Now that we gave some basic styles to our form, let’s deal with the title. There are 3 different font styles in the title: bold, caps and dark grey; bold, caps and orange; light, low and light grey. So basic styles + 2 spans:
.form-2 h1 { font-size: 15px; font-weight: bold; color: #bdb5aa; padding-bottom: 8px; border-bottom: 1px solid #EBE6E2; text-shadow: 0 2px 0 rgba(255,255,255,0.8); box-shadow: 0 1px 0 rgba(255,255,255,0.8); } .form-2 h1 .log-in, .form-2 h1 .sign-up { display: inline-block; text-transform: uppercase; } .form-2 h1 .log-in { color: #6c6763; padding-right: 2px; } .form-2 h1 .sign-up { color: #ffb347; padding-left: 2px; }
Next, we use two paragraphs that will be placed side by side. Each one takes 50% of the available space in the form element, and thanks to the “border-box” box-sizing, the padding is calculated inside those 50%. That’s why we can make spacing between those two.
.form-2 .float { width: 50%; float: left; padding-top: 15px; border-top: 1px solid rgba(255,255,255,1); } .form-2 .float:first-of-type { padding-right: 5px; } .form-2 .float:last-of-type { padding-left: 5px; }
Our wrappers are set. Let’s style the elements inside them! So we have a label and an input. The icon is inside the label in this example:
.form-2 label { display: block; padding: 0 0 5px 2px; cursor: pointer; text-transform: uppercase; font-weight: 400; text-shadow: 0 1px 0 rgba(255,255,255,0.8); font-size: 11px; } .form-2 label i { margin-right: 5px; /* Gap between icon and text */ display: inline-block; width: 10px; }
Note: using cursor: pointer
on labels helps users understand they can click on it to focus the according input. This is an important detail.
.form-2 input[type=text], .form-2 input[type=password] { font-family: 'Lato', Calibri, Arial, sans-serif; font-size: 13px; font-weight: 400; display: block; width: 100%; padding: 5px; margin-bottom: 5px; border: 3px solid #ebe6e2; border-radius: 5px; transition: all 0.3s ease-out; }
Don’t forget the hover and the focus states:
.form-2 input[type=text]:hover, .form-2 input[type=password]:hover { border-color: #CCC; } .form-2 label:hover ~ input { border-color: #CCC; } .form-2 input[type=text]:focus, .form-2 input[type=password]:focus { border-color: #BBB; outline: none; /* Remove Chrome's outline */ }
Check out how we use the sibling selector (~
) to trigger the hover state on the inputs when we hover the labels. Isn’t that super cool?
Now, the submit buttons. But wait, since they are both floated in their container, we have to apply a clearfix to it. Remember how we do it?
.clearfix:after { content: ""; display: table; clear: both; } .form-2 input[type=submit], .form-2 .log-twitter { /* Size and position */ width: 49%; height: 38px; float: left; position: relative; /* Styles */ box-shadow: inset 0 1px rgba(255,255,255,0.3); border-radius: 3px; cursor: pointer; /* Font styles */ font-family: 'Lato', Calibri, Arial, sans-serif; font-size: 14px; line-height: 38px; /* Same as height */ text-align: center; font-weight: bold; } .form-2 input[type=submit] { margin-left: 1%; background: linear-gradient(#fbd568, #ffb347); border: 1px solid #f4ab4c; color: #996319; text-shadow: 0 1px rgba(255,255,255,0.3); } .form-2 .log-twitter { margin-right: 1%; background: linear-gradient(#34a5cf, #2a8ac4); border: 1px solid #2b8bc7; color: #ffffff; text-shadow: 0 -1px rgba(0,0,0,0.3); text-decoration: none; }
Both buttons are 49% wide, and they have a left/right margin to make a small gap between them. Now we give them a hover, and -it doesn’t harm just this once- an active state.
.form-2 input[type=submit]:hover, .form-2 .log-twitter:hover { box-shadow: inset 0 1px rgba(255,255,255,0.3), inset 0 20px 40px rgba(255,255,255,0.15); } .form-2 input[type=submit]:active, .form-2 .log-twitter:active{ top: 1px; }
Thanks to the position relative, we can apply top: 1px
to the buttons on the active state to make them look like they are being pushed down.
Important: for browsers that don’t support box-shadow (still exist, right?), we use a background-color change instead. The no-boxshadow
class is applied to the HTML with Modernizr in case a browser does not support box shadows. This is a nice example of how you can create a simple “fallback” for older browsers:
.no-boxshadow .form-2 input[type=submit]:hover { background: #ffb347; } .no-boxshadow .form-2 .log-twitter:hover { background: #2a8ac4; }
The JavaScript
Hey, didn’t we forgot our little “show password” thing? We’re getting into it! First, did you know we can’t change the type
attribute on an input? IMPOSSIBRU! To make a “show password” toggle, we have to delete the actual password input and create a text input instead.
I’m not very good at jQuery, so I found a little snippet by Aaron Saray to manage it. Let’s have a look:
$(function(){ $(".showpassword").each(function(index,input) { var $input = $(input); $("<p class='opt'/>").append( $("<input type='checkbox' class='showpasswordcheckbox' id='showPassword' />").click(function() { var change = $(this).is(":checked") ? "text" : "password"; var rep = $("<input placeholder='Password' type='" + change + "' />") .attr("id", $input.attr("id")) .attr("name", $input.attr("name")) .attr('class', $input.attr('class')) .val($input.val()) .insertBefore($input); $input.remove(); $input = rep; }) ).append($("<label for='showPassword'/>").text("Show password")).insertAfter($input.parent()); }); }); ?
So what does this script do exactly? A few things:
- It spots every input with the
.showpassword
class. - It creates a new container (
.opt
). - Inside this container, it creates a checkbox with a label linked to it.
- It inserts this container after the
.showpassword
input’s parent. - When the checkbox in clicked, it removes the
.showpassword
input and creates another one instead with the according type attribute.
Let’s not forget to give some styles to our checkbox and new label.
.form-2 p:last-of-type { clear: both; } .form-2 .opt { text-align: right; margin-right: 3px; } .form-2 label[for=showPassword] { display: inline-block; margin-bottom: 10px; font-size: 11px; font-weight: 400; text-transform: capitalize; } .form-2 input[type=checkbox] { vertical-align: middle; margin: -1px 5px 0 1px; }
Last but not least, we add a few lines of jQuery to change the icon when the checkbox is checked! Fairly simple but quite effective!
$('#showPassword').click(function(){ if($("#showPassword").is(":checked")) { $('.icon-lock').addClass('icon-unlock'); $('.icon-unlock').removeClass('icon-lock'); } else { $('.icon-unlock').addClass('icon-lock'); $('.icon-lock').removeClass('icon-unlock'); } });
Example 3
This one is inspired by an old work from Virgil Pana on Dribbble. Sadly, it looks like he removed it from Dribbble so I can’t show you the original concept. Anyway, you’ve probably understood the point that it’s for showing you how to create this awesome light effect with pure CSS!
The Markup
<form class="form-3"> <p class="clearfix"> <label for="login">Username</label> <input type="text" name="login" id="login" placeholder="Username"> </p> <p class="clearfix"> <label for="password">Password</label> <input type="password" name="password" id="password" placeholder="Password"> </p> <p class="clearfix"> <input type="checkbox" name="remember" id="remember"> <label for="remember">Remember me</label> </p> <p class="clearfix"> <input type="submit" name="submit" value="Sign in"> </p> </form>?
Look how we introduce a new feature in this form: the “Remember me” option. This is something very specific to login forms since it allows the application to remember that you’re authenticated.
The CSS
.form-3 { font-family: 'Ubuntu', 'Lato', sans-serif; font-weight: 400; /* Size and position */ width: 300px; position: relative; margin: 60px auto 30px; padding: 10px; overflow: hidden; /* Styles */ background: #111; border-radius: 0.4em; border: 1px solid #191919; box-shadow: inset 0 0 2px 1px rgba(255,255,255,0.08), 0 16px 10px -8px rgba(0, 0, 0, 0.6); }
The shadow under the login form will look special because of the negative spread radius. We can actually compress the shadow like that.
Let’s dig a little bit into the structure of our form, shall we? For the fields, we use two p
tags wrapping a label and an input, both floated. This means we have to clearfix our containers (see previous examples).
Let’s add some style to the labels and text/password inputs plus their hovered and focused states, of course:
.form-3 label { /* Size and position */ width: 50%; float: left; padding-top: 9px; /* Styles */ color: #ddd; font-size: 12px; text-transform: uppercase; letter-spacing: 1px; text-shadow: 0 1px 0 #000; text-indent: 10px; font-weight: 700; cursor: pointer; } .form-3 input[type=text], .form-3 input[type=password] { /* Size and position */ width: 50%; float: left; padding: 8px 5px; margin-bottom: 10px; font-size: 12px; /* Styles */ background: linear-gradient(#1f2124, #27292c); border: 1px solid #000; box-shadow: 0 1px 0 rgba(255,255,255,0.1); border-radius: 3px; /* Font styles */ font-family: 'Ubuntu', 'Lato', sans-serif; color: #fff; } .form-3 input[type=text]:hover, .form-3 input[type=password]:hover, .form-3 label:hover ~ input[type=text], .form-3 label:hover ~ input[type=password] { background: #27292c; } .form-3 input[type=text]:focus, .form-3 input[type=password]:focus { box-shadow: inset 0 0 2px #000; background: #494d54; border-color: #51cbee; outline: none; /* Remove Chrome outline */ }
Now that we have some beautiful inputs, we have to create our little checkbox for the “Remember me” feature, and the submit button. Those two things are floated side by side:
.form-3 p:nth-child(3), .form-3 p:nth-child(4) { float: left; width: 50%; }
We use advanced CSS selectors to target them, but you could use a class if you want (or if you have to, for legacy browser coverage). Anyway, let’s start with the checkbox and its label:
.form-3 label[for=remember] { width: auto; float: none; display: inline-block; text-transform: capitalize; font-size: 11px; font-weight: 400; letter-spacing: 0px; text-indent: 2px; } .form-3 input[type=checkbox] { margin-left: 10px; vertical-align: middle; }
Since this label is quite different from the others, we have to tweak a few things to make it right: so it’s pretty much removing previously set styles. As for the checkbox, we add a little margin to its right to prevent the label to stick to it, and the vertical align fix some weird, well, vertical align (!).
Last, our submit button with its hovered state:
.form-3 input[type=submit] { /* Width and position */ width: 100%; padding: 8px 5px; /* Styles */ border: 1px solid #0273dd; /* Fallback */ border: 1px solid rgba(0,0,0,0.4); box-shadow: inset 0 1px 0 rgba(255,255,255,0.3), inset 0 10px 10px rgba(255,255,255,0.1); border-radius: 3px; background: #38a6f0; cursor:pointer; /* Font styles */ font-family: 'Ubuntu', 'Lato', sans-serif; color: white; font-weight: 700; font-size: 15px; text-shadow: 0 -1px 0 rgba(0,0,0,0.8); } .form-3 input[type=submit]:hover { box-shadow: inset 0 1px 0 rgba(255,255,255,0.6); } .form-3 input[type=submit]:active { background: #287db5; box-shadow: inset 0 0 3px rgba(0,0,0,0.6); border-color: #000; /* Fallback */ border-color: rgba(0,0,0,0.9); } .no-boxshadow .form-3 input[type=submit]:hover { background: #2a92d8; }
But where the hell is our promised light effect? Okay guys, let’s go for it. To achieve this, we need three elements:
- One for the gradient line from the top of the form
- One for the small flash on the previous line
- One for the large reflection on the right part the form
We will start with the first two elements with pseudo-elements on the form
tag.
/* Gradient line */ .form-3:after { /* Size and position */ content: ""; height: 1px; width: 33%; position: absolute; left: 20%; top: 0; /* Styles */ background: linear-gradient(left, transparent, #444, #b6b6b8, #444, transparent); } /* Small flash */ .form-3:before { /* Size and position */ content: ""; width: 8px; height: 5px; position: absolute; left: 34%; top: -7px; /* Styles */ border-radius: 50%; box-shadow: 0 0 6px 4px #fff; }
Finally, our light reflection. But wait, we don’t have enough pseudo-elements! Don’t worry, we will use our first paragraph for it.
.form-3 p:nth-child(1):before{ /* Size and position */ content: ""; width: 250px; height: 100px; position: absolute; top: 0; left: 45px; /* Styles */ transform: rotate(75deg); background: linear-gradient(50deg, rgba(255,255,255,0.15), rgba(0,0,0,0)); pointer-events: none; }
Important: you have to disable click events on it with the pointer-events property
. If you don’t, you won’t be able to click on inputs anymore since there will be a layer on top of them. We will have to remove the reflection for browsers that don’t support the pointer-events (we’ve added this none-core detect to our Modernizr build):
.no-pointerevents .form-3 p:nth-child(1):before { display: none; }
Example 4
This one’s particularity is the absence of labels. Or icons. Yes, I know, I said earlier we absolutely need to have something to tell users what to do. And we have! We have placeholders. And for browsers that don’t support them, we will make labels visible!
The Markup
<form class="form-4"> <h1>Login or Register</h1> <p> <label for="login">Username or email</label> <input type="text" name="login" placeholder="Username or email" required> </p> <p> <label for="password">Password</label> <input type="password" name='password' placeholder="Password" required> </p> <p> <input type="submit" name="submit" value="Continue"> </p> </form>?
Let me introduce the required
attribute to you. When supported, it allows the browser to check if the field is empty or not, and submit the form accordingly.
Important: you should always build a server-side verification for submitting your forms. With a web inspector, it is very easy to remove an attribute, and JavaScript can be disabled as well, so don’t rely on client-side verification only.
The CSS
As always, we start with the form and the title since it’s fairly simple.
.form-4 { /* Size and position */ width: 300px; margin: 60px auto 30px; padding: 10px; position: relative; /* Font styles */ font-family: 'Raleway', 'Lato', Arial, sans-serif; color: white; text-shadow: 0 2px 1px rgba(0,0,0,0.3); } .form-4 h1 { font-size: 22px; padding-bottom: 20px; }
Let’s move on to the inputs:
.form-4 input[type=text], .form-4 input[type=password] { /* Size and position */ width: 100%; padding: 8px 4px 8px 10px; margin-bottom: 15px; /* Styles */ border: 1px solid #4e3043; /* Fallback */ border: 1px solid rgba(78,48,67, 0.8); background: rgba(0,0,0,0.15); border-radius: 2px; box-shadow: 0 1px 0 rgba(255,255,255,0.2), inset 0 1px 1px rgba(0,0,0,0.1); -webkit-transition: all 0.3s ease-out; -moz-transition: all 0.3s ease-out; -ms-transition: all 0.3s ease-out; -o-transition: all 0.3s ease-out; transition: all 0.3s ease-out; /* Font styles */ font-family: 'Raleway', 'Lato', Arial, sans-serif; color: #fff; font-size: 13px; }
Let’s change the style for the placeholders (where it’s possible):
.form-4 input::-webkit-input-placeholder { color: rgba(37,21,26,0.5); text-shadow: 0 1px 0 rgba(255,255,255,0.15); } .form-4 input:-moz-placeholder { color: rgba(37,21,26,0.5); text-shadow: 0 1px 0 rgba(255,255,255,0.15); } .form-4 input:-ms-input-placeholder { color: rgba(37,21,26,0.5); text-shadow: 0 1px 0 rgba(255,255,255,0.15); }
Next, let’s add the hover and focus styles:
.form-4 input[type=text]:hover, .form-4 input[type=password]:hover { border-color: #333; } .form-4 input[type=text]:focus, .form-4 input[type=password]:focus, .form-4 input[type=submit]:focus { box-shadow: 0 1px 0 rgba(255,255,255,0.2), inset 0 1px 1px rgba(0,0,0,0.1), 0 0 0 3px rgba(255,255,255,0.15); outline: none; } /* Fallback */ .no-boxshadow .form-4 input[type=text]:focus, .no-boxshadow .form-4 input[type=password]:focus { outline: 1px solid white; }
And the submit button:
.form-4 input[type=submit] { /* Size and position */ width: 100%; padding: 8px 5px; /* Styles */ background: linear-gradient(rgba(99,64,86,0.5), rgba(76,49,65,0.7)); border-radius: 5px; border: 1px solid #4e3043; box-shadow: inset 0 1px rgba(255,255,255,0.4), 0 2px 1px rgba(0,0,0,0.1); cursor: pointer; transition: all 0.3s ease-out; /* Font styles */ color: white; text-shadow: 0 1px 0 rgba(0,0,0,0.3); font-size: 16px; font-weight: bold; font-family: 'Raleway', 'Lato', Arial, sans-serif; } .form-4 input[type=submit]:hover { box-shadow: inset 0 1px rgba(255,255,255,0.2), inset 0 20px 30px rgba(99,64,86,0.5); } /* Fallback */ .no-boxshadow .form-4 input[type=submit]:hover { background: #594642; }
And now, let’s deal with our no-placeholder fallback. Placeholder is not a vital feature I know, unless you exclusively rely on it to tell user what are the inputs for. In this case, you have to provide a fallback.
.form-4 label { display: none; padding: 0 0 5px 2px; cursor: pointer; } .form-4 label:hover ~ input { border-color: #333; } .no-placeholder .form-4 label { display: block; }
This is very simple: if placeholders are not supported, labels turn visible. End of story.
Example 5
This last example is a glass-like, minimal form with a subtle twist. We won’t use labels, and everything looks very compact. We’ll rotate the text of the submit button and make an arrow appear on hover.
The Markup
<form class="form-5 clearfix"> <p> <input type="text" id="login" name="login" placeholder="Username"> <input type="password" name="password" id="password" placeholder="Password"> </p> <button type="submit" name="submit"> <i class="icon-arrow-right"></i> <span>Sign in</span> </button> </form>????
A minimalistic markup for a minimalistic form. 😉
The CSS
.form-5 { /* Size and position */ width: 300px; margin: 60px auto 30px; position: relative; /* Styles */ border-radius: 5px; box-shadow: 0 0 5px rgba(0,0,0,0.1), 0 3px 2px rgba(0,0,0,0.1); }
Let’s style the paragraphs and the inputs:
.form-5 p { width: 70%; float: left; border-radius: 5px 0 0 5px; border: 1px solid #fff; border-right: none; } .form-5 input[type=text], .form-5 input[type=password] { /* Size and position */ width: 100%; height: 50px; padding: 0 10px; /* Styles */ border: none; /* Remove the default border */ background: white; /* Fallback */ background: rgba(255,255,255,0.2); box-shadow: inset 0 0 10px rgba(255,255,255,0.5); /* Font styles */ font-family: 'Montserrat', sans-serif; text-indent: 10px; color: #ee4c8d; text-shadow: 0 1px 2px rgba(0,0,0,0.3); font-size: 20px; } .form-5 input[type=text] { border-bottom: 1px solid #fff; /* Fallback */ border-bottom: 1px solid rgba(255,255,255,0.7); border-radius: 5px 0 0 0; } .form-5 input[type=password] { border-top: 1px solid #CCC; /* Fallback */ border-top: 1px solid rgba(0,0,0,0.1); border-radius: 0 0 0 5px; }
Let’s apply some hover styles and style the placeholders:
.form-5 input[type=text]:hover, .form-5 input[type=password]:hover, .form-5 input[type=text]:focus, .form-5 input[type=password]:focus { background: #f7def7; /* Fallback */ background: rgba(255,255,255,0.4); outline: none; } .form-5 input::-webkit-input-placeholder { color: #fff; text-shadow: 0 -1px 1px rgba(0,0,0,0.4); font-family: 'Handlee', cursive; } .form-5 input:-moz-placeholder { color: #fff; text-shadow: 0 -1px 1px rgba(0,0,0,0.4); font-family: 'Handlee', cursive; } .form-5 input:-ms-input-placeholder { color: #fff; text-shadow: 0 -1px 1px rgba(0,0,0,0.4); font-family: 'Handlee', cursive; }
And now, the submit button. The little i will contain an arrow icon but we will not make it visible for now, just on hover. Note that we use a span inside the button to turn the text without turning the button.
.form-5 button { /* Size and position */ width: 30%; height: 102px; float: left; position: relative; overflow: hidden; /* Styles */ background: url(../images/noise.png), radial-gradient(ellipse at center, #ee4c8d 0%,#b53467 100%); border-radius: 0 5px 5px 0; box-shadow: inset 0 0 4px rgba(255, 255, 255, 0.7), inset 0 0 0 1px rgba(0, 0, 0, 0.2); border: none; border-left: 1px solid silver; cursor: pointer; line-height: 102px; /* Same as height */ } .form-5 button i { position: absolute; width: 100%; height: 100%; top: 0; left: -20px; font-size: 64px; line-height: 109px; color: #8d1645; opacity: 0; text-shadow: 0 1px 0 rgba(255,255,255,0.4); transition: all 0.2s ease-out; } .form-5 button span { display: block; /* Font styles */ color: #8d1645; font-family: 'Montserrat', Arial, sans-serif; font-size: 20px; text-shadow: 0 1px 0 rgba(255,255,255,0.4); transform: rotate(-90deg); transition: all 0.2s linear; }
In case the browser doesn’t support the transform property, the text is simply not rotated. No big deal.
We’ve added a subtle texture to the button by applying two backgrounds: the texture and the radial gradient that lies beneath.
Now, let’s add the hover, focus and active state styles. On hover, we will make the span move to the left and fade out and the arrow will appear:
.form-5 button:focus { outline: none; } .form-5 button:hover span, .form-5 button:focus span { opacity: 0; transform: rotate(-90deg) translateY(-20px); } .form-5 button:hover i, .form-5 button:focus i { opacity: 0.5; left: 0; transition-delay: 0.2s; } /* Click on button */ .form-5 button:active span, .form-5 button:active i { transition: none; } .form-5 button:active span { opacity: 0; } .form-5 button:active i { opacity: 0.5; left: 0; color: #fff; }
When we click on the button, we don’t want any transitions so that it doesn’t look to messy.
The JavaScript
Let’s use a little bit of JavaScript here for adding HTML5 placeholder behavior to the browsers that don’t support it. We are going to use a jQuery plugin by Mathias Bynens. Check out the GitHub repo for details.
After including jQuery and the script, we simply call it like this:
$(function(){ $('input, textarea').placeholder(); });
And this will add placeholder behavior to older browsers.
Final words
Now that you have read this, the only thing you have to do is to create your own forms. This is something which can be very creative, so please let yourself go and show us what you can do!
Dribbble is a wonderful source of inspiration for such things, so I’d suggest you have a little ride over there to see what’s going on. You may find beautiful forms like these:
- Login Register Widget by Matt Anderson
- Login form by Ashish Thakkar
- Login form by Janko Jovanovic
- Login form from the Impressionist UI by DesignModo
As further readings, I recommend:
- A round-up about the current state of HTML5 forms by Wufoo
- A screencast from Chris Coyier about advanced form styling and functionality
- An article by Luke Wroblewski on Smashing Magazine about forms on mobile devices
- Another article by Luke Wroblewski on Smashing Magazine about new approaches to designing login forms
Thanks a lot for reading this tutorial, and as always if you have any question, just ask, or if you have related work to show, just do!
Right Post came at the right time, I was just about to search for the same Login Forms. Now need to go anywhere else. Thanks A lot ! 🙂
Nice work! Thank you for sharing it!
Um ótimo trabalho e de excelente bom gosto! Venho acompanhando a muito tempo os tutoriais e as dicas, é de muito valor este seu trabalho, continue sempre … vlws
Very nice login forms , thank you , u inspire me a lot
Nice!
perfect composition for our new website.. Well done..
I am feeling jealous about you guys,
How do you get creativity to do all these things.
Can you share the secret behind your creativity.
I am feeling like a old school kid who only knows to finish his homework no matter of handwriting.
Awesome, outstanding, I love it. Congratz.
Slight error in Example 4, in the Markup field.
You start with and end with . Should end with … 🙂 Great article though, good job bro 🙂
Fixed! Thanks a lot. 🙂
you start with
h1 and end with h3. Should end with h1.
Great examples of creative login forms, I’ll use one of the designs this week on a project with some tweaks here and there. Keep the good stuff flowing!
Thanks for fresh ideas and inspiration!
Really awesome workout, you guys rocks…..
It just gets better..well i have been coming here for these stuffs … best ever blog 🙂
Great tutorial! example #1 is really cool
awesome………………………:D
Love these, but they’re missing common things like “Forgot your password?” links that might throw off some people trying to develop something a bit more functional.
Very nice. All login screens are nice. Thank for sharing.
WOW…
Amazing!
very cool, very usefull, came at the right time,
thanks for sharing such beautifull stuff !
Ah…. cool.
Great stuff! Thanks a lot, I’ll use it soon.
Really nice stuff, it was very inspiring for me.
so cool ! css3 wonderful
Super tutorial. I wonder why you use P as “line separator”. Should it be a div or li (in my opinion LI is not totally correct).
because is more semantic then
Its so exiciting and informative.
It inspire us to design like this and to think in different ways like you.
Like it.
Thanks for inspiring us..
wow! this is cool stuff. Thanks! 😀
Beautiful, thanks!
Hi, I would like to use your first login form but I would prefer the right arrow instead of this strange sign in the demo 1… anyone know how to change it ?
In form-2, you are using .form-2 .float:last-of-type, which isn’t actually being applied
After some research it seems type is the element type first, then matches the class and there are 3 p elements
wow.. really cool design.. love it. (y) (y). thanks 🙂
Well, the form 3 doesn’t work with IE 10, for some odd reason. Do you know why?
Any help? Any ideas why Form 3 doesn’t work under IE 10?
I am using the example 1 in a class project and was wondering how to scale it down to view for mobile devices. i.e. tablets and phones. Would someone be able to help me with the CSS? It would be much appreciated!! Thank you in advance!!
hi i can use this in wordpress?
i like form in demo 1 and want to use. but that piece of code
*,
*:after,
*:before {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
padding: 0;
margin: 0;
}
crash all aother borders of site.How can it be use localy
Thank you so much .3
its awesome………………i waant more menu styles..can u plzz help me…
PureFull , Stuff .
it’s great!
great taste !!! yum yum