Wednesday, March 25, 2015

Labels As Placeholders

A while ago I wrote an entry about using the placeholder attribute as a label, but as with all things, I was certain I could improve it - and I was not wrong.

The original post suggested we use the placeholder attribute and hide the label; however, I am now thinking that may not be the best user experience, because when the user starts entering something into the field, the label disappears. That insight made me re-think my approach to see just what I could do differently.

What I want is a clean form that shows the user the label inside the input so there's no question which input should get which data - thus reducing cognitive load - and still maintain that label after the user has entered data in case they want to review their information before submitting it, because in the end, we want to make all of the experiences the best we can for our customers.

A simple improvement is not only possible, but in fact, with CSS3 and HTML5, very easy. The only alteration in our standard practice is the addition of a new HTML5 attribute - otherwise, use the same HTML tags you've been using forever to mark up the form - input and label primarily. Just as in the previous blog post, put the label after the input it's describing. By doing this, if there are problems with rendering you're less likely to get something awful. Be sure to use the id and for attributes to link the tags...and I wrap both the input and label in a div I call "field" so that I can manipulate them a little easier - placing them in a grid, for example. Now for the new part - add the "required" attribute to the input tags - that's it.

Once you have your form built, it's time to start on the stylesheet. For this, there isn't much that's new either. You'll want to use the sibling selector to select labels that follow an input (i.e., a '+' - input + label for example) and set a default style that will format the label when it displays below the input - this will basically include everything except the vertical positioning. Also keep in mind that when you alter the vertical positioning, you want to allow the label to display on top of the input without disrupting the input - I'm using a transparent background so the user easily sees the input. In order to manipulate the label effectively, set the display style to block and the position to relative - I also add a transition for the top margin to smooth the movement of the label text so we're not distracting the user my quick movements that will always draw their eye. Once you've built the style for how it will look when the field is populated, you're ready for the "new" part - adding code that can be used with a CSS selector and pairing it with the sibling select to shift the label upward. Of course to do this without using JavaScript, we need a way to test to see if an input element is empty using CSS - or in this case CSS3 specifically. To do that, we'll use the required pseudoclass (CSS line 36-38) and the valid pseudoclass (CSS line 39-41) and the required HTML attribute (HTML lines 5 and 9). The LABEL element has a negative value for margin-top by default and when the input is valid the top margin is set to 0, moving the label below the field.

There are a couple of things you'll want to keep in mind. First, this isn't going to work very well if you have a mix of required and optional inputs, because there isn't an easy way to pass the required validation on form submit with a false positive. Second, you may have trouble with forms that are auto-filled. Luckily there's an pseudoclass that will handle this second issue - -webkit-autofill - so feel free to add input:-webkit-autofill + label to the style rule for default label handling.

That's it. Simple little improvements that should work in nearly all new browsers.

To see how this works with the label that displays on top of the input and moves out of the way but remains visible while you enter information, copy the sample code below into your editor, save it, and open it in a browser. While the code is not meant to be a complete solution (you'll have to adjust it to meet your needs a little), it will get you started.


CSS

form.login {     background:linear-gradient(#fff, #8df, #fff);     font-family:Verdana;     margin:auto;     overflow:auto;     text-align:center;     width:40%;   } form.login fieldset {     border-radius:0.5em;     box-shadow:0.7em 0.7em 0.5em rgba(128, 128, 128, 0.5);     display:inline-block;     margin:2em;     overflow:auto;     text-align:left;   } form.login div.field {     display:block;     height:2.75em;     overflow:visible;     padding:0.5em;   } form.login div.field input {     border:1px solid black;     border-radius:0.5em;     display:inline-block;     margin-left:-0.3em;     padding:0.1em 0.3em;   } form.login div.field input + label {     background:transparent;     display:block;     position:relative;     transition:margin-top 1s;   } form.login div.field input:required + label {     margin-top:-1.6em;   } form.login div.field input:valid + label{     margin-top:0;   } form.login input[type="submit"] {     border:1px solid black;     border-radius:0.7em;     float:right;     padding:0.2em 0.5em;   }



HTML

<form class="login">   <fieldset>     <legend>Login</legend>     <div class="field">       <input id="username" name="username" type="text" required="true" />       <label for="username">Email</label>     </div>     <div class="field">       <input id="password" name="password" type="password" required="true" />       <label for="password">Password</label>     </div>     <input name="login" type="submit" value="Login" />   </fieldset> </form>


EXAMPLE


Login


Happy coding.

No comments:

Post a Comment