Fluid Responsive CSS Font Size

From HaFrWiki
Jump to: navigation, search

Introduction

Making Responsive Websites is not easy.
Many examples are just made for just one part of the problem and seldom on the entire problem.
Let me try to help, by creating this page, which is, of course, at-the-moment under construction.

Summary

Embracing fluid typography might be easier than you think.
It has wide browser support, is simple to implement and can be achieved without losing control over many important aspects of design.

Source: Smashing Magazine, 2016, Fluid Typography [1]

Viewport

Text Code Javascript + jQuery

Viewport units making fluid typography on the web possible. Viewport units refer to a percentage of the browser’s viewport dimensions.

For example, 1 viewport width (vw) is equal to 1% of the viewport’s width.
The units differ from percentages because they are always relative to the viewport, whereas a percentage is relative to the element’s parent container.

## What is viewport's height and width using JS
$ console.log( "Viewport vh x vh : " + window.innerHeight + "px x " + window.innerWidth + "px" )

## Result in (not your real viewport, just an example):
Viewport vh x vh : 836px x 1638px


Viewport unit Description
vw Viewport width, equivalent to JS window.innerWidth
vh Viewport height, equivalent to JS window.innerHeight
vmin Smaller value of the viewport’s width and height
vmax Larger value of the viewport’s width and height


Text Code Javascript + jQuery

Easiest way to start fluid typography is to set the font-size on an html element.
The root element is set to 2vw, changing the "root em". Because all em and rem units either directly are or indirectly related to the root em, they will now also be fluid.

html { font-size: 2vw; }
A heading size of 2em is now equivalent to 4vw because this is twice the current font size of 2vw.

Using viewport-relative units alone comes with some drawbacks :

  • We don’t get precise control over the rate of scale;
  • We don’t have min or max font sizes;
  • Just like pixels, a declaration might override the user’s font-size preferences.

Luckily, there are ways to overcome all of these limitations.

 
h1 { font-size: 2em; }

CSS for Fluid

Text Code Javascript + jQuery

A minimum font size property is missing in CSS, but there is workaround using the CSS calc() expression.

A viewport width of 0, the font-size would be exactly 1em. As the screen gets larger, the value of 1vw would be added to the minimum font size of 1em. But this technique is not always ideal; often we want to set a minimum font size at a screen size other than zero.

html { font-size: calc(1em + 1vw); }

We can handle this using media queries In this example, the font size would become fluid once the viewport reaches a width of 50 ems. This works really well, but it usually means a jump between the fixed and fluid values. To eliminate this, we can work out the precise point at which the fluid value matches the fixed value and set a breakpoint at that viewport size.

If the default font size is 16 pixels and if 2vw is 2% of the viewport’s width, then the calculation for working out the breakpoint would be 16 ÷ (2 ÷ 100). This gives us 800 pixels.

@media screen and (min-width: 50em) {
  html {
    font-size: 2vw;
  }
}

The same calculation to work out a maximum font size. If we wanted a maximum font size of 24 pixels, we could calculate like so: 24 ÷ (2 ÷ 100) = 1200px. In ems, that would be: 1.5 ÷ (2 ÷ 100) = 75. Then, above 75 ems, we would reset the font size to a fixed value.

@media screen and (min-width: 75em) {
  html {
    font-size: 1.5em;
  }
}

These calculations are not difficult, but I find that a table helps us to visualize the breakpoints and the rate at which fonts scale with different viewports units. The viewport unit values are across the top, and the device resolutions run down the left side of the table.

Looking at this table, you can see that we have little control over the rate at which the viewport units change. Using viewport units alone, we are limited to the font sizes available in a single column of the table.

  1vw 2vw 3vw 4vw 5vw
400px 4px 8px 12px 16px 20px
500px 5px 10px 15px 20px 25px
600px 6px 12px 18px 24px 30px
700px 7px 14px 21px 28px 35px
800px 8px 16px 24px 32px 40px

Controlling the rate of Scale

Text Math

Assume:

  • Choose a font size of 16 pixels at a screen resolution of 400 pixels
  • Transition to 24 pixels at a resolution of 800 pixels,

Is impossible without a breakpoint. As well, you might have noticed we have been calculating the breakpoints for the minimum and maximum font sizes, not choosing them.

How do we get around these limitations? The answer is to use calc(). Using calc() and viewport units together, we can get advanced fluid typography that scales perfectly between specific pixel values within a specific viewport range. We simply need to create a basic mathematical function.

Fluid Responsive design using CSS calc().

This pure mathematical function takes a value within a range and works out what the new value would be if applied to a different range.
So, if we had the numbers 1 and 100 and a value of 50 and then applied this to a new range between 1 to 200, our new value would be 100.
Both of these values remain right in the middle of the range.

A value of 100vw is the variable in this equation because the resolved value of 100vw changes as the viewport’s size changes.
Though the calculation looks slightly complex, it is fairly simple.
Choose the minimum and maximum font size and the screen sizes over which the font should scale and then plug them into the equation.
Any unit type can be used, including ems, rems or pixels.

Controlling the width

Text Math
Create a CSS-schema for the complete website for the following HTML
<html>
 <head></head>
 <body>
  <div class="container">
   <app-header></app-header>
   <app-content></app-content>
   <app-footer></app-footer>
  </div>
 </body>
</html>
<style>
app-header,
app-content,
app-footer,
.container {
   max-width               : min( 1950px, 95vw ) !important;
   min-width               : min(  400px, 95vw ) !important;
   width                   : 95vw;
}
.container {
   margin-left             : auto;
   margin-right            : auto;
}

</style>

Ideal Line Length

Robert Bringhurst suggest that a comfortable line has around 45 to 70 characters [2].
However, with fluid typography, adjustment at specific breakpoints becomes unnecessary.
Just set the size of the container to scale at the same rate as the font. Use the calc() technique described above on the width property just as easily as we do on font-size.

Modular Scale

A modular scale is a series of numbers that are harmoniously proportional to each other. This is best described visually:

  1. Modular Scale
  2. Modular Scale
  3. Modular Scale
  4. Modular Scale

Min, Max and Clamp

Text Syntax

Recently, CSS introduced min() and max() which are now available in every major browser.
And the wrapper clamp() for the combination of the two aforementioned functions, clamp(MIN, VAL, MAX).

Note that using clamp() for font sizes, as in these examples, allows you to set a font-size that grows with the size of the viewport, but doesn't go below a minimum font-size or above a maximum font-size.
It has the same effect as the code in Fluid Typography but in one line, and without the use of media queries.

/* Static values */
width: clamp(200px, 40%, 400px);
width: clamp(20rem, 30vw, 70rem);
width: clamp(10vw, 20em, 100vw);

/* Calculated values */
width: clamp(min(10vw, 20rem), 300px, max(90vw, 55rem));
width: clamp(100px, calc(30% / 2rem + 10px), 900px);

Fluid calc() vs clamp()

As you can see in the function signatures the clamp() that

  • The viewports minimum and maximum are missing.

So both functions will not have the same impact.
Choose whatever you want but remind that using Sass will need adjustments.

See also

top

Reference

top

  1. Smashing Magazine, 2016 Fluid Typography, an article by Michael Riethmuller.
  2. The Elements of Typographic Style by Robert Bringhurst