Apply multiple font properties with the same name
Description
In tailwindcss@v3 it is possbile to configure fonts in this way:
theme: {
fontFamily: {
sans: ["Inter"]
},
fontSize: {
"label-large": [14, { fontWeight: 500, letterSpacing: 0.5, lineHeight: 20 }]
}
}
Which roughly generates the following:
<p class="text-label-large">Hi</p>
.text-label-large {
font-family: Inter;
font-size: 14px;
font-weight: 500;
letter-spacing: 0.5;
line-height: 20;
}
So I tried to do the same in @master/css@v2 with the following:
variables: {
"font-family": {
test: ["arial", "sans-serif"],
},
"font-weight": {
test: 500,
},
"font-size": {
test: 20,
},
"line-height": {
test: 1.5,
},
}
But due to name collision, only font-weight is applied:
<p class="font:test">Hi</p>
.font\:test {
font-weight: 500;
}
It is possible to achieve the same functionality? This can be really useful to implement material 3 typography scale system
@ceopaludetto This is expected. In Master CSS, we deliberately map certain CSS properties ambiguously to a shared variable namespace in order to simplify the markup. https://github.com/master-co/css/blob/rc/packages/core/src/config/rules.ts#L192-L199
Therefore, if a collision occurs, you should write out the full variable name.
<div class="font-weight:font-weight-test">
However, this is admittedly a somewhat awkward behavior, and we will further evaluate how to improve it.
Alternatively, what we might need is a warning to alert developers when a collision occurs.
I was able to achieve what I want by creating a new rule:
rules: {
typography: {
subkey: "typ",
declare(value) {
if (!this.css.variables.has(`font-size-${value}`))
return {};
return {
"font-family": this.css.variables.get(`font-family-sans`)!.value.toString(),
"font-size": toRem(this.css.variables.get(`font-size-${value}`)!.value),
"font-weight": this.css.variables.get(`font-weight-${value}`)!.value,
"line-height": toRem(this.css.variables.get(`line-height-${value}`)!.value),
"letter-spacing": toRem(this.css.variables.get(`letter-spacing-${value}`)!.value),
};
},
},
},
Then I just use like this:
<p class="typ:test">Hi</p>
Which generates:
.typ\:test{
font-family: ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;
font-size: 1.25rem;
font-weight: 500;
line-height: 1.25rem;
letter-spacing: 0.03125rem;
}
I was able to achieve what I want by creating a new rule:
rules: { typography: { subkey: "typ", declare(value) { if (!this.css.variables.has(
font-size-${value})) return {};return { "font-family": this.css.variables.get(`font-family-sans`)!.value.toString(), "font-size": toRem(this.css.variables.get(`font-size-${value}`)!.value), "font-weight": this.css.variables.get(`font-weight-${value}`)!.value, "line-height": toRem(this.css.variables.get(`line-height-${value}`)!.value), "letter-spacing": toRem(this.css.variables.get(`letter-spacing-${value}`)!.value), }; },}, }, Then I just use like this:
Hi
Which generates:.typ:test{ font-family: ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji; font-size: 1.25rem; font-weight: 500; line-height: 1.25rem; letter-spacing: 0.03125rem; }
Nice! Or you can just use config.components
export default {
components: {
typ: 'font-family:font-family-sans ...'
}
}