Search code examples
htmlcssfont-sizetypographyviewport-units

How can I get fluid typography that gradually change type scale using the max() CSS Function?


I’m a big fan of fluid typography and I want a website I’m developing to adopt it. Recently, I learned about the max() CSS Function. I thought of using it to get fluid typography. In particular, I want the text on webpages to start from a specific type scale and then to adopt a different one. To be concrete, I want the text to use the Minor Third scale on a small starting viewport. When the viewport becomes larger, I want the text to use the Perfect Fifth scale instead. I want to get a result like the one Utopia lets you obtain. There, you specify the two type scales you want to use on different viewports. I want to try to replicate the same effect, but using only the max() Function, since I don’t want to provide a “max viewport”: my text must scale infinitely. So far, I’ve tried using this code:

    <!DOCTYPE html>
    <html>
    <head>
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <style>
          h1   { font-size: max(2.488rem, 11.089vw); }
          h2   { font-size: max(2.074rem, 6.854vw); }    
          h3   { font-size: max(1.728rem, 4.236vw); }
          h4   { font-size: max(1.44rem, 2.618vw); }
          h5   { font-size: max(1.2rem, 1.618vw); }
       </style>
    </head>
    <body>
       <h1>Heading 1</h1>
       <h2>Heading 2</h2>
       <h3>Heading 3</h3>
       <h4>Heading 4</h4>
       <h5>Heading 5</h5>
    </body>
    </html>

What this code does is using the max() Function for every heading, whose first member is the scale defined by the Minor Third scale, while the second one is the scale defined by the Perfect Fifth scale. To see what I’m taking about, try resizing the viewport after running the code snippet above and you’ll see the heading changing scales. I don’t know if this code does exactly what I’m trying to achieve (that is, to switch from a scale to another one), but it seems to. What I want to avoid, however, is the interval that occurs from, for example, the h1 and the h2 elements while they change when resizing the viewport. Specifically, the h1 starts adopting the new scale before the h2 does. This makes sense since the two maximum values calculated are different, but I’d like all my headings to start adopting the new scale at the same time, that is when I resize the viewport.


Solution

  • In the end, I found the best solution was to use something like:

    :root {
     --step6:calc(1.602rem + 5.063vw);
     --step5:calc(1.424rem + 3.375vw);
     --step4:calc(1.266rem + 2.25vw);
     --step3:calc(1.125rem + 1.5vw);
     --step2:calc(1rem + 1vw);
     --step1:calc(0.889rem + 0.667vw);
     --step0:calc(0.79rem + 0.444vw)
    }
    

    I use these CSS variables to specify the sizes of elements and let the text scale indefinitely, without the need to use media queries to specify precise points in which my design should change. I get the effect I was looking for with just the use of these variables. For example, an h1 element can use:

    h1 { font-size:var(--step6) }
    

    and an h2 element:

    h2 { font-size: var(--step5) }
    

    This lets me say: «I provide only the smallest values. When the viewport grows up, I want the sizes to scale indefinitely, using this ratio». Of couse, I use these variables not ony with font sizes, but also with other properties such as margins, paddings, etc.