You do not need to create a new CSS class to target li
elements, but you do need to have two different CSS rules, whatever the preprocessor you use or in plain CSS.
Keep in mind what you would write in plain CSS:
.some-specific-ul {
margin: 4em;
}
.some-specific-ul > li {
color: grey;
}
What you'd write using vanilla-extract is almost the same. The only difference is that the class name is not hardcoded anymore, but generated somehow. Still, you can use the class name in multiple rules.
import { globalStyle, style } from "@vanilla-extract/css";
export const ul = style({
margin: '4em',
});
globalStyle(`${ul} > li`, {
color: 'grey',
});
In both cases, you only need one class to apply to the ul
element, and li
elements would be automatically styled as well. In the second case, only the ul
class name is exported, and that makes sense: there's no way to force the li
rule, it can only be applied automatically depending on the parent ul
.
Now, keep also in mind that your code may become less maintainable if you abuse of "magically applied rules". As the number of rules and the element hierarchy depth grow, people won't know where the styles are coming from. I believe there's a point beyond which it's worth to explicit the styles you apply. Under the hood it creates CSS classes, but you shouldn't care about that.
Imagine:
import { style } from "@vanilla-extract/css";
export const ul = style({
margin: '4em',
});
export const li = style({
color: 'grey',
});
import * as React from "react";
import * as classNames from "./my-list.css";
export const MyList: React.FC<{ items: string[] }> = ({ items }) => (
<ul className={classNames.ul}>
{items.map(item => (
<li key={item} className={classNames.li}>{item}</li>
)}
</ul>
);
The take-away advice is that your style file will look the same, you'll loose a little time to write additional class names, but you'll gain a lot more time in maintenance.