How to style child components in React with CSS Modules
Asked Answered
A

2

22

I'm using React with SASS and CSS Modules. How can I style the children component without passing a new ClassName or something like that. For Ex.

I want to position or do some styles over the child components, without having to give a specific class, just like when you do p span just for example, all the spans would be the childrencomponent, and I just want to do some styling referencing all the children component in the parent. But as the class is compiled, I don't know how to reference those children.

//ParentComponent.js
Import Styles from 'ParentComponent.scss';
Import Child from 'ChildComponent';
Import ChildB from 'ChildComponentB';
...
return(
    <div>
        <ChildB />
        <Child />
        <Child />
    </div>
);


//ParentComponent.scss (?)(?)
.child {...}

Here how do I reference the Child components only without passing down a ClassName for example, or without importing the ChildComponent's SASS file in order to get reference to the component class.

//ChildComponent.js
Import Styles from 'ChildComponent.scss';
...
return(
    <div classNames={Styles.child}></div>
);

//ChildComponent.scss
.child {...}
Arcuate answered 7/6, 2018 at 17:20 Comment(0)
S
15

There is multiple approach for this, with and without drawbacks.

Wrap each child in a div

This first one is to wrap each of your child components in a div and then add a class on it which then you can reference in your stylesheet:

return(
    <div>
        <div className={style.child}><ChildB /></div>
        <div className={style.child}><Child /></div>
        <div className={style.child}><Child /></div>
    </div>
);

Pass the className as props

You can pass the class name as props and then add this props to any tag you want in your Child component. On the other hand, you have to do this for every components that you would like to have a class.

return(
    <div>
        <ChildB className={style.child}/>
        <Child className={style.child}/>
        <Child className={style.child}/>
    </div>
);
//ChildComponent.js
Import Styles from 'ChildComponent.scss';
...
export default ({ className }) => 
    <div className={`${Styles.child} ${className}`}></div>

Use the CSS child combinator

In your parent stylesheet, you can use the direct children selector > to select any direct children. You can also combine this operator with the star operator, but be careful with this one since it may slow the browser if used to frequently on a page

If we assume all your Child component is a div:

/* ParentComponent.scss */
.parent > div {
  
}

Or if you don't how of what Child are made of

/* ParentComponent.scss */
.parent > *{
  
}
Simard answered 9/3, 2019 at 21:12 Comment(1)
The approach above doesn't work when the child class names are mangled and you'd like to select specific class on the parent to override its styles, does it?Octavo
H
1

Custom properties (--*): CSS variables could be an option if you have control over those child components.

Firstly, define child style with CSS variables, such as

.some-selector {
  /* '--custom-var-name' is the css variable name, while 'white' is the default value */ 
  background-color: var(--custom-var-name, 'white');
}

Then define --custom-var-name in parent components at any level.

<Parent style={{ '--custom-var-name': 'black' }}>
  <Child />
</Parent>

or

<GrandParent style={{ '--custom-var-name': 'black' }}>
  <Parent>
    <Child />
  </Parent>
</GrandParent>
Highness answered 9/8, 2022 at 2:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.