Anyway to have a label respond to :focus CSS

You can't actually give focus to a label. It's not a focusable form element. Besides, even if you could do that, then whatever previously had focus (that means your input) would lose it to the label anyway.

You may have to restructure your HTML (and modify your CSS accordingly) so that you can select input:focus and then that input's corresponding label. For instance, if you moved your label after your input and used the following CSS selector for your label, you should be able to accomplish what you want.

#header .search input:focus + label

Now using Flex box will solve this. Have the label element follow the input element in the HTML. Then use flex-direction: column-reverse to change its position to appear above the input element. You can then use the input:focus + label: {} to target the label.

.input-container {
  display: flex;
  flex-direction: column-reverse;
}

  .input-container > input {
  /* your input styles */
}

 .input-container > input:focus + label {
  /* targets the label when the input receives focus */
  color: red;
 }
<div class="input-container">
  <input type='email' />
  <label>Email</label>
</div>

use:checked instead of :focus and you must give id,name,value into 'input'.

BoltClock's answer is the more semantic, lightweight way of achieving this functionality. However it's not always possible to have a specific HTML structure (especially to facilitate a minor feature like this) and CSS lacks the ability to traverse up the HTML hierarchy. To get around that, here are two alternatives. The first is coming soon (CSS spec 4) and the second is our old mate Javascript.

First up, CSS4's :focus-within pseudo selector. This does exactly what it says on the tin (scopes based on any child element's active focus state). Read more about the spec here. So assuming you have a HTML structure of:

<div class="input-wrapper">
    <label for="elem">Label Text
      <input name="elem" id="elem" type="text" />
    </label>
</div>

you could scope the 'focussed' label by simply:

label:focus-within{}

by the same token, you could also scope the parent div with:

div.input-wrapper:focus-within{}

Magical. But not for use today :(

Second up, if you're already using a JS selector engine (i.e. jQuery, Sizzle, etc.), you could also do something along the lines of:

$('input').on("focus", function(){
  var input = $(this);
  // assuming label is the parent, i.e. <label><input /></label>
  var label = $(this).parent();
  label.addClass('focussed');
  input.on("blur", function(){
    label.removeClass('focussed');
    input.off("blur");
  });
});

This is untested but the essence of what this achieves is using a class rather than the :focus pseudo selector. So you can add your focussed styles to label.focussed{}. I've added (and self-removed) the blur handler to facilitate removing the class.

Tags:

Css

Focus

Label