
Don’t use IDs in CSS selectors? (2011) - outdooricon
http://oli.jp/2011/ids/
======
_RPM
[Slightly off topic] One of the reasons I wouldn't use ID's is because the DOM
element with that ID is automatically introduced to the global scope. Open up
the console and type "up_8630368" and you will see it yields a DOM Element.

~~~
paulojreis
Is this true? If I have a element with id="foo", then "foo" will be available
as a variable in the global JS context? I tried, but can't reproduce it
(Chrome, Windows & Safari, OS X).

~~~
paulojreis
OK, sorry about the reply to myself, but it is true indeed.

I was testing with an id which contains a "-" (hyphen). As the hyphen isn't
valid for a variable, you can't access it directly or via the window object
(with the "dot" notation). However, it is there, and you can access it with
the array-like syntax.

Is this part of the spec? Or _creative_ interpretations?

tl;dr: HTML element with id="foo-bar". You can't access it as the variable
foo-bar in the global context or window.foo-bar (invalid var name). However,
you can access it via window['foo-bar'].

~~~
bzbarsky
It started as creative interpretations, then got added to every browser except
Firefox , then got added to Firefox because too many websites were relying on
it. And now it's in the spec, because too many sites are relying on it, so a
browser that doesn't do it wouldn't be web-compatible.

Classic race to the bottom. :(

------
dreamweapon
This is rather like famous "Go To Statement Considered Harmful" dictum of
lore, and its variants in other contexts: the key takeaway shouldn't be that
we should _never_ use these constructs -- rather than we should _be
circumspect_ about using them, as they tend to have hidden side effects.

~~~
drinchev
Totally agree, but in this case I can say for sure that the benefits of using
IDs are so impractical, that with no doubt I will add a class name to the
target element style the class not the ID.

In my development practice I've found that messing CSS with IDs don't help
scale your app ( you can hardly override them ), they are also subject of all
the reasons stated here and in the article ( bad performance, global scope
introduction, ... ).

The only reason to style IDs would be if I happen to have an old theme that
people styling it were using IDs.

I totally don't support styling IDs ( or using !important - which basically is
on the same page ).

------
Joe8Bit
I have to admit to not feeling too strongly either way about this, but the
argument I would have against the 'never use IDs in CSS selectors' is purely a
semantic one.

An ID, by design, semantically references a single thing. This has important
meaning when making HTML (amd CSS) readable and parseable. Now, I'm not
necessarily saying this is a 'winning' argument, but throwing away a useful
tool for declaring semantic meaning for hand wave'y arguments about
'britality' feels like overkill.

~~~
lcmatt
That's exactly the problem - you're referencing a single element which can't
be reused. I bet all the styling being used on the element could be broken
down in to reusable classes leading to cleaner code and less specificity.

~~~
Joe8Bit
I would argue about cleaner code, in my view doing something like:

    
    
        // HTML
        <div id="myLoginWidget">...</div>
        
        // SCSS
        #myLoginWidget {
          @extends #baseWidget;
          @extends #somethingElse;
          @include rounded-cornders(0.5rem);
          background: darken($base-blue, 20%);
          ...
        }
    

Is 'cleaner' than:

    
    
        // HTML
        <div class="baseWidget somethingElse small-rounded-corners dark-blue-bg">...</div>
    
        // SCSS
        .baseWidget { ... }
        .somethingElse { ... }
        .small-rounded-corners { ... }
        .dark-blue-bg { ... }
    

It achieves the same reusability (in code) without polluting the content
(HTML) with the presentation (CSS).

~~~
talmand
Are we saying "cleaner" as in "more efficient"? You have to keep in mind the
resulting CSS generated after compiling. There is a balance to be had between
clean CSS and efficient CSS.

If you are using the classes from the second example in more than one place in
your HTML and then depending on your actual CSS in those classes, then the
second option may be more efficient then your first. In SASS, it will totally
depend on how you write the actual CSS, not just the class versus id debate.

But a question from the article comes to mind in your example, what if you are
requested to insert a second login widget to the page? Even worse, if your
Javascript uses the ID for targeting the login code then you have to
reconsider that code as well.

