Which CSS selector?

Sometimes I find it difficult to choose the right CSS selector. Consider this, for example:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Which CSS selector</title>
    <style>
        [for="married"] {
            outline: 1px solid red;
        }
    </style>
</head>

<body>
    <form>
        <label for="name">Name</label>
        <input type="text" id="name">
        <label for="married">Married</label>
        <input type="checkbox" id="married">
    </form>
</body>

</html>

I can get the same result with:

  • label:nth-child(3)
  • label:nth-of-type(2)
  • #name + label
  • etc.

I can even give the element an ID and get it directly. But isn’t it better to keep your HTML tidier/smaller?

Sure, but within reason. It’s no big deal to add a special class where needed, although in this case [for="married"] is fine. Just consider support in older browsers if it matters to you.

never be afraid to use your nogin! :wink:
if you find that there is more more than one way to skin a cat, then use the one most suited to your goal.

for example.

IDs will taget your element yes, but they cant be repeated and and have some serious CSS heft. On the other hand if you also need to feed that element to a JS… IDs are pretty handy. So if the element was IN DEED unique to the page OR BETTER YET if you needed the ID anyway for .js then why not take advantage of it in your CSS?

Same deal with the attr selector, unless you are supporting REALLY OLD browser, and you need the ‘for’ attribute, why not take advantage of it as a CSS selector as well.

Classes are almost ubiquitous solutions ( the only downside being you have to add the class to your mark up)

and descendant selectors are great because, theoretically, they allow you to target elements w/o ANY alteration to your mark up. But the downside to that is that your CSS is now intrinsically tied to your HTML structure; deviate from that structure and you could have a hot mess on your hands. Also, some IE versions registered comments as elements.
for example:

<p></p><--!IE eats glue--><p><b>I dont eat glue!</b></p>
p+p>b { display:none;}

Older IE will not honer this rule ; since it sees the comment as an element so there is no p immediately following another p.

hope that helps.

Thanks for the explanation! :slight_smile:

[font=calibri]What you’ve got looks good to me, with a class/ID directly on the element if you don’t have a handy attribute selector to use. I wouldn’t consider any of the other options you’ve given as appropriate in this case – there are valid use cases for each of those constructions, but they don’t fit what you’re doing here. Why not? Think about what happens if you re-order the code, or add extra elements.

[list][]label:nth-child(3) will always target the third child of a parent when it is a label. That might not match any elements, let alone the right one, if you change your form around.
[
]label:nth-of-type(2) is better because you know it will always hit a label, but you’ve no guarantee it will be the right one if you decide to shuffle the form round or add an extra question.
[]#name + label will hit the label following the input with ID of ‘name’, but again, what happens if you want to add an extra question? You want your CSS to be robust and to survive those kind of changes intact, and there’s no reason why it shouldn’t be able to if you choose your selectors properly.
[
]etc. is not a valid selector :rofl:[/list][/font]

Thanks for the advice and good sense of humor! :wink: