Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pass CSS classes to React children and ensure they will override the child’s local class?

I have a <Parent /> component with a single <Child />:

<Parent>
    <Child />
</Parent>

I want to pass a CSS class from the parent into the <Child />, so I do this:

<Parent>
    <Child className={ styles.pill } />
</Parent>

The <Child /> has a className prop and applies the class using the classnames package, like this:

<div className={ classNames(styles.pill, props.className) } />

But you see the <Child /> has a class called styles.pill with these styles:

.pill {
    align-content: stretch;
    align-items: center;
    color: var(--grey__text--dark);
    cursor: pointer;
    display: flex;
    flex-flow: row nowrap;
    justify-content: flex-start;
}

The class the parent passed in contains these styles:

.pill {
    align-items: flex-end;
    flex-flow: column wrap;
}

With this setup I can’t guarantee that the styles passed in from the parent will override the styles within the <Child /> component, which is exactly what I want them to do. Currently you never know which will trump the other. It’s seemingly random with every build of the project.

How can I ensure that the CSS properties in class passed in from the parent override any similar properties in the Child component?

like image 403
Brandon Durham Avatar asked Sep 15 '17 15:09

Brandon Durham


People also ask

How to use CSS child selectors in react material UI?

To use CSS child selectors in React Material UI, we can start the property names of the style properties with &.

How do I select all children of a component in CSS?

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:

What can’t we easily do anymore in CSS modules?

But sooner or later, you would realize there is one thing we cannot easily do anymore in CSS modules – a rather important (if not fundamental) thing in CSS: selecting and overwriting the styles of the (deep nested) child component that’s in a different module from the parent.

How do I add a class to a child component?

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: 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.


2 Answers

It is a matter of CSS specificity, there are many ways to insure the override.

  1. Multiple selector trick, in order to enlarge the specificity you can double the selector size by duplicating the class name, in you case, .pill.pill { ...} will be more specific than the original, and therefore will override the style.

  2. Usage of !important, you can specify that in the class of the parent, .pill's declaration will contain !important at the end.

  3. Multiple different selectors, the parent will pass additional different className, that child component will address, .pill.parent-pill {...}, the parent will pass the .parent-pill class to the child.

Those are just 3 easy ways to override the child styles there are more.

like image 69
felixmosh Avatar answered Oct 16 '22 10:10

felixmosh


You can use Object.assign to merge one/many objects into a target object, giving precedence to each subsequent object:

const foo = { a: '1', b: '2' }
const bar = { a: '3' }
console.log(Object.assign(foo, bar));
like image 26
shabs Avatar answered Oct 16 '22 10:10

shabs