Just plain CSS

est. 2015

Text input with CSS transition

I used CSS transitions, a little tiny hack and a bit of CSS to make the search form of this site – here’s how I did it …

So you may (or may not) have noted the behavior of the search form at the top of the site transitioning from placeholder text to input and back and you may have (incorrectly) assumed that I used the placeholder/value and some JavaScript to achieve this …


The setup for this particular technique requires only an <input type="text"/> and a <label>. The text input needs to be required for the CSS to work – I’ll explain why in a second …

<form id="searchform" method="get" action="http://justcss.co.za">
    <input type="text" name="s" id="s" size="15" required="required" />
    <label for="s">Search justCSS</label>
    <input type="submit" value="&raquo;" id="go">

First we start with the form basics – we need the form to be positioned relative (I leave the rest of the values, but most are important for styling only, and not for the trick to work) …

  background: #fff;
  font: inherit;
  font-size: 1.5em;
  height: 4em;
  padding: 0;
  position: relative;/* This is the important bit here */
  vertical-align: middle;

Then onto the input itself – we change the border-color as part of the overall transition, but it is not …

#searchform #s{
  border: 1em solid #eee;
  border-radius: 0;
  box-shadow: none;
  color: #999;
  display: inline-block;
  font: inherit;
  font-size: 1em;
  height: 100%;
  outline: none;
  padding: 0 1em;
  transition: border-color 500ms ease;
  -webkit-transition: border-color 500ms ease;
  vertical-align: middle;
  width: 100%;
  -webkit-appearance: none;
#searchform #s:focus{
  border-color: rgba(85, 113, 128, 0.3);
  /* Change the border color when the text input has focus */

Next we want to tackle the label; the label serves as our placeholder here and is absolutely positioned over the text input …

  color: #999;
  height: 2em;
  left: 2em;
  line-height: 2em;
  opacity: 1;
  filter: alpha(opacity=100);
  pointer-events: none;
  position: absolute;
  top: 1em;
  transition: opacity 300ms linear;
  -webkit-transition: opacity 300ms linear;
  vertical-align: middle;

Finally, we use the :focus state of the input and a direct adjacent sibling selector to hide the label when the focus is on the text input, but what happens when we click away? Obviously, the label re-appears … this is why we make the text input required – if we didn’t enter text, the label re-appears as it should; if we entered text, the input is :valid and we create another selector to hide the label when the text input is valid …

#searchform #s:focus + label,
#searchform #s:valid + label{
  opacity: 0;
  filter: alpha(opacity=0);

The nett effect (also the tl;dr – just gimme code) …

See the Pen Text input with CSS transition by Jacques Mostert (@jayx) on CodePen.14523

Simple stuff, looks tight and tidy and works in anything except IE9 and lower (no :valid and/or CSS transitions support) … off you go then; copy|paste at will.

A side note:
This is a nice trick for something like a search form, where it is safe to use the required= attribute (or any other field that is genuinely required) – it would be nuts to go and use this for large forms and/or as a replacement for placeholder text … use wisely.

Leave a Reply

Your email address will not be published. Required fields are marked *