Open acstll opened 2 years ago
Hm… @acstll clamp
is a CSS
function, you can do many things with it, and "fluid typography" here is a trick. I don't think there should be any declared types for tricks unless we have an official solution. Also it's very specific and work for web only.
Because you use this approach on web, why don't you create a @mixin
for this or a CSS
variables and store it in the web lib. Then you can take design tokens and your mixins and create a file typography.css
where you will sore CSS
classes like header1
, header2
etc. with included mixins, media-queries etc.
In my opinion it better to isolate CSS
logic inside the web UI lib. If you need it in other projects, then just import it.
But if you need to make it as a composite design token, I think "groups" it's what fits better here.
I 100% agree that there needs to be min and max values for fluid typography and spacing.
{
"fluid-dimension-token": {
"$type": "fluid",
"$value": {
"min": "32px",
"max": "48px"
}
}
}
How each platform uses this data is up to the coder (eg. whether using clamp or media queries in CSS). min
can work as the fallback for static design tools that don't allow fluid typography and spacing.
@mikemai2awesome agreed that here could be minmax
type, but fluid
term doesn't fit here. And might be it shouldn't be attached to typography only.
There is another question — how to handle if values more than 2 if we're talking about typography. Many designers prefer to use a specific font-size
for tablets. So, there will be at least desktop
, tablet
and mobile
.
I would rather think about breakpoints
token in this case 🤔
{
"heading-level-1": {
"$type": "typography",
"$value": {
"fontFamily": "Roboto",
"fontSize": "42px",
"fontWeight": "700",
"letterSpacing": "0.1px",
"lineHeight": "1.2"
},
"$extensions": {
"type": "breakpoints",
"values": {
"mobile": {
"fontSize": "32px",
"lineHeight": "1.1"
},
"tablet": {
"fontSize": "32px",
"lineHeight": "1.2"
},
"desktop": {
"fontSize": "42px",
"lineHeight": "1.2"
}
}
}
}
}
@PavelLaptev But that is not fluid design, that's imaginary breakpoint design as a result of the static design tool. There is no such thing as mobile, tablet, and desktop, as the app/website viewport is adjustable across all devices nowadays. Something as opinionated as breakpoints should not be in the spec.
I can agree that the term fluid
might not be best to describe the type, neither is clamp
. That can be workshopped a bit more. However, I don't agree this is typography only. Spacing can be fluid, too.
@PavelLaptev But that is not fluid design, that's imaginary breakpoint design as a result of the static design tool. There is no such thing as mobile, tablet, and desktop, as the app/website viewport is adjustable across all devices nowadays.
Yes, but still even if someone design a website in browser he's creating these average imaginary mobile
, tablet
and desktop
breakpoints, because design for desktops wouldn't work on mobiles — different space, different layouts.
Like @PavelLaptev suggested, it's worth asking: should this be the job of the token parser (and by extension the concern of the token format), or should it be the responsibility of the platform rendering the UI?
Put another way: what if we had tokens like:
{
"type-size-large-fluid-min": {
"$type": "dimension",
"$value": "32px",
},
"type-size-large-fluid-max": {
"$type": "dimension",
"$value": "48px",
},
"type-size-large-fluid-preferred": {
"$type": "dimension",
"$value": "4vw",
},
"type-size-large-fixed": {
"$type": "dimension",
"$value": "40px",
},
}
I could then write the css (assuming my tokens were compiled into custom properties):
h1 {
font-size: var(--type-size-large-fixed);
font-size: clamp(
var(--type-size-large-fluid-min),
var(--type-size-large-fluid-preferred),
var(--type-size-large-fluid-max)
);
}
This saves us from having to write logic into our token parser to understand and decide what the equivalent of clamp()
is in each target context.
100% agreed with @PavelLaptev and @ilikescience here—it doesn't make a lot of sense to me for this to be part of the design tokens spec. It's a "trick" that some web designers use that doesn't really have an analog in design tools or other non-CSS platforms. I think that specifying those values as a set of tokens like in the previous comment makes the most sense.
Since font sizes must be in px
or rem
, that would require alternative units like CSS's vw
to be specified as an $extension
.
{
"type-size-large-fluid-preferred": {
"$type": "dimension",
"$value": "40px",
"$extensions": {
"use-this-instead-if-in-css": "4vw"
}
},
}
What @ilikescience wrote above is too specific to CSS, I am suggesting just the essential min and max values:
{
"type-size-large-fluid-min": {
"$type": "dimension",
"$value": "2rem",
},
"type-size-large-fluid-max": {
"$type": "dimension",
"$value": "4rem",
},
}
Web devs decide what they want to do with those min and max tokens:
h1 {
font-size: clamp(
var(--type-size-large-fluid-min),
var(--type-size-large-fluid-min) * 0.9 + 0.25vw, /* This formula would be situational and completely up to the author. */
var(--type-size-large-fluid-max)
);
}
The formula is the trick part, the concept of min and max is not a trick, and eventually iOS and Android would come up with their own fluid method (with their split screen and overlay features becoming more mainstream). The min and max would be applicable on all platforms by then.
Yes, but still even if someone design a website in browser he's creating these average imaginary mobile, tablet and desktop breakpoints, because design for desktops wouldn't work on mobiles — different space, different layouts.
@PavelLaptev I beg to differ on this. Fluid design would produce different layouts just as breakpoint design can, but fluid would account for every viewport, not just specific breakpoints. Someone designing in the browser nowadays has the technologies to do so, modern CSS is very powerful. By removing hundreds of lines of breakpoint media queries, a website would have much greater performance.
@mikemai2awesome I think that you don't need media-queries
or container-queries
only if you have a simple website or components, I mean a website where you need to hide a menu if there is not enough space and show a burger icon, or if you have three columns layout then you need to use media-queries
so switch e.g. flex-direction: row
to flex-deriction: column-reverse
etc. don't see how relative aka "fluid" units can handle that
@PavelLaptev Your column example is one of the biggest downfalls of breakpoint design. 3 column layout at 1280px viewport looks fine while 3 column layout at 801px viewport looks super awkward. Content is squeezed so much that it becomes hard to read. It is just missing that 1px to shift to a different and better layout. Why utilize such static design approach when the web allows you to be much more dynamic now? A row of content blocks can flow vertically once a block hits a certain width like 25 characters, no media query or container query required. That's 1 line of code vs multiple lines of media queries.
I agree there are certain complex layouts that would require some tricks involving breakpoints still, but breakpoints shouldn't be a core design principle. And this is irrelevant to the fluid typography and spacing tokens we are discussing here, so let's agree to disagree and get back on the main topic.
@acstll any other thoughts or comments based on the feedback provided on this issue?
This dimension token is just what I needed. For context I have been working on utils to generate clamped scales in css and their equivalent px values for a given dartboard size in Figma.
I have been setting a config like this
{
"config": {
"range": [-2, -1, 0, 1, 2, 3, 4],
"sizes": [
{
"$name": "BP1",
"width": 320,
"fontSize": 16,
"typeScale": 1.067
},
{
"$name": "BP2",
"width": 768,
"fontSize": 16,
"typeScale": 1.067
},
{
"$name": "BP4",
"width": 1440,
"fontSize": 20,
"typeScale": 1.067
}
]
},
then referencing it as this, which isn't ideal as fontScale isn't an obvious token.
"Heading 1": {
"$type": "typography",
"$value": {
"fontFamily": "{font.family.heading}",
"fontWeight": "{font.weight.heading.normal}",
"letterSpacing": "0px",
"lineHeight": "{font.lineHeight.heading}",
"fontSize": null,
"fontScale": 4
}
},
But I think with the approaches above something like
{
"typography-scale":{
"$type":"scale",
"$value":{
"min":{
"width":"320px",
"base":"16px",
"ratio":1.067
},
"max":{
"width":"1728px",
"base":"21px",
"ratio":1.414
}
}
}
}
"Heading 1": {
"$type": "typography",
"$value": {
"fontFamily": "{font.family.heading}",
"fontWeight": "{font.weight.heading.normal}",
"letterSpacing": "0px",
"lineHeight": "{font.lineHeight.heading}",
"fontSize": "{{scales.typography-step-4}}",
}
},
The parser can then work out if it needs to render a px, rem, clamp or array of sizes.
It would also be good to have an array as an option for rendering multiple styles for different artboard sizes in Figma (useful when testing out lots of layout permutations) or if someone wanted to target media queries, or native platforms.
{
"typography-scale":{
"$type":"scale",
"$value":[
{
"width":"320px",
"base":"16px",
"ratio":1.067
},
{
"width":"1024px",
"base":"16px",
"ratio":1.067
},
{
"width":"1728px",
"base":"21px",
"ratio":1.414
}
]
}
}
@acstll any other thoughts or comments based on the feedback provided on this issue?
super sorry for the late reply.
I'm happy with @mikemai2awesome solution above https://github.com/design-tokens/community-group/issues/188#issuecomment-1335476072
min
and max
values as tokens with an explicit nameI would also like to point out the "agree to disagree" part as well, which I second a 100%.
I agree there are certain complex layouts that would require some tricks involving breakpoints still, but breakpoints shouldn't be a core design principle. And this is irrelevant to the fluid typography and spacing tokens we are discussing here, so let's agree to disagree and get back on the main topic.
Using CSS's clamp
may look like a trick now, but fluid design isn't, and to me it looks like the future.
@kevinmpowell should we close this one then?
While working on responsiveness and the fluid typography topic we found ourselves wondering whether we should put
clamp(0.64rem, 0.69rem + -0.27vw, 0.5rem)
in a design token. (We would use this for font sizes, but these can be used for spacing as well.)According to the current spec, the dimension type is a string ending with either
px
orrem
.How should we handle this? Has this already been discussed somewhere else?
Many questions arise:
0.69rem + -0.27vw
)?I would imagine something like this: