If you haven’t noticed yet, we have to fill out forms all the dang time. Every time you post to your Face Space, you’re interacting with one or more of these things. The documentation for designing and working with them is pretty sparse. These inputs also have a literal gazillion gotchas varying among browser and device types. <sarcasm>Hooraaaaaaay.</sarcasm>
This is the first in a post series on form elements and some of their intricacies. Hopefully I can keep this series shorter than the latest Game of Thrones novel. Here we go!
The humble text input
Here’s the code for a text input.
<input name="input" type="text" placeholder="Placeholder text!" />
If in use, it would need a few more attributes and a label. Always use a label unless you hate happiness.
Here’s what a completely unstyled text input looks like across the latest version of Chrome, Firefox, Safari, Internet Explorer 11, Mobile Safari (iOS), and Android by default.
And here’s what text inputs look like in your browser:
Nifty. You’ll notice all of the various design patterns. Here are a few of the discrepancies:
- All the desktop browsers have varying focus styles.
- Of which, Firefox has the least noticeable.
- IE has a big `x` for clearing entered content.
- The padding varies almost across the board.
- Mobile Safari has no focus styles.
- Because mobile Safari forces the screen to zoom in when focused. Ugh.
- Mobile Safari has annoying round corners. (even more annoying on search inputs)
What text inputs do well
Single line text entry
Duh. This seems like a no-brainer, but it’s a bit more complex than it seems. Text inputs are handy in that they limit the content that can be dropped in. I’ll come back to this when I do a writeup on
contentEditable, but sanitizing the data entered (or pasted in) can be a pretty big pain. All inputs and textareas do this by default.
For example, selecting everything on a page (
control + a) and then pasting the clipboard into a text input or textarea results in plain text contents being dropped in. All styles, html elements, and scripts are stripped out (though are still held in your clipboard). Cool.
What text inputs do not so well
Can’t handle large amounts of text
This seems semi-obvious. Text inputs weren’t really designed for large amounts of text. When, I say this, I mean they can’t handle a paragraph or really long title of a post gracefully. They all involve scrolling sideways (a pain on every device).
Well, couldn’t you use a
textarea for that? Yes. You could, but it’s still pretty terrible for different reasons. I’ll cover these in the next post.
They don’t behave like other box-model elements
I would actually love if they could be persuaded to wrap instead of scroll. This, as far as I know, is impossible. There is no way to convince inputs to wrap the text dropped in and resize vertically (like an
h2 would with
contentEditable would behave).
Something like this from a little CodePen experiment I built would be ideal:
Styling can be quirky and unreliable
The properties that work on placeholder text can be particularly unreliable. There are also some really strange quirks here and there.
For example, I made a Pen called Text Input Love to show off some interesting and useful ways to show label, placeholder, and input content in interesting ways. I was informed that some of the demos didn’t work in IE so I delved into the issues at hand. IE has some really annoying quirks.
Highlights and fallback suggestion:
:empty doesn’t work on inputs
Remember that CodePen Experiment I mentioned earlier? It uses elements with the
contentEditable attribute. Demo:
It uses the
:empty selector cleverly to determine if the editable element has content in it. If it doesn’t, it uses pseudo elements to show the
aria-label. This method could be used to drastically change styles based on whether an input has a value entered or not. Unfortunately,
:empty doesn’t work on inputs.
The ideal text input experience.
Here’s what I want for markup. Nothing is new here. Always label your inputs and use the
for attribute. It’s awesome.
<input id="yep" type="text" placeholder="Michael" /> <label for="yep">Name</label>
Now for experience flow:
- I focus the input invoking sweet focus styling.
- The label moves out of the way, yet stays visible so I don’t have to defocus to figure out which field I’m writing in.
- The placeholder shows up giving me a good example of what my entry might look like.
- I start to type.
- The placeholder disappears. It’s no longer needed unless I clear my entry.
- If I type a particularly long entry, the text should wrap (or at least have that ability as an option via CSS)
- I unfocus the field (by going to the next one or tapping outside.
- The input allows the `:empty` selector and styles the now filled in field differently than it was when it was empty. (this currently has to be done with JS.)
- I can sleep at night.