Responsive tokens #284
|
I think it's good idea! export const { styled, css } = createStyled({
tokens: {
fontSizes: {
$base: '16px',
large: {
$base: '20px', // It's useful for responsive text (if you use rem)
},
},
space: {
$pagePadding: '16px',
large: {
$pagePadding: '80px',
},
},
},
breakpoints: {
large: (rule) => `@media (min-width: 2200px) { ${rule} }`,
},
});In css :root {
--fontSizes-base: 16px;
}
@media (min-width: 2200px) {
:root {
--fontSizes-base: 20px;
}
}
html {
font-size: var(--fontSizes-base);
}
p {
font-size: 1rem;
} |
Replies: 7 comments 10 replies
|
@shashkovdanil Thanks for raising this. I also think that is also a good idea! We've started to experiment with something similar. /cc @jonathantneal |
|
We currently recommend against using multiple versions of a scale, like responsive tokens, and instead, we suggest putting tokens into a single scale. For example, say we wanted to organize a |
|
Actually ended up with this approach (create variables at
':root': {
$gap: '$space$6',
$gapDouble: 'calc(var(--gap) * 2)',
$gapHalf: 'calc(var(--gap) / 2)',
$gapQuarter: 'calc(var(--gap) / 4)',
$pageMargin: '$space$8',
'@mx3': {
$gap: '$space$4',
$pageMargin: '$space$6',
},
},
space: {
1: '4px',
2: '8px',
3: '12px',
4: '16px',
5: '20px',
6: '24px',
7: '32px',
8: '48px',
9: '64px',
10: '80px',
gap: 'var(--gap)',
gapQuarter: 'var(--gapQuarter)',
gapHalf: 'var(--gapHalf)',
gapDouble: 'var(--gapDouble)',
pageMargin: 'var(--pageMargin)',
}, |
|
Hello, I'm trying to create a Grid component based on the Bootstrap grid system. And so, some columns are styled like this: I believe responsive tokens would be the way to go to achieve this behavior, something like this: export const Column = styled('div', {
position: 'relative',
width: '100%',
minHeight: '1px',
variants: {
sm: {
'@bp1': {
'1': {
flex: '0 0 auto',
maxWidth: '8.3333%',
},
// ... other styles
},
},
md: {
'@bp2': {
'1': {
flex: '0 0 auto',
maxWidth: '8.3333%',
},
// ... other styles
},
},
},
})Is there some way to achieve this without responsive tokens in the meanwhile? |
|
Following @predaytor example I made responsive font-size tokens. export const globalStyles = globalCss({
":root": {
$h1: "4.5rem",
$h2: "2.375rem",
$h3: "1.75rem",
$h4: "1.4",
$body: "0.75rem",
$small: "0.75rem",
"@md": {
$h1: "10.625rem",
$h2: "3.5rem",
$h3: "2.625rem",
$h4: "2rem",
$body: "1rem",
$small: "0.75rem",
},
},
}export const { styled, css, getCssText, globalCss } = createStitches({
theme: {
fontSizes: {
h1: "var(--h1)",
h2: "var(--h2)",
h3: "var(--h3)",
h4: "var(--h4)",
body: "var(--body)",
small: "var(--small)",
},
}
}); |
|
This is much more complicated than other solutions, but just to add another alternative approach: A major goal I was trying to accomplish was easy custom theming, since my UI is used by multiple sites with different fonts. Previous attempts I made were very clunky to override the theme, but this one is quite simple to pick and choose what font sizes you want to override in the theme, as it should be with Stitches. Here is a fairly condensed example of usage that hopefully communicates the idea: // text.ts (separate file for text types and sizes)
export type ThemeTextSizes =
| '01'
| '02'
| '03'
| '04'
| '05'
| '06'
| '07'
| '08'
| '09'
| '10'
| '11'
| '12'
export const pxTextSizes: Record<ThemeTextSizes, number> = {
'01': 12,
'02': 14,
'03': 16,
'04': 18,
'05': 20,
'06': 24,
'07': 28,
'08': 32,
'09': 36,
'10': 40,
'11': 48,
'12': 56,
}
export const textSizes = {
xsMin: pxTextSizes['01'],
xsMax: pxTextSizes['01'],
smMin: pxTextSizes['02'],
smMax: pxTextSizes['02'],
mdMin: pxTextSizes['03'],
mdMax: pxTextSizes['03'],
lgMin: pxTextSizes['05'],
lgMax: pxTextSizes['05'],
xlMin: pxTextSizes['06'],
xlMax: pxTextSizes['06'],
h5Min: pxTextSizes['04'],
h5Max: pxTextSizes['06'],
h4Min: pxTextSizes['05'],
h4Max: pxTextSizes['07'],
h3Min: pxTextSizes['06'],
h3Max: pxTextSizes['08'],
h2Min: pxTextSizes['07'],
h2Max: pxTextSizes['10'],
h1Min: pxTextSizes['08'],
h1Max: pxTextSizes['11'],
}And then in your stitches config you can do something like this: // stitches.config.ts
createStitches({
theme: {
// ...
fontSizes: {
baseRem: 16,
maxBp: breakpoints[breakpoints.length - 1],
...textSizes,
},
// ...
},
utils: {
fz: (size: textTokens): StitchesCSS => {
/**
* clamp() performs a calc() on each of its arguments,
* so there is no need to add a calc() to each of these values.
* Normally this is not valid css without a calc() wrapper.
*/
const min = `$${size}Min / $baseRem * 1rem`
const max = `$${size}Max / $baseRem * 1rem`
const mid = `$${size}Max / $maxBp * 100vw`
/**
* The first fontSize is a fallback for browsers that don't support clamp().
* We are simply falling back to the min value for each text size.
*
* The `@supports` query is simply checking that calculations within clamp
* are also supported. It might be overkill, but that is tough to test.
*/
return {
fontSize: `calc(${min})`,
'@supports (font-size: clamp(12 / 16 * 1rem, 18 / 1024 * 100vw, 2rem))':
{
fontSize: `clamp(${min}, ${mid}, ${max})`,
},
}
},
}Obviously a lot more code, but the usage has been nice, as I can call the util like so: // Text.styles.ts (just as one example)
variants: {
size: {
xs: {
fz: 'xs',
},
sm: {
fz: 'sm',
},
md: {
fz: 'md',
},
lg: {
fz: 'lg',
},
xl: {
fz: 'xl',
},
},
}Now any component that I want to set a font-size for has a very simple rule, with some type safety and hinting, that sets the responsive text styles. |

We currently recommend against using multiple versions of a scale, like responsive tokens, and instead, we suggest putting tokens into a single scale.
For example, say we wanted to organize a
fontSizesfor wider desktop and narrower mobile uses inTextandHeadingcomponents. We would recommend creating a singlefontSizescale, and then creatingTextandHeadingcomponents with immutablesizevariants (at least forText) referencing values fromfontSizes.