asharpharp
asharpharp

Reputation: 169

React - Override all previous clashing styles when adding a new class

I have seen a lot of threads on the topic, but nothing seems to work for me the way I want it. I have a React component which takes in className as a prop. I also have a HOC which takes in a component and default style, and returns a component which takes in a new style, as such:

function withCombinedStyles(WrappedComponent, defaultClassName) {
    return ({className: newClassName, ...rest}) => {
        const className = combineClassNames(newClassName, defaultClassName);

        return <WrappedComponent className={className} {...rest} />;
    };
};

Currently, combineClassNames just concatenates the strings. I want to make it so that the newClassName always overrides the clashing styles with the defaultClassName but keeps the old ones. Currently, one of the styles seems to override the other but without apparent order - it doesn't matter how I put defaultClassName and newClassName. How can I do that? Currently, I use CSS modules but the project is still small enough for me to be able to rewrite the styles with another technology if that would achieve the desired result and CSS modules cannot do that (though I would prefer to use CSS modules and a React-specific solution with them would work since).

I would use !important but that would mean that I can never add a third className and it could be challenging to extend the styling in the future.

Upvotes: 0

Views: 1325

Answers (1)

t0mgerman
t0mgerman

Reputation: 184

If you were doing CSS in JS then the order would matter, but because you're just combining CSS class names what really matters is specificity. Say newClassName has declarations that are less specific than the ones in defaultClassName - then the more specific declarations in defaultClassName will win over. You can probably fix your CSS by just ensuring the statements you want to 'win' are more specific.

Check out calculators like this one

If you went with inline CSS-in-JS styles I think something like this might work:

function withCombinedStyles(WrappedComponent, defaultStyles) {
    return ({styles: newStyles, ...rest}) => {
        return <WrappedComponent style={{...defaultStyles, ...newStyles}} {...rest} />;
    };
};

Upvotes: 1

Related Questions