I’ve been intrigued by CSS Modules lately. If you haven’t heard of them, this post is for you. We’ll be looking at the project and it’s goals and aims. If you’re intrigued, stay tuned, as the next post will be about how to get started using the idea. If you’re looking to implement or level up your usage, part 3 will be about using them in a React environment.
Article Series:
- What are CSS Modules and why do we need them? (You are here!)
- Getting Started with CSS Modules
- React + CSS Modules = 😍
What are CSS Modules?
According to the repo, CSS modules are:
CSS files in which all class names and animation names are scoped locally by default.
So CSS Modules is not an official spec or an implementation in the browser but rather a process in a build step (with the help of Webpack or Browserify) that changes class names and selectors to be scoped (i.e. kinda like namespaced).
What does this look like and why do it? We’ll get to that in a sec. First, remember how HTML and CSS normally work. A class is applied in HTML:
<h1 class="title">An example heading</h1>
And that class is styled in CSS:
.title {
background-color: red;
}
As long as that CSS is applied to the HTML document, the background of that <h1>
would be red. We don’t need to process the CSS or the HTML. The browser understands both those file formats.
CSS Modules takes a different approach. Instead of writing plain HTML, we need to write all of our markup in a JavaScript file, like index.js
. Here’s an example of how that might work (we’ll take a look at a more realistic example later):
import styles from "./styles.css";
element.innerHTML =
`<h1 class="${styles.title}">
An example heading
</h1>`;
During our build step, the compiler would search through that styles.css
file that we’ve imported, then look through the JavaScript we’ve written and make the .title
class accessible via styles.title
. Our build step would then process both these things into new, separate HTML and CSS files, with a new string of characters replacing both the HTML class and the CSS selector class.
Our generated HTML might look like this:
<h1 class="_styles__title_309571057">
An example heading
</h1>
Our generated CSS might look like this:
._styles__title_309571057 {
background-color: red;
}
The class attribute and selector .title
is entirely gone, replaced by this entirely new string; Our original CSS is not being served to the browser at all.
As Kitty Giraudel said in his tutorial on the subject:
[the classes] are dynamically generated, unique, and mapped to the correct styles.
This is what is meant by styles being scoped. They are scoped to particular templates. If we have a buttons.css
file we would import it only into a buttons.js
template and a .btn
class within would be inaccessible to some other template (e.g. forms.js
), unless we imported it specifically there too.
Why would we want to mess with the CSS and HTML to do this? Why on earth would we want to work this way?
Why should we use CSS Modules?
With CSS Modules, it’s a guarantee that all the styles for a single component:
- Live in one place
- Only apply to that component and nothing else
Plus, any component can have a true dependency, like:
import buttons from "./buttons.css";
import padding from "./padding.css";
element.innerHTML = `<div class="${buttons.red} ${padding.large}">`;
This approach is designed to fix the problem of the global scope in CSS.
Have you ever been tempted by a lack of time or resources to simply write CSS as quickly as possible, without considering what else you might affect?
Have you ever slapped some random bits and junk at the bottom of a stylesheet, intending to get around to organizing it but never do?
Have you ever run across styles that you weren’t entirely sure what they did or if they were even being used?
Have you ever wondered if you could get rid of some styles without breaking something? Wondered if the styles stood on their own or depended on other things? Or overwrote styles elsewhere?
These are questions that can lead to big headaches, bloated project deadlines and sad, wistful looks out of the window.
With CSS Modules, and the concept of local scope by default, this problem is avoided. You’re always forced to think about the consequences as you write styles.
For instance, if you use random-gross-class
in HTML without applying it as a CSS modules-style class, the style will not be applied, as the CSS selector will be transformed to ._style_random-gross-class_0038089
.
composes
keyword
The Let’s say we have a module called type.css
for our text styles. In that file we might have the following:
.serif-font {
font-family: Georgia, serif;
}
.display {
composes: serif-font;
font-size: 30px;
line-height: 35px;
}
We would declare one of those classes in our template like so:
import type from "./type.css";
element.innerHTML =
`<h1 class="${type.display}">
This is a heading
</h1>`;
This would result in markup like:
<h1 class="_type__display_0980340 _type__serif_404840">
Heading title
</h1>
Both classes have been bound to the element by the use of the composes
keyword, thus avoiding some of the problems of similar solutions, like Sass’ @extend
.
We can even compose from a specific class in a separate CSS file:
.element {
composes: dark-red from "./colors.css";
font-size: 30px;
line-height: 1.2;
}
BEM not required
We don’t need to use BEM when we’re making a CSS module. This is for two reasons:
- Easy parsing – Code like
type.display
is just as legible for developers as the BEM-y.font-size__serif--large
. Likely even easier to mentally parse when the BEM selectors get long. - Local scope – Say we have a class like
.big
in one module where it changes thefont-size
. In another we use the exact same class.big
that increasespadding
andfont-size
in a different amount. It simply doesn’t matter! They won’t conflict, because the styles are scoped very deliberately. Even if a module imports both stylesheets, then it has a custom name which our build process makes specifically for that class. In other words, specificity issues disappear with CSS Modules.
Cool, huh?
These are only some of the benefits of writing CSS Modules.
If you’re interested in learning more, Glen Madden has written extensively about some of the other benefits to this approach.
The next article in this series will look at how to get a project up and running with Webpack and CSS Modules. We’ll be using the latest ES2015 features to do this and looking at some example code to guide us through the process.
Further reading
- CSS Modules: Welcome to the Future
- Kitty Giraudel’s CSS Modules tutorial on Sitepoint
- Understanding ES6 modules
- Let’s Learn ES2015
- Brief overview of ES6 Module Syntax
Article Series:
- What are CSS Modules and why do we need them? (You are here!)
- Getting Started with CSS Modules
- React + CSS Modules = 😍
If the CSS is so tightly bound to the element then it should be put in the element’s style attribute.
I agree. This seems like unnecessary complication. The point of using external css is cleaner html. I even try to avoid overusing the class attribute. Just add
<section class="newsList">
and style by element name down the tree.Inline CSS has some limitations, like no support for pseudo selectors…
I thought the same. The only thing is that you would write the style part once.
I agree with Richard. This seems like a step backwards in my opinion.
It is more user friendly actually I have to agree with Robin on this point, it would also work on IE6 would you believe, though a site I was on the other day seems to use this throughout their website http://www.skyblueoceanmedia.com/ .. They also use the Section-Class modules too? I am still quite baffled as to how this works in IE6 let alone new browsers?
I don’t see myself writing all HTML inside JS only to use CSS Modules… sorry, this is a clever idea but I don’t believe it’s practical
I Agree !
This sounds needlessly complicated. Especially when you can use scoped css with a polyfill.
My initial reaction was WTF!
And I thought to myself – “Maybe I’m being particularly thick, and am missing the point entirely.”
So I also read http://glenmaddern.com/articles/css-modules
Yes, the current CSS modules implementation looks really messy to me, but I can see why they may be a good thing.
I might change my mind somewhere along the line, but this seems needlessly complicated.
The whole “let’s turn everything into JavaScript” is getting out of hand. I love React & friends just as much as the next guy, but a line needs to be drawn. This something that good, tidy and well-designes Sass files can easily accomplish, without the ridiculous amount of extra work.
There are a lot of other ways to get your scope under control than resorting to this. I suppose this method would be useful if you’re already using a tool like React where they do everything in JS, but with tools like LESS or PostCSS (with addons), this kind of precise scoping can already be done within the realm, and with better semantics.
There are two key things that I really like about CSS Modules:
They can assume/complement the role of BEM (or any of the other naming conventions/methodologies), but they can be automated as part of your build. For large projects/teams, this can be extremely helpful to keep everything scoped properly.
They allow for some cool innovations in your build. For example, using PostCSS-Modules and SweatMap (a little Github project of mine), I’ve been able to obfuscate all of my super semantic BEM class names like
.hello__greeting
into.a
and pass those into all the relevant JS and HTML files while still being properly scoped.The other thing I wanted to comment on was this statement in the article:
To be clear, we do not need to write our markup in JavaScript. The markup can be authored in whatever we like, we just have to be able to pass in our CSS Modules data during the build. I recently did a static site project in Handlebars + PostCSS-Modules and it felt a lot more natural that authoring my markup in a JavaScript file. When a project calls for React, JSX does feel pretty good too :)
Good breakdown Robin! I’m looking forward to the day when we have a native way to scope our css properly that doesn’t require a build process or “arcane” naming conventions.
Your SweatMap tool looks awesome – I was looking at some source code from google and assumed they had a similar build process.
How do you see this process working in development teams where front-end code is passed on to back-end developers?
Thanks Dean! PostCSS-Modules handles back-end templating by generating a JSON file of all the modules that were changed. As long as your front-end build runs before your back-end build, you’d just pass that JSON file in to whatever you’re using for back-end templating (really slick in React centric products).
Coordinating between front-end and back-end is always a bit of a challenge, but I’ve found that to be true in any project regardless of tooling.
Well, yes, I do agree with most of the comments found here. No, i will definitely not develop a new framework in javascript which generates HTML code just because the CSS is modular.
But i thought to myself “what if i was given a task to find the perfect scenario for this?” – in my opinion this is good for having dynamically generated pages. Most likely user-generated content in scenarios when you have profile sections for each user where they can modify the layout and structure of their Profile page. you might not want to load all modules of that page. There used to be iGoogle (now: http://www.igoogleportal.com/).
I’m guessing that’s a scenario?
Just an FYI, CSS scoping is something that Angular 2 does out of the box. It’s kinda nice for making clean reusable components.
“Instead of writing plain HTML, we need to write all of our markup in a JavaScript file, like index.js.”
Nope. Not writing all of my markup in JS and adding a compile step, ending up with class names that are semantically meaningless just to address scoping.
And I really hope the front end dev community loses its fascination with trying to use JS for everything. It’s incredibly useful but shoehorning every bit of front end dev into a JS mindset is really starting to be annoying.
I totally agree that the move toward JS solutions has been moving at a pace that’s super fast — and perhaps too fast for our own good.
At the same time, shutting the idea down altogether might be to our detriment as well. I firmly believe in choosing the right tool for a particular job and JS templating (including CSS Modules) could be a solid solution for applications you may not have encountered just yet.
It’s possible that JS templating DOES have a niche. I simply don’t like that it’s being pushed as the solution we reach for first. Chris just published a link to a talk by Jeremy Keith (https://css-tricks.com/resilience/) that I think captures the approach that I, too, favor:
Identify core functionality of your website.
Make that available using the simplest technology.
Enhance!
By all means, use JS where it adds true value. If that’s in templating for given project then by all means use it. But don’t push JS templating at me as a good general purpose practice.
Agreed!!
Writing all my my markup in pure JS, would kill me and my frontend developers…. :(
CSS modules seems like a great idea, but I’m thinking it’s not there yet, if we need to turn to JS markup…
Not technically true. You just need a mechanism to get the automatically-generated CSS class name into the final HTML mark-up.
If you are using JSX or ES2015 templates, then JavaScript is that mechanism.
But the CSS modules approach works just fine with Angular 1, which uses HTML templates.
Please don’t scare people away from CSS modules. :)
Ron.
Any chance you could explain how to use CSS modules with Angular?
I’m surprised by the number of comments that miss the point of this article. I can see a lot of people frowning when told to use Javascript to output HTML, so this kind of use of CSS should lead to similar – if not worse – reactions.
But times and techniques in web development change fast, and things like React that was rejected and even ridiculed when it first came out are now the most discussed technologies around.
And look at that – in the third part we’ll see the integration of CSS modules with React, which is where I expect them to really shine. Of course, it’s unpractical for smaller projects that maybe don’t even need compilation, but come on guys, you have to give them a chance.
I won’t speak for others but it’s the notion implicit in your comment – that things on the web should be written in React or something like it – that I’m pushing back on. There are certainly cases where React or similar is the absolute right thing to use. However, that’s not 100% of the cases and it seems a lot of people are reaching for a JS framework as a default without asking if the project they’re on really needs one at all. Apps? Yeah. Many many sites? Probably not.
I think of the web as HTML/CSS/JS and that we use the simplest, fastest, most basic tech first, moving to more complex things only when we really need to.
Or maybe the article missed the real point of CSS modules. Maybe such silly examples fail to demonstrate any significant use case, especially as an introduction for new adopters.
Also “most used” or “discussed” doesn’t mean “best”. Popularity is not a validator, nor it guarantees suitability.
Promoting adoption requires better use cases because (at best) decisions should taken based on need, not influence.
I just don’t get it! This seems like yet another way we have managed to find to massively complicate the development process for no real gain. The selling point for using external CSS files back in the day was that you could style components of your site globally. This just introduces a rediculous level of specificity that is going to produce CSS bloat, and in order to achieve it you have to code your HTML and CSS in a JS file!
Daft if you ask me, but each to their own.
LOVE how the first example itself is something that under logical structural rules (aka something we had before HTML 5’s asshattery pissed all over numbered headings) is something that there is NO legitimate reason to ever do in the first place… class on a numbered heading? That’s a good one.
But then given the bloated idiotic halfwit dumbass rubbish class the preprocessor/include crap is vomiting up and has the unmitigated gall to call markup, I suppose such an idiotic “how hard can we make something simple” approach to development should hardly be a shock; given that anyone DUMB ENOUGH to use this type of thing by choice — just like SCSS, OOCSS and it’s kine (yes, the archiac plural for cow is truly appropriate here) — probably doesn’t know enough about HTML, CSS, JavaScript, bandwidth limitations, limitations of the medium, accessibility, sustainability, or user experience to be making websites in the first place!
Mein Gott, the more articles I’m reading about these “new” approaches for making HTML and CSS pointlessly more cryptic and harder to maintain, the more terrifying it gets. Seriously, if you find ANY advantage to approaches like this in writing HTML and CSS, do the world a favor, back the honk away from the keyboard, and go take up something a bit less detail oriented like macramé!!!
But I guess with all the people dumb enough to bloat out their code with mouth-breathing short-bus idiocy like bootcrap and jQuery, the kid gloves are off on trying to make websites as painfully bloated and agonizingly difficult to maintain as possible!
Perhaps you’d like to back up some of these opinions with some examples of your work?
I’d hazard a guess your websites probably look like the Yahoo homepage circa 1996 as you seem to think that web technologies shouldn’t have moved on from the original basic document markup and styling tools they were 20 years ago.
Or, perhaps the reason you hate SASS, module loading, JS frameworks etc. is that you just lack the capability to understand them properly?
If you hate all new technologies so much, I think you’re in the wrong industry.
Does ‘textExtract’ plugin support it ? Looks like inline stylesheet in your debugger window.
http://www.xanthir.com/blog/b49w0
This is what I imagine as css modules. I’ll just wait till it’s implemented in native CSS or there’s a polyfill for it. I don’t see myself doing what you have here
On one hand, I’m tempted to be the skeptic that I usually am, and write something along the lines of what everyone else has already written…
On the other hand, this is kind of intriguing. In its most simplest terms, it seems to boil down to this, after getting rid of all of the JS junk and writing some pseudocode:
foo.css
bar.css
index.html
Whereas, if both stylesheets were simply concatenated (or just included together),
foo
would end up applying both the styles fromfoo.css
and `bar.css, with no way to separate:Except… why not ditch the whole pre-/post-processing step and just namespace your CSS classes?
foo_foo
takes the same effort to type asfoo.foo
, and takes a lot less effort to set up (no pre-/post-processing, no unnecessary HTML templating, etc.).Oh, and no terrible, ugly, what-the-hell-is-even-going-on class names.
So, long story short, it sounds like what this article has described is CSS namespacing, but using filenames instead of prepending something into the CSS identifiers. Am I missing something?
Well, I guess what I’m missing is the tight coupling between CSS and HTML. With CSS modules, it becomes easier to analyze what CSS rules are actually used, what rules are dead code, etc.
But, wait a second… how the heck do you use these classes from dynamic code? E.g.
foo.toggleClass('active')
? Do we have to get into some complicate JS maps of styles likefoo.toggleClass(compiledStylesMap['active'])
wherecompiledStylesMap['active']
results in'active_fileName_1234'
?My head hurts a bit.
Yep! CSS Modules is essentially build/automated namespacing.
This is a good idea if you’re on a small team or you’re lone wolfing it and practice good conventions (BEM, ACSS, etc.). The problem starts when you start to add developers to your team and they don’t buy in or have good practices. CSS Modules enforce namespacing whether or not your team does.
How the class names appear is entirely up to you. What’s displayed above is just the default or whatever the author has chosen for that project. You could use CSS Modules and spit out something like
[filename]_[classname]
and generate a class name exactly as you described above without thinking about it or doing any extra work once the build is setup. You could even obfuscate the names (like I mentioned in my comment above) and save a few bytes turning.my-semantic-class
into.a
for production while ensuring it’s still unique.During the build. The Github pages for CSS Modules and PostCSS-Modules go into things in more detail.
“The problem starts when you start to add developers to your team and they don’t buy in or have good practices.”
That’s an engineering management/lead failure and I’m not sure that it’s a good idea to use a technology like this to patch people’s laziness and inability or unwillingness to get organized.
This isn’t just about laziness or inability. People can make mistakes too.
With the risk of sounding dogmatic myself, I’d argue that automation and tooling to make our optimizations for us is always a good idea. Why do something manually and by extension, have the entire team do manually what you could do automatically and perfectly consistent at build time? Yes it adds complexity, but we’re talking about team projects here that warrant it.
If you’re on a team, I’m assuming you perform other optimizations on your HTML, JS, and CSS like minification and obfuscation automatically. What makes name spacing your classes during a build an “engineering management/lead failure”?
Benjamin, can you link me to an example of interacting with the classes dynamically? Sorry, couldn’t find what you were referencing.
Sure thing @Agop, check this out -> https://github.com/outpunk/postcss-modules#integration-with-templates
It gives some examples using Jade (now Pug) and straight up HTML with PostHTML. The same principles apply to any templating setup that can take in a JSON object as values at build time. I’ve personally used it with both JSX and Handlebars to render static HTML. Let me know if that doesn’t work out for ya!
You lost me at “white HTML in javascript” lol come on.
Write *
I’m sorry, I yet don’t understand the value of “CSS Modules”. The main reason advertised here is avoiding the cascade which is simply not possible if you want proper markup and want to use any CSS on that markup. I summarized my “problems” over here: https://helloanselm.com/notes/on-css-modules/.
If you have real life experience with CSS modules, I’d love to know whether my points in the article are true and what your main advantage is for using the technique/tool. Thanks in advance.
Anselm, great response. You picked up on the same things I did.
I’ve been trying to be open-minded about this article, but I think I found why I can’t related to this when I read the linked Glen Madden article:
I think it gets to the root of why so many of us in the Comments aren’t resonating with what’s being proposed. The CSS Modules way of thinking assumes that CSS as a language is “broken” because it doesn’t work like other languages. Therefore it needs to be fixed (using JavaScript) to be like the other languages.
CSS doesn’t work like other languages because it was designed to be a globally applicable, far reaching language, where you can affect a lot of change with little effort.
CSS a powerful language that takes a lot of training and experience to use well. Even if CSS Modules do have a practical purpose, this article is trying to argue that purpose from a standpoint of “coding is hard, and maintaining code is harder, so here’s a shortcut” which isn’t the way to win the hearts and minds of CSS Experts.
I do enjoy a thought-provoking discussion though, so good article in that respect.
@Kevin Powell, the problem we are facing today are not the same of 20 years ago. Now the web is used to build web app, hybrid app and even desktop app. That is the problem of CSS. Right now we need to solve CSS at scale. JavaScript has evolved during this year to solve his scalability problem, now it is time CSS do the same.
Even for really large websites and web-apps in large front-end teams I never had a problem with scalability of CSS (or how people tend to say: “CSS at scale”). It’s more effort and requires much more discipline to write re-usable, modular code that is small in large teams, but that is the job for a person who writes CSS.
There is one exception where you are right though, Matteo, which is “Desktop-Apps”. In this scenario, where we talk about a Desktop app that does not need to download CSS via network, filesize isn’t that critical anymore. But on the other hand, you also don’t want a bloated, slow app (I’m not saying “CSS Modules” are slow, this depends entirely on how it’s used). If you have real-world experience of where CSS at scale sucks, tell me. I haven’t found much besides the need for element queries for my modules (which would be really useful but overall is no requirement to make it work).
Hey Team,
This is a strong discussion – proof to me that this is worth talking about.
This would be a good time to practice not thinking dogmatically and remember the web is a big place with lots of ways to do things (sometimes the same things).
Indeed.
I remember the negativity surrounding Angular when people realised it involved putting javascript in HTML attributes (not to mention some of us using non standard HTML tags). Lots of people said that CSS preprocessors would never take off too. Angular and SASS seem to have done fairly well for themselves though, and I can’t imagine going back to not using them.
Having said all that, I’m not personally a fan of this as I think it’s ugly and involves too many compromises. I do think it’s needed though and I think a better solution will come, even if we have to wait for the WC3/browser vendors to come up with a proper CSS modules spec.
Thanks for the clear explanations Robin, +1 to this.
A few remarks about the concept, NOT the article or Robin:
The concept of CSS Modules: 110% absolutely valid.
Implementation of CSS Modules: Complete disaster.
Gotta love this:
class="_type__display_0980340 _type__serif_404840"
“BEM not required” – BEM is never required :)
Moving CSS into JavaScript will only keep fragmenting web design and development professionals.
Is solving this “global scope in CSS” issue really THAT important? Actually, is it even an issue?
Isn’t “compose” a property rather than a keyword?
From the other comments here, especially by Kevin Powell, it seems like CSS modules are simply removing the powerful global scope of CSS (the reason it was created) to solve an issue that people have – not having organized code, not following best practices. Of course our world isn’t perfect and so neither is our coding, but I think this adds in a huge level of complication for very little payoff.
I am surprise so many people missed the point of having CSS Modules.
CSS selector are like an API which HTML can use to apply a certain style.
CSS Module is proposing a solution to solving the problem of name collision, encapsulation and better management of style composition.
Clever approach however not needed in all situations.
I’d like to raise a point that I haven’t seen in the comments as of yet.
My biggest concern other than adding overall complexity is the weight of the final web pages. Although this may not be a terribly big issue for smaller website with little content, it certainly can be for Single Page Applications where content is being requested dynamically and constantly (e.g. Twitter, Facebook) as you are fetching that data from the server with every request. (Smaller is better?)
Each character in the class attribute is going to be roughly equal to 1 byte (UTF-8) assuming the character is within the ASCII range and the amount of characters generated using this method has the potential of at least doubling, if not more. Depending on how you structure your website and how often you intend to use classes, the weight of the page will certainly increase along with it. This is especially concerning when regarding mobile devices as you generally don’t want to needlessly use up the users’ data.
I’ll be keeping an eye out for the following articles as I’d like to see where this goes. I might simply be biased due to lack of understanding. Just as a picture is worth a thousand words, so too would a practical example be.
So the size of the classes aren’t generally a concern, especially since you should probably be Gzipping everything which is far more important and beneficial. That said, the actual class names are completely you up to you. You can specify the format, or even obfuscate them (
.my-semantic-class
->.A
) if you choose. You can read more on the Github pages for CSS modules and PostCSS-Modules.I kinda geek out over saving a few bytes here and there, so I made a tool called SweatMap that works really well with CSS Modules and allows me to do the obfuscation I mentioned above.
Yeah, there might be potential. But with such silly examples it’s HARD to become a believer any time soon.
I think there’s a “not” missing in the title.
Wait, what about other selectors, like
:nth-child(x)
or[foo=bar]
? What about sibling selectors? What about nesting (e.g..no-js .foo {}
)?To me, there’s no need for CSS here. These aren’t “CSS modules”. Might as well just call them “SDL modules” – “Style Definition Language modules”:
I have worked with this inside a React app. It is definitely interesting and always good to try new stuff. But what I didn’t like is that you had to write plain HTML inside the JS files. Also, it is not possible to use HAML afaik which is a big dealbreaker for me (indented syntax FTW). Afaik SASS syntax is not supported, so you can’t use SASS mixins. But overall i find the strength of CSS that you can write reusable styles that can be used by any element inside the application. This approach doesn’t promote this. Furthermore I didn’t like that CSS is scattered all over the project, instead of all in one place. This might have some benefits to some people but i didn’t like it (opinion). Not a fan of those awful long random classnames either. Makes it very hard to debug.
To solve the problem of conflicting classnames, i think using proper architecture and following best practices (combined with a method like BEM) is a better choice.
Hi! I just wanted to know with theme for DevTools are you using.
Oh no, yet more complexity in simple HTML/CSS. It seems to me CSS modules are to create organised css styles because the developer is sloppy. I think the focus should be making devs write organised code, and stop relying on things like this to organise it for them. Also, with so many different ways of doing things, its a nightmare when someone takes over a web project that is not familiar in the dev tools used.
Will seeing “_styles__title_309571057” in Chrome Inspector help me debug any issues?
LOL.
That’s not a bug, it’s a feature. Cascading Stylesheets, anyone?
Stop fighting! Learn to ♥ the cascade.
I guess selectors like “:root” won’t work (same goes for googles’ polymer, for example)
Trust me, this will make more sense once you start using React. Check out React Starter Kit for those who want to know what I’m talking about.
This is an interesting, if esoteric trick. It’s fine for small dirty hacks, but for someone who can organise and code CSS properly it seems, well, a quaint method. All it is good for is fixing bad html structure – by making it more complicated. Especially with SASS etc. and predecessors, this method is almost self-redundant.
And, what if there’s no JS – the whole thing breaks anyway :-)
What Jason Knight ^^^ said ;-)
Appears the end goal of this article series, is how to work within React. Maybe changing the title to “What are CSS Modules and why do we need them for React” would be a good idea? The current title sure tends to fall on the dogmatic approach…
Agree!
If you have ever worked on an enterprise application with pieces being used and custom styled by hundreds of vendors you’ll understand how great this is.
This ^. The added value of CSS Modules is proportional to the size of the codebase and number of people involved.
…then the article needs to be renamed, “What are CSS Modules and why do we need them in an Enterprise App?”. Right tool and technique for the job is so applicable in this situation. As the majority of comments attest, this is just not a practical way to leverage the global power of CSS (as Kim Joy Fox/Kevin Powell pointed out).
Absolutely agree with the right tool for the job mantra. The problem is that the global power of CSS just starts to be a big burden more than a benefit at a certain scale.
CSS modules
The benefits: namespacing. Very useful, but easily remedied by standard best practices of decedent selectors, nesting in a preprocessor, or manual naming convention scheme if you prefer (BEM, etc.). Efforts would be better spent getting namespacing added to the CSS spec!
The costs: greatly increased complexity, poor rendering performance (only native css is applied before javascript), css bloat from repeated css properties across modules that were previously global.
First of all, I’m not against change. On the contrary, I use and embrace many of the new tools and patterns including Js as a view engine (like React), immutable data, transpiling, preprocessing, build tools, etc. I’ve thought objectively about css modules, but in the end I think it a terrible mistake and hope it doesn’t take off very far.
I can guarantee that the biggest reason this is being pushed on the web development world is so computer science majors who’ve barely glossed over front end concerns, can jump into the front end with as little css knowledge as possible. Think about it. This is coming down to us thanks to the hiring/team makeup decisions of HR/finance departments of major corporations. Have you noticed? Recently over the last few years, they have slowly replaced people who were really GOOD at html/css (though attrition or otherwise) with those who are software engineers. They’ve achieved this by a) using tools that abstract away need for deeper html/css knowledge like Bootstrap or 3rd party themes and b) because of the responsive revolution, current trends in UI/UX are dumbed down and require less specialized knowledge. These are the engineers who are writing articles like this and who are mainly evangelizing it.
I’m not saying there’s anything wrong with these guys. But many of them don’t deeply understand that what is good for application logic isn’t always in the best interest of the way design works. For one thing, design benefits from an uncluttered scaffold. The more technicality and boilerplate in the way, the more the brain has to process. Personally, and I think I speak for others, while I can understand and work with extra structure and many times see its merit, it can also gum up the creative process to the point that the added efficiency is at or past the point of diminishing returns.
Software engineers are taught that global namespace is an evil, as a mantra, from day 1. This is generally true with programming languages… not only because of collisions with your own and 3rd party code, but in Javascript with the core global object. But in CSS the concerns are different than a programming language. Inhertance by default is not a bad thing, because so much inheritance is needed. Design is brand. Brand needs to be uniform, and therefor the cascade is your friend, not your enemy.
That said, of course we need protection from name collisions in css so why not build it right into CSS? Aside from the ability to tame descendant selectors, I also embrace the idea of web components that are protected from the cascade. But the difference is as someone who regularly builds complex user interfaces of large applications from pure white pages ;-) , I believe a global first in CSS is the right approach. Pushing on to people that global is actually bad in CSS will do more harm than good and I guarantee will result in a lot of ruined branding… (i.e. an H1 that’s 30px on one “component” but 32 on another, etc. etc.)