How can I use CSS Modules with Rails 8 and PostCSS?

I would like to be able to link CSS Modules at the layout/partial level in order to build my own components and themes that I can use in different projects.

I still can’t wrap my head around Import Maps, CSSBundling Rails, Propshaft, and JSBundling Rails.

How does it all fit together?

It seems like the official documentation on these is pretty minimal. And all the guides online are all about Tailwind CSS, but I would rather write vanilla CSS and opt into a few features like CSS Modules.

I’m new here so please let me know if this is the wrong place to post this.

Any help would be much appreciated!

To link CSS Modules at the layout/partial level and better understand Rails’ modern asset handling tools, here’s a breakdown:

  1. CSS Modules: Use tools like CSSBundling-Rails to process your CSS (including CSS Modules). It lets you write vanilla CSS while enabling modular scoping.
  2. Import Maps: Handles JavaScript dependencies without a bundler. Import Maps is unrelated to CSS Modules but works well if you’re managing JS for interactive components.
  3. Propshaft: A modern replacement for Sprockets, Propshaft handles asset pipelines in Rails, focusing on simplicity (e.g., direct file serving). Use it for linking assets like CSS/JS.

Thank you for your reply. I managed to install CSSBundling-Rails but I don’t know how to import my classes into my layout or partial. And I can’t seem to find any documentation about it.

I like Importmaps. Can I make PostCSS work with that?

I’m unfamiliar with CSS Modules but from what I can tell they allow you to generate unique CSS classes in JavaScript. Partials/Layouts are not generated by JavaScript, they are just html that gets generated via a Ruby template engine (most often ERB).

So to import css modules into a partial or layout I would use a script tag (or stimulus controller if using stimulus.js) that imported the css module and then applied the module class names to the DOM directly. You’d need to figure out how to map those on your own, such as with a custom data attribute in your html. It looks like postcss-modules generated a JSON map that can help in that mapping process , but you still have to manually apply classes unless you’re using a FE framework such as react or vue that compiles your html from JSX or an equivalent.