CSS Selector for selecting an element that comes BEFORE another element?

CssCss Selectors

Css Problem Overview


I'm working on a login page for my website and I want to bold the label that comes before the input box when the text box gains focus. Right now I have the following markup:

<label for="username">Username:</label>
<input type="textbox" id="username" />

<label for="password">Password:</label>
<input type="textbox" id="password" />

I can use the adjacent selector to select the label after the text box, but I can't select the element before it. I can use this CSS selector rule, but it only selects the label after, so when the username text box gains focus, the password label becomes bold.

input:focus + label {font-weight: bold}

Is there anything I can do to make this work? I know JavaScript could be used to easily do this, but I'd like to use a purely CSS-based solution if possible, I just can't figure out a way to do it.

Css Solutions


Solution 1 - Css

The CSS Selectors 4 Spec provides a syntax for defining the "subject" of a selector by using a !. As of early-2016, this is not available in any browser. I'm including this because it will be the correct way to do this using pure CSS once browsers implement this syntax.

Given the markup in the question

<label for="username">Username:</label>
<input type="textbox" id="username" />

<label for="password">Password:</label>
<input type="textbox" id="password" />

This CSS would do the trick.

label:has(+ input:focus) {font-weight: bold}

Of course, this assumes browsers actually implement the subject selector and that there are no bugs related to how this syntax works with the :focus pseudo-class.

Solution 2 - Css

It would be possible to use the 'adjacent sibling selector' if the input was before the label. Just put the input before the label, and then modify the layout to put label before the input. Here's an example:

<head runat="server">
    <title></title>
    <style type="text/css">
    input:focus + label {font-weight: bold}
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <div style="direction:rtl">
        <input type="text" id="username" />
        <label for="username">Username:</label>
    </div>
    <div style="direction:rtl">
        <input type="password" id="password" />
        <label for="password">Password:</label>
    </div>
    </form>
</body>

(It's kind of a hack, I would personally use javascript to do this)

input:focus + label {font-weight: bold}

<form id="form1" runat="server">
  <div style="direction:rtl">
    <input type="text" id="username" />
    <label for="username">Username:</label>
  </div>
  <div style="direction:rtl">
    <input type="password" id="password" />
    <label for="password">Password:</label>
  </div>
</form>

Solution 3 - Css

There's no selector that will give you the previous element using CSS..

You will need to use javascript to handle what you're after.

Solution 4 - Css

Use this selector:

label[for=username]
{
font-weight: bold
}

this will select the label that has the value 'username' in the attribute 'for'

Solution 5 - Css

Floating the input element to the right, achieves correct element order without changing order of "Username" and ":" in the label text that you get with direction:rtl.

<style type="text/css">
	form {text-align: right;}
	input:focus + label {font-weight: bold}
	input {float:right; clear:right;}
</style>
<form>
    <div>
        <input type="text" id="username" />
        <label for="username">Username:</label>
    </div>
    <div>
        <input type="password" id="password" />
        <label for="password">Password:</label>
    </div>
</form>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDan HerbertView Question on Stackoverflow
Solution 1 - CssDan HerbertView Answer on Stackoverflow
Solution 2 - CssMatt BrunellView Answer on Stackoverflow
Solution 3 - CssJayTeeView Answer on Stackoverflow
Solution 4 - Cssuser434917View Answer on Stackoverflow
Solution 5 - CssOle HelgesenView Answer on Stackoverflow