Reputation: 22663
Let's say I'm having the following component in React:
import classNames from 'classnames';
import style from './Cat.module.scss';
export default function Cat({ src, alt, bio, disclaimer, className }) {
return (
<div className={classNames(
style.container,
className,
)}>
<img
src={src}
alt={alt}
/>
<p className={style.bio}>
{bio}
</p>
<p className={style.disclaimer}>
{disclaimer}
</p>
</div>
);
};
Now, let's use this Cat
component on a page component:
import style from './GarfieldPage.module.scss';
export default function GarfieldPage() {
return (
<>
<h1>This is my cat!</h1>
<Cat
src="garfield.png"
alt="Garfield"
bio="The best cat ever!"
disclaimer="Loves lasagna"
className={style.garfield}
/>
</>
);
};
I'd like to apply some custom styling to, let's say, bio. There are several ways to do it, in order I personally find them friendly:
data-
attributes to mark elements for easier access, so in my Cat
component it would become:<p className={style.bio} data-bio>
Then in my page component's styles:
.garfield [data-bio] {
color: purple;
}
Importing class names from other SCSS module. This could be the most "correct" way to do it, but sounds like a lot of imports.
Allowing class names as props for each element:
export default function Cat({
src,
alt,
bio,
disclaimer,
className,
bioClassName,
disclaimerClassName,
}) {
return (
<div className={classNames(
style.container,
className,
)}>
<img
src={src}
alt={alt}
/>
<p className={classNames(
style.bio,
bioClassName,
)}>
{bio}
</p>
<p className={classNames(
style.disclaimer,
disclaimerClassName,
)}>
{disclaimer}
</p>
</div>
);
};
Sounds like a prop hell, especially when component is large.
.garfield [class~=bio] {
color: purple;
}
I don't like that one, because there could be a name clash.
.garfield p:last-child {
color: purple;
}
Assuming that component wouldn't change their tree sounds like a bad idea.
Is there any recognized pattern to style children elements in a module? Did I miss a better way to do it?
Upvotes: 2
Views: 3338
Reputation: 1984
You can also use :global
.
You would do something like this:
.garfield :global(.bio) {
color: purple;
}
A working demo.
I can't say it's better than the approaches you mentioned, it depends on the situation really. :global
is especially useful when you want to override a component style that comes from a package when it doesn't let you to do so via props.
Upvotes: 6