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.
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. :)
[1] https://cs.chromium.org/chromium/src/third_party/WebKit/Sour...
[2] https://cs.chromium.org/chromium/src/third_party/WebKit/Sour...
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.
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.
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.
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:
https://codepen.io/Ravenstine/pen/xpYoWv
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.