As we all know there are some discussions about using placeholders instead of labels. We also know that only using placeholders can make a form pretty slick, especially on mobile devices. The downside is the usablity of the form, which decreases enormously. Beside that there are some differences in how browsers handling the placeholders. But what if your input has to be slick and…

Well, I think we can have best of both worlds. Yeah, it maybe sounds like a bit like a fairytale, but this one may be real. I will take a look at 2 possibilities which share the same base. Neither of those are possible with css only. This is because it’s not possible to work with pseudo elements on input fields. We’re going to use the focus-state for this.

The first one is an input only. The html only has an input with a placeholder. There will be no label and the input of the placeholder will be shown on focus. As you can see the input is wrapped by a paragraph. This will make it easier to position the span where we put out placeholder text. The HTML will look like this:

<form>
  <p>
    <input class="show-place" name="label" type="text" placeholder="there's no label" />
  </p>
</form> 

The next step is the javascript part. I’m using jQuery for this one because it’s used on most sites, but can easily be done with vanilla javascript. If the input has focus there will be an empty span placed after the input. This span will be inside the paragraph. The nextAll will search for the first sibbling of the type span. Now we can add one or more class for the styling and an id for removing the span on blur. The id will get the value of the name-attribute of the input. Now the placeholder content will be put into the span and we’re almost ready. The last step we have to make is to remove our span on blur. 

$( 'input' )
  .focus( function() {
    $( this )
      .after( '<span></span>' )
      .nextAll( 'span' )
      .addClass( 'placeholder' )
      .attr( 'id', $( this ).attr( 'name' ) )
      .html( $( this ).attr( 'placeholder' ) );
  } )
  .blur( function() {
    $( '#' + $( this ).attr( 'name' ) ).remove();
  } );

For the finishing touch we can style our span. The demo shows a live example of the above including the styling.

See the Pen Label vs Placeholder by Navelpluisje (@navelpluisje_nl) on CodePen.

The downside of showing your placeholder this way, is the fact there’s no label or title. A title can be added pretty easy. This will make it better accessible and readable by screenreaders, but gives you the nice browser-‘popup’ on mouseover.

The second solution has a label. This one has some pro’s compared to the previous solution. It uses a proper label, which makes it semantically better, no annoying browser-‘popup’ on mouseover and if you have to restyle the form in the future you already have the HTML and only have to edit some css. The base of this solution is equal to the first one. The crux is to get the text of the label by fetching this by the for-attribute and the label uses clip: rect( 0, 0, 0, 0 ) instead of display:none. Here’s the example:

See the Pen Label vs Placeholder 2 by Navelpluisje (@navelpluisje) on CodePen.

You can do some more styling and use some fadeIn and fadeOut animations for some fancyness. If you want to know more about formfields and labels you can read more about this on W3C. I hope this was a helpfull post.