Hacker News new | ask | show | jobs
by ravenstine 3020 days ago
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:

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.