twind
twind copied to clipboard
[Feature]: generate px instead of rem for tailwind classes
Describe the problem
I'm using twind.style to inject tailwind styles into shadow dom for a chrome extension that runs on different sites. The issue is rem is calculated based on the base font size set of html
element and this varies from site to site. Because of this the default font-size is different on different sites. Is there a way to get CSS output as px instead of rem units? This should make the shadow dom UI consistent across sites
Describe the proposed solution
ability to get px instead of rem for tailwind classes.
Alternatives considered
No response
Importance
would make my life easier
Additional Information
No response
there's this postcss lib that converts rem to px but it seems like it is not compatible with twind https://github.com/TheDutchCoder/postcss-rem-to-px
You can transform the generated CSS using the finalize(rule)
config option:
const config = {
finalize(rule) {
return {
...rule,
// d: the CSS declaration body
// Based on https://github.com/TheDutchCoder/postcss-rem-to-px/blob/main/index.js
d: rule.d.replace(/"[^"]+"|'[^']+'|url\([^)]+\)|(-?\d*\.?\d+)rem/g, (match, p1) => {
if (p1 === undefined) return match
return `${p1 * 16}${p1 == 0 ? '' : unit}`
}),
}
}
})
This could be packaged as preset:
export default presetRemToPx({baseValue = 16} = {}) {
return {
finalize(rule) {
return {
...rule,
// d: the CSS declaration body
// Based on https://github.com/TheDutchCoder/postcss-rem-to-px/blob/main/index.js
d: rule.d.replace(/"[^"]+"|'[^']+'|url\([^)]+\)|(-?\d*\.?\d+)rem/g, (match, p1) => {
if (p1 === undefined) return match
return `${p1 * baseValue}${p1 == 0 ? '' : unit}`
}),
}
}
}
}
And then:
export default defineConfig({
presets: [presetRemToPx()],
})
@sastan thank you so much, that worked!
this worked for me.
twind.config.js
import { defineConfig } from "@twind/core";
import presetAutoprefix from "@twind/preset-autoprefix";
import presetTailwind from "@twind/preset-tailwind";
const presetRemToPx = ({ baseValue = 16 } = {}) => {
return {
finalize(rule) {
return {
...rule,
d: rule.d?.replace(
/"[^"]+"|'[^']+'|url\([^)]+\)|(-?\d*\.?\d+)rem/g,
(match, p1) => {
if (p1 === undefined) return match;
return `${p1 * baseValue}${p1 == 0 ? "" : "px"}`;
}
),
};
},
};
};
export default defineConfig({
presets: [presetAutoprefix(), presetTailwind(), presetRemToPx()],
});
where does finalize come from?
You can transform the generated CSS using the
finalize(rule)
config option:const config = { finalize(rule) { return { ...rule, // d: the CSS declaration body // Based on https://github.com/TheDutchCoder/postcss-rem-to-px/blob/main/index.js d: rule.d.replace(/"[^"]+"|'[^']+'|url\([^)]+\)|(-?\d*\.?\d+)rem/g, (match, p1) => { if (p1 === undefined) return match return `${p1 * 16}${p1 == 0 ? '' : unit}` }), } } })
This could be packaged as preset:
export default presetRemToPx({baseValue = 16} = {}) { return { finalize(rule) { return { ...rule, // d: the CSS declaration body // Based on https://github.com/TheDutchCoder/postcss-rem-to-px/blob/main/index.js d: rule.d.replace(/"[^"]+"|'[^']+'|url\([^)]+\)|(-?\d*\.?\d+)rem/g, (match, p1) => { if (p1 === undefined) return match return `${p1 * baseValue}${p1 == 0 ? '' : unit}` }), } } } }
And then:
export default defineConfig({ presets: [presetRemToPx()], })
Hey! Thanks so much. I get "rule" is undefined when i try to use this. not sure where rule or finalize come from. Thanks!