Note from the publisher: You have managed to find some of our old content and it may be outdated and/or incorrect. Try searching in our docs for current information.

A while ago I designed an interactive placeholder thing for our forms and wrote it entirely in CSS. I made it assuming no one would ever notice, so you can imagine my surprise when I saw that it got featured on LittleBigDetails, one of my favorite blogs!

To show my gratitude I thought I would share how I designed that placeholder and how it manages to adapt to user input. And by that I mean, our investors the team liked the attention so much that I was forced motivated to follow up with a blogpost and milk share it for all it’s worth.

Live Demo

See the Pen Adaptive Placeholder by Danny King (@dannykingme) on CodePen.

I’m throwing the demo at you first so 1) you have something to reference, and 2) if you’re lazy you can get right to the good stuff. Okay, here we go!

Forms Follow Function

Before I came up with the interactive placeholder, I was just using a normal one. I liked the simplicity of using a placeholder as a label. It actually made a pretty crappy interaction for the user though. A user would type and the text disappeared.

Entire teams use Circle – the person who enters a value first isn’t always the same person who sees it later. To solve this problem I tried making the placeholder persist through the typing.

This worked well and made handling pre-filled data that much easier. When the <input> gets pre-filled, it behaves as it would if the user entered it themselves. Now teammates who view this in the future will know what this input is meant for right away.

Fun With Pseudo-Selectors

The first big problem I ran into was figuring out how to select the normal placeholder I was using. Initially, I tried selecting the actual placeholder element itself from the Shadow-DOM This worked okay, but only in Chrome, which wasn’t good enough.

input::-webkit-input-placeholder { ... }

After that didn’t work I had a cool idea to handle it with a “:before” pseudo-element but apparently that’s not possible. So instead I just selected an adjacent <label> and styled it to look like a normal placeholder.

input + label { ... }

Then to move the placeholder out of the way at the right time, I used a “required” attribute. That combined with a “:valid” pseudo-selector let me know whether the <label> was holding text or not.

input:valid { ... }

A Recent Addition

I’ve added styles for the “alt” attribute so you can show one string initially and a completely different string once text is entered. We use this to give temporary instructions to users, as seen on our Enterprise page.

Markup Setup

To get this thing up and running in HTML just create an <input> and give it a “required” attribute. Follow that with a <label> and give it a “placeholder” attribute – optionally, give it an “alt” attribute.

<input type="text" required></input> <label alt="BEFORE" placeholder="AFTER"></label>

The LESS Mixin

For reusability purposes I took everything and threw it in a LESS mixin so I wouldn’t have to worry about it anymore. Now I can choose when and where to show these bad boys with just a couple of line changes.

See the Pen Adaptive Placeholder by Danny King (@dannykingme) on CodePen.

Ta-Da!

That’s it! The whole thing is fairly simple and it seems to be creating a memorable little interaction for our users. If you end up using this concept yourself, be sure to let us know! We’d love to see your implementation!

By the way, the team and I are always looking for awesome designers to help us with fun stuff like this. Feel free to send me a message directly at danny@circleci.com.

P.S.

This isn’t the first design like this to come along and we doubt it’ll be the last. We do think ours is pretty neat though. Here’s a few others we found after a bit of research: http://stackoverflow.com/questions/1171575/ http://www.joelsroofingandgutter.com/contact.php#email https://medium.com/web-design-and-development/101aa28d0ab2 http://dribbble.com/shots/1254439–GIF-Float-Label-Form-Interaction https://news.ycombinator.com/item?id=6685833