~~~
Joe8Bit
If the SASS compiler wasn't smart enough to deduplicate several references to
a mixin it would unquestionably mean redundant properties and more weight in
the compiled CSS, but it wouldn't be any less efficient from a page paint POV.

There's a completely valid argument that any "improvements" in the above sense
are outweighed by the extra time in downloading and parsing a larger cold-
cached CSS file, but in my case I am happy to rely on the browser cache and
the compiler to be smart (and maybe sacrifice a small amount of resulting CSS
weight if it's not) resulting in "cleaner", more semantic HTML (and arguably
CSS).

In terms of the second login widget, you're absolutely right, my
implementation would fall down, but then it would be a VERY simple refactor.
However having n of something on a page would have a semantically different
meaning than my case, so therefore classes are indeed the right specificity
method!

------
moron4hire
I don't think you can really make a blanket statement like this. When you make
blanket statements, you're ultimately basing a decision on superstition,
rather than need or evidence. It's why I don't really care for anything that
claims to be "best practices". The term "best practices" really just means
"this worked for us in our situation". That's great, and one should be aware
of such things, but that doesn't make it a standard or a law.

~~~
mistercow
> The term "best practices" really just means "this worked for us in our
> situation"

I strongly disagree. Obviously there are always exceptional circumstances, but
if something is really a best practice, that means "if you decide not to do it
this way, you should have a good reason for that decision".

Now I _would_ agree that people are too quick to call something a "best
practice", when really it's just their personal preference (e.g. "always use
semicolons in JS", or "never use semicolons in JS").

~~~
moron4hire
Well, that's really what I mean. Too many people call their personal habits
"best practices", to the point that I just can't be bothered to listen to what
the general population of programmers has to say about how I do my own job.

~~~
kazinator
Exactly. If you are going to call something "best practice" then first you
need to put it in a formal document, and second, that document should be
signed off by a wide panel of experts from a broad cross-section of the
relevant industry.

The coding style guide put out by your 12 member startup isn't "best practice"
for everyone. It's just best practice for continuing to work there.

------
onion2k
_the performance difference between classes and IDs is irrelevant_

Instead of a test with a list of 1000 elements, try a test with a _nested_
list of 1000 elements. The performance problem with classes is that the
browser has to traverse the DOM to find them, starting from the deepest
element and working up. It's pretty quick, but not _that_ quick when you have
a deep tree. Whereas finding an element by ID is literally just a single
lookup in an index regardless of where the element actually appears.

That said, DOM traversal was a very slow procedure for a long time, so browser
developers spent a lot of time and energy optimising it. It's way better than
it was. It could well be the case that classes don't have the performance
problems they once did. Unfortunately, the test in this article won't show
whether that's true or not.

To clarify, if you have a selector like "div.class a", and HTML like;

<div
class="class"><div><div><div><div><div><div><a>Woo!</a></div></div></div></div></div></div></div>

..then the browser goes to every anchor in the DOM and then looks up the tree
asking 'Does this div have a class of 'class'?". That's what's slow. If you
use "div#id a" then the browser can look for the id more quickly. That's why
IDs are faster.

~~~
debacle
Did you read the article? It said explicitly that regardless of `div.class a`
or `div#id a` the same lookup takes place - every anchor on the page's parent
is checked to see if it has the id or class specified by the selector.

So the selector `a#id` will be faster than `a.class` but a parent selector
uses the same heuristic.

------
spion
Or simply don't use CSS at all:

[https://speakerdeck.com/vjeux/react-css-in-
js](https://speakerdeck.com/vjeux/react-css-in-js)

That presentation goes into more depth describing problems with CSS. Given a
virtual DOM in JS, the solution becomes simple and obvious: plain objects.

Its interesting how React completely reinvents "best practices".

~~~
1010
In my experience, "Don't use X at all" is very rarely, if ever, a suitable
response to "X has some flaws".

~~~
spion
I agree, and I understand that such "radical" claims invite a dismissive
reaction (downvotes). But the presentation really does make a very compelling
argument and offers a simple and elegant alternative solution that solves most
problems.

------
ad_hominem
HN title should be "Don't use IDs in CSS selectors? [2011]"

(missing question mark from original title and the year written)

