You could put the style right in the HTML tag, or on the page where it's used, but with dynamic pages (and static stylesheets) both options will cost you bandwidth.
And they split up your styles into separate places.
So putting the style on the id is the right thing to do, and I don't understand why the author is against it.
If I need my footer to look a certain way, then #footer {} is exactly what you should do.
Not add some bogus class based style just in case someone decides we need two footers on one page.
There is not a single time I had though to myself "This should have been an ID instead of a class"; but there are hundreds of times where I have though to myself "This should have been a class instead of an ID".
Interesting, I'm the other way around, I've defaulted to classes and then found that Ids would be more appropriate in many cases.
My simple rule for id vs class (as a non-expert) is if you say 'this is the x' e.g. 'this is the footer/header/navigation-panel' then it's an Id, if you would say 'this is a y' e.g. 'this the a product/list-item/image' then it's a class.
In terms of pure CSS it doesn't matter, but for JavaScript that manipulates the DOM (e.g. jQuery), it does. Specifically, `getElementById` is more than 50% faster than `getElementsByClassName`.
That micro benchmark is comparing getElementById which is a map lookup (assuming the id is unique in the document) vs getElementsByClassName which is creating an iterator that would scan the document as you loop over it, except that the page is not looping over it or calling .length, so it's not really scanning anything at all.
Essentially it's benchmarking a handful of branches inside getElementById that do the map lookup for an Element [1] against the handful of branches inside getElementsByClassName that do the map lookup for a NodeList [2]. They both look pretty similar to me in branch and map lookup count, so I'm not sure where the difference is, but it's not something that would impact real content since on a real page getElementsByClassName's cost is related to typical behavior being O(N) instead of O(1) like getElementById. Browsers have a ton of caching around it though, so getElementsByClassName can look like O(1) in micro benchmarks.
You could could alter the benchmark to do getElementsByClassName("my-class")[0] to test the scanning but browsers cache that too, so you'd need to actually modify the document between each run of the benchmark somehow (ex. adding or removing an element) to invalidate the cache.
Typical content that uses getElementById will be faster than content that uses getElementsByClassName, but it's hard to show that in a benchmark. :)
Well if what you style is the main content/header/footer area, and there is should only be one of it per page, using an id is a good way to enforce it as well as document it.
If you made it a class, I would assume I can reuse it elsewhere.
Now it's ony true for stuff you can't reuse, but unless you are building a boostrap competitors, there are actually a lot of things you never reuse in a real website.
Once I needed to make an internal IE addon to listen for certain elements being selected on pages outside of our control. (to ensure we never collected sensitive data for compliance reasons, long story. Trust me it makes more sense in context than it does in a single paragraph.)
My co-worker wanted to grab by id and attach listeners, but I was convinced that wouldn't work. I wanted to listen at the top level and filter down by id/class/etc...
The first production test was <redacted>.com/login. It had a login widget on the navbar and a login widget in the main content section. Both the username and the password field had the same id in the navbar and the content. So the addon did the right thing on the navbar, but not in the content, and we had to go back and redo it thanks to id reuse.
My point is, elements with ids are rarely unique. I've never regretted using a class instead of an id. I've regretted using an id instead of a class. And I really regretted third parties using ids instead of classes.
Please don't use ids. Your unique elements won't be for long, I guarantee it.
A friend once told me about a girl in their cs 101 class, who learned about arrays, and proceeded to make every variable an array. When queried, she responded, "I might end up realizing I need a multiple of the variable, and this way I won't have to change anything when I do".
Did she then go on to create jQuery? Because that concept (with a touch of functional inspiration) is one of the underlying ideas behind the library and why it was considered so much easier to work with than the DOM API.
I get where you're coming from, but I don't think it's a good reason to avoid classes. That's what they're there for.
Not at all; some simple effects like a stick-to-the-top header usually require cloning such element using JavaScript; and even if such effects are not needed right now they may be added in the near future, so no, there is not a single time where having an ID over a class makes sense.
I tend to reserve IDs for things that exist only once on the page at a given time, and the only properties I define under IDs are ones for layout. For example, if I have a page for an article, I would make the top-most element "#article" and things like the navbar and the body "#article__nav" and "#article_body". The only thing those IDs are concerned with is how the navbar and the body are sized and positioned when on the article page.
Shared stylistic properties for components use class names. The properties that make a navbar look like a navbar(color, font, and anything that applies to children) would be specified under ".nav" and the same would apply for the body under ".body". Anything that's stylistically-specific to
Shared variations of components are handled with modifiers. An example would be ".nav--dark".
Any one-off variations are handled with parent-scoped class names like ".article__nav", since I treat even that topmost element as a component. (or a block if you're thinking in BEM).
I've found that keeping "style" and "layout" CSS properties separate helps keep components flexible and untangled from a given page layout. The differentiation between IDs and class names makes this more convenient because it becomes obvious what parts of my CSS are intended for.
But what about the internal layout of components? If the children of a component are supposed to change their sizing and positioning at different breakpoints, then how are you supposed to achieve this while keeping components agnostic about the page layout?
It's a tricky problem, but I solve this with Sass mixins. If a component has different internal layouts for mobile and tablet screens, as an example, I write mixins to define those states using the same naming convention that I would use with class names and IDs. If I was using a grid system, I would define them as "@nav--lg", "@nav--md", "@nav--sm", "@nav--xs", etc. Then underneath the page layout, in this case "#article", I would include those mixins under the chosen breakpoints. That way, all layout can be handled by IDs in stylesheets dedicated to page layouts.
It just so happens that I have a Codepen that demonstrates this idea:
The only part that is different is that I made the masthead and the footer not a part of "#article". If you don't plan on having components like that behave differently depending on the page they are on, that's probably appropriate.
I think the author probably agrees with you. What you pointed out is the exception to the rule though. The percentage of things on a page that are "singletons" is very small compared to reusable widgets.
If you don't have much resuable stuff on your site, that's a code smell in itself
> If you don't have much resuable stuff on your site, that's a code smell in itself
It can be reusable and yet unique on each page. And those should get id's, and are not rare at all.
> The percentage of things on a page that are "singletons" is very small compared to reusable widgets.
That isn't necessarily true. Obviously there are different types of pages, but a typical page will have a number of elements on it that are each unique. (They might appear on more than one page, but on any particular page, they are unique.)
> It can be reusable and yet unique on each page. And those should get id's, and are not rare at all.
I _think_ what's going on here is that, in the, excuse my French, _enterprise_ sector it's very common to have some sort of an end-user configurable, enormous form (or dashboard or whatever) full of widgets that are not in any way unique. In fact in many places it's so common, that for a certain section of developers it might be hard to imagine that the opposite is actually quite common.
This is _a lot_ of "web" development. Often done by developers who, to be honest, would rather be doing this in QT (eww) or something.
Elements can often be unique today but not tomorrow as pages grow in complexity and start sharing features. Ids are fine (even necessary) for things that are unique in their very essence, like a label's for="", the target for a URL fragment, or things that need special individualized treatment in JavaScript. In the common "unique today" case, ids provide no benefit over classes as simple styling hooks and quickly become a PITA when they start colliding.
In the classic days of web dev it was best practice (and still is in my opinion) to separate style (CSS) from functionality (JavaScript). So you had classes for CSS and id's for JS. So if you change the id you don't have to update your CSS. If you have a "singleton" it's better to use the element's name instead of id in the CSS. for example body instead of #body for the same reason (separate from JS). And if you want to have different types of body, add a class to the special body. id's will for example create global JS variables, so if you are styling using #id you will create a bunch of unnecessary global JS variables.
I would use ".xed-footer" for reusable footer bearing the x caracteristic. And #main-footer for the stuff that stick at the bottom of most of my pages with unique caracteristics.
Way more self describing. No team member will ask which one is reusable and which one is not.
I think the preference against ids is covered over point #2 about specificity. id styles will always override class styles, so when you're trying to apply a class-based style guide to an element that's already been styled with an id, you end up having to use !important which just creates a similar specificity problem for someone else down the line.
Of course, you can still do this if you want to. To quote Chris Rock, "you can drive a car with your feet if you want to." But if you work on a large code base that lots of developers have touched, and lots of future developers will touch, you run into these issues all the time. And the bugs that come about can be tough to spot and to fix.
You could put the style right in the HTML tag, or on the page where it's used, but with dynamic pages (and static stylesheets) both options will cost you bandwidth.
And they split up your styles into separate places.
So putting the style on the id is the right thing to do, and I don't understand why the author is against it.
If I need my footer to look a certain way, then #footer {} is exactly what you should do.
Not add some bogus class based style just in case someone decides we need two footers on one page.