Scoped CSS is all the rage right now, and I personally am a big fan. (CSS Modules is a good implementation: github.com/css-modules/css-modules)
Here's why: when you're building an app, you spend a few minutes styling the app itself and many hours styling (or wanting to style) individual components. But CSS by default doesn't support that. Every style affects the whole app. There's no modularization, which leads to frequent surprises (a la "dang it, I guess that class name is already in use" or "why did my style change over here mess up my component on a totally different route?").
BEM is really good, but it's a workaround. Scoped CSS is a solution. And it's a first-class citizen of Angular and Vue, if you happen to use one of those.
I've really begun to dig the scoped CSS while working in Vue. It's made creating modular components that can be shared across the org a repeatable process that doesn't end in firefights on who's styling wins.
But, I don't have enough experience with large scale projects and long term projects, so I'm really enjoying reading this post :)
Most of the time you're right, a CSS methodology works great and avoids scoping issues. But regular CSS is non-scoped and non-modular by definition, so there's always the possibility that in a larger app, a developer will unknowingly use a component or utility name that is already in use elsewhere, thus destroying the semantic barriers between components and causing style conflicts. I've seen this happen a few times (with BEM) and it can be very difficult to figure out why things are broken.
That said, I'm not opposed to CSS methodologies at all, but if scoped CSS is an option I will always choose that because it's far less likely to fail due to human error.
In my company, we separate each CSS component in different files (button.scss, tabs.scss, etc). This way, there'no way to get conflicts.
If you think, css classes create scopes the same way js functions does.
CSS is not the problem. Developers are.
That's not the way I see it. If I have two separate JavaScript functions and each declares a variable named "foo", they will always refer to different memory locations. There is no way to get "foo" in one function to refer to "foo" in the other function. In CSS, if I declare two classes named "foo", both of them globally refer to everything with the class "foo."
Separating CSS components into different files doesn't create new CSS scopes. If you happen to use the same selector in both, then you'll end up with two different sets of styles for a single element. This isn't a rarity in large apps; it happens often. If one developer wants to create a tab that acts like a button (.button-tab) and another developer wants to create a button that looks like a tab (.button-tab) they'll end up with an overlapping selector. Some developers will dig through the codebase to figure out where the conflict is and rename the class to fix things; many will not, and instead choose to bump up the specificity in order to make their styles work, which over time reduces maintainability.
CSS was created for developers. If developers consistently have trouble with certain aspects of it, then blaming the developers isn't a productive approach. Scoped CSS is inherently predictable and debuggable in ways that global CSS is not.
If you create 2 foo functions globally, they will conflict. Of course you won't do it.
In CSS you can also prevent that. For example you can use BEM - or even nested selectors to help.
That's what I was trying to explain.
About separated CSS files, I forgot to say that every class inside each file must start with its name. For example, in the file button.scss you would put .button, .button--big, .button__icon, etc.
Developers - specially with less experience - have problems with every language. That doesn't mean the languages are bad or wrong. It means we must create patterns and best practices for them.
Scoped CSS is all the rage right now, and I personally am a big fan. (CSS Modules is a good implementation: github.com/css-modules/css-modules)
Here's why: when you're building an app, you spend a few minutes styling the app itself and many hours styling (or wanting to style) individual components. But CSS by default doesn't support that. Every style affects the whole app. There's no modularization, which leads to frequent surprises (a la "dang it, I guess that class name is already in use" or "why did my style change over here mess up my component on a totally different route?").
BEM is really good, but it's a workaround. Scoped CSS is a solution. And it's a first-class citizen of Angular and Vue, if you happen to use one of those.
you find out just how bad it is when you load a vue single file component and it mysteriously break another one because the CSS wasn't loaded yet
This has never happened to me. I wonder if that's been fixed in the latest version.
Cool, these are concepts I've seen flash my way but I never really caught the wave. Thanks. Still would love some other input on any of this.
I've really begun to dig the scoped CSS while working in Vue. It's made creating modular components that can be shared across the org a repeatable process that doesn't end in firefights on who's styling wins.
But, I don't have enough experience with large scale projects and long term projects, so I'm really enjoying reading this post :)
If you follow a CSS methodology, your code is going to be modular and you won't have any problem with scope. Try ITCSS, for example.
Most of the time you're right, a CSS methodology works great and avoids scoping issues. But regular CSS is non-scoped and non-modular by definition, so there's always the possibility that in a larger app, a developer will unknowingly use a component or utility name that is already in use elsewhere, thus destroying the semantic barriers between components and causing style conflicts. I've seen this happen a few times (with BEM) and it can be very difficult to figure out why things are broken.
That said, I'm not opposed to CSS methodologies at all, but if scoped CSS is an option I will always choose that because it's far less likely to fail due to human error.
In my company, we separate each CSS component in different files (button.scss, tabs.scss, etc). This way, there'no way to get conflicts.
If you think, css classes create scopes the same way js functions does.
CSS is not the problem. Developers are.
That's not the way I see it. If I have two separate JavaScript functions and each declares a variable named "foo", they will always refer to different memory locations. There is no way to get "foo" in one function to refer to "foo" in the other function. In CSS, if I declare two classes named "foo", both of them globally refer to everything with the class "foo."
Separating CSS components into different files doesn't create new CSS scopes. If you happen to use the same selector in both, then you'll end up with two different sets of styles for a single element. This isn't a rarity in large apps; it happens often. If one developer wants to create a tab that acts like a button (
.button-tab
) and another developer wants to create a button that looks like a tab (.button-tab
) they'll end up with an overlapping selector. Some developers will dig through the codebase to figure out where the conflict is and rename the class to fix things; many will not, and instead choose to bump up the specificity in order to make their styles work, which over time reduces maintainability.CSS was created for developers. If developers consistently have trouble with certain aspects of it, then blaming the developers isn't a productive approach. Scoped CSS is inherently predictable and debuggable in ways that global CSS is not.
If you create 2 foo functions globally, they will conflict. Of course you won't do it.
In CSS you can also prevent that. For example you can use BEM - or even nested selectors to help.
That's what I was trying to explain.
About separated CSS files, I forgot to say that every class inside each file must start with its name. For example, in the file button.scss you would put
.button
,.button--big
,.button__icon
, etc.Developers - specially with less experience - have problems with every language. That doesn't mean the languages are bad or wrong. It means we must create patterns and best practices for them.
"A CSS methodolody"... is a thing?! Oh you mean a way of structuring and naming selectors...?
Yes. Such as BEM, ITCSS, OOCSS, Atomic, etc.