Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS Modules - referencing classes from other modules

I have understood the concept of CSS modules so much that I am convinced that I do not want to do anything else that that for the future.

Currently I am trying to refactor an existing app to use CSS modules, the app has used classic sass with BEM methodology since.

Before I describe my problem I want to make clear that I undestand that I am addressing an issue that is not really within the domain of CSS modules. One should apply styles solely for usage inside a single module. At the most one should compose CSS classes with other CSS classes of other modules. But basically: You build an (HTML-)module and you use CSS modules to style that module and that's that.

Here's the problem: In the process of refactoring there is one single issue that derives from having had a SASS-based style system. I can't find a valid method to work with a CSS class within a CSS modules environment when this class should work in combination of another class from another module.

Example in SASS:

[page.scss]

.wrapper {
    margin: 0;
}

[headline.scss]

.headline {
    color: green;
}
.wrapper {
    .headline {
        color: orange;
    }
}

As you can see: One module (page) defines a CSS class "wrapper", another module defines a CSS class "headline". And, additionally, the class "headline" should behave a bit differently when placed inside the class "wrapper".

Again, I know that this is not really the domain of CSS modules. But I really would like to know if this is somehow doable with CSS modules? The "composes"-feature of CSS modules does not really fit here...

like image 803
hurrtz Avatar asked Mar 03 '17 20:03

hurrtz


People also ask

Can you use SCSS with CSS modules?

Next.js allows you to import Sass using both the .scss and .sass extensions. You can use component-level Sass via CSS Modules and the .module.scss or .module.sass extension.

Are CSS modules scoped?

A CSS Module is a CSS file in which all class names and animation names are scoped locally by default. CSS Modules let you write styles in CSS files but consume them as JavaScript objects for additional processing and safety.

What is the difference between .CSS and module CSS?

Any valid . css file can be a CSS module. The difference is that the style definitions in that file are scoped to specific components instead of globally. The composes property is used in CSS module files to combine local style definitions.


1 Answers

This is a common issue when migrating to CSS Modules. In short, a css module cannot override a style from another css module, and this is by design. Styles are supposed to live with the components that render them, and nowhere else.

What you can do to refactor this is to create a component style variant and explicitly set the variant through a prop when rendered within your wrapper.

For example, suppose your headline component currently looks something like this:

CSS

.headline {
  color: green;
}

JSX

import styles from "Headline.css";
const Headline = () => {
  return (
    <div className={styles.headline} />
  );
}

Rather than trying to override the .headline class name from somewhere else, you can create a variant class name that you toggle through a prop:

CSS

.headline-green {
  color: green;
}

.headline-orange {
  color: orange;
}

JSX

import styles from "Headline.css";
const Headline = ({orange}) => {
  return (
    <div className={orange ? styles.headlineOrange : styles.headlineGreen} />
  );
}

And when you render it from your wrapper, set it to the orange variant:

<Headline orange />

Tip: you can use composes to eliminate duplicate common styles between your variants.

like image 100
Aaron Beall Avatar answered Sep 22 '22 14:09

Aaron Beall