How to style child components in React with CSS Modules

k3b picture k3b · Jun 7, 2018 · Viewed 8.6k times · Source

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 {...}

Answer

felixyadomi picture felixyadomi · Mar 9, 2019

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 > *{
  
}