CSS Modules - referencing classes from other modules
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.
Scss module (css modules): importing from other scss files
css-modules is not related to SASS or SCSS and has its own set of supported features and keywords. Yes, they can be used together, which I actually do in most my projects. But I avoid having classname dependencies between different files. I'm aware of some features that could be used to share classnames, but avoiding the need for it is probably the best solution. I will in the following section list all potential solutions to your conundrum I can think of; choose what suits you best:
- Solution #1: Never sharing classnames, co-locating styles that belong together and operate on the same classnames.
In your case this would mean that you only have one scss file relating to buttonsbuttons.modules.scss
and bothButton.js
andButtonGroup.js
import it. - Solution #2: exempt shared classnames from the unique generated name mechanism by marking them as
:global
. This can be done thus:
// button.module.scss
// this will stay a global classname
:global(.button) {
// the button styles
}
// this will be treated as usual, generating a local name
.icon {
// some icon stuff
}
// buttongroup.module.scss
.buttonGroup {
display: flex;
// will be resolved as local classname
&.horizontal {
flex-direction: row;
// will be resolved as global classname
& > :global(.button):not(:first-child) { margin-left: 1rem; }
}
&.vertical {
flex-direction: column;
& > :global(.button):not(:first-child) { margin-top: 1rem; }
}
}
- Solution #3: accept anonymous children. You can omit the classname of the children. no one places non-buttons in a button group (might even enforce it in your component code).
// buttongroup.module.scss
.buttonGroup {
display: flex;
&.horizontal {
flex-direction: row;
& > *:not(:first-child) { margin-left: 1rem; }
}
&.vertical {
flex-direction: column;
& > *:not(:first-child) { margin-top: 1rem; }
}
}
- Solution #4: Reference content from another file. There seems to be some support for a syntax that can reference/import stuff from other files, but I perused the documentation and a few github issue discussions 'import className from fileName' 'more' 'and more' without getting any clear answer as to how one would import a local classname from another file. There might be something possible either along those lines see here:
@import button from './button.module.scss';
.buttonGroup {
display: flex;
&.horizontal {
flex-direction: row;
& > .button:not(:first-child) { margin-left: 1rem; }
}
&.vertical {
flex-direction: column;
& > .button:not(:first-child) { margin-top: 1rem; }
}
}
...or along those lines see here:
:import("./button.module.scss") {
imported-button: button;
}
.buttonGroup {
display: flex;
&.horizontal {
flex-direction: row;
& > .imported-button:not(:first-child) { margin-left: 1rem; }
}
&.vertical {
flex-direction: column;
& > .imported-button:not(:first-child) { margin-top: 1rem; }
}
}
- Solution #5: Have your container component add a class
.button-group-item
to each child and use it to apply the margins instead of the.button
class.
Reference global class names from within a css module
To refer to a globally declared class name inside :local
scoped css modules you should use :global
switch:
.container {
// rules for container
}
.container:global(.pull-right) {
// rules for when the container element also has the pull-right class
}
More detailed explanation in css-modules documentation.
How to access hidden CSS classes from CSS modules in React
You have to use :global
to get not modular styles such as styles for Carousel
https://github.com/css-modules/css-modules#exceptions
Applying style of multiple CSS classes using React CSS Modules
The reason the style wasn't being applied is because I had supplied the css 'active' class as a string value rather than as a reference from the imported CSS module:
import classes from "./RecipeSection.module.css";
Then I could supply the reference:
${classes.active}
The real clue was that in the initial generated html, my active class had not been allocated a hash as the recipe-section class had
<div class="RecipeSection_recipe-section__Asce8 active">
How to reference child class when using SCSS is in CSS modules?
This css code means that you have a markup with a class tableThemeA
which has a child markup tbody
which has a child markup td
which has a child markup with a class colHeader
so to access to this style you must have to follow it inheritance.
.tableThemeA {
tbody {
td {
.colHeader {
...
}
}
}
}
So to refer to this style you must do this:
import styles from './foo.module.scss';
...
<table classsName={styles.tableThemeA}> // class tableThemeA
...
<tbody> // child tbody
<td> // child td
<span className={styles.colHeader}></span> // class colHeader
</td>
</tbody>
</table>
Related Topics
Sass Mixin Error for Ie Specific Filters Like -Ms-Filter
How to Shift a Background Image with CSS
Is Decimal Precision When Specifying a Font-Size Respected by All Browsers
Jquery Mobile Android - Fixed Full-Screen Background Image
CSS Resize Property - Change Resize Icon Properties
Select Element Based on Child Class
What Tag Should I Use Instead of Deprecated Tag Font in HTML (Cannot Use CSS)
Internet Explorer 11 and Supported Web Fonts
How to Vertically Center Elements in Bulma
Is Anyone Experiencing Layout Issues After Upgrading to Chrome 72
CSS Animation, Absolute Position Go Off Screen to Right and Come Back from Left
Fontawesome Does Not Work When Served by Iis
In the CSS Visual Formatting Model, What Does "The Flow of an Element" Mean