font-size: 3vw;
means that the font size will be 3% of the viewport width. So when the viewport width is 1200px – the font size will be 3% * 1200px = 36px.
So a max-font-size of 36px can be easily implemented using a single media query to override the default 3vw font-size value.
Codepen demo (Resize Browser)
div { font-size: 3vw; } @media screen and (min-width: 1200px) { div { font-size: 36px; } }
<div>hello</div>
Update: With the new CSS min() function, we can simplify the above code – without using media queries (caniuse)
div { font-size: min(3vw, 36px); }
In the above example, the font-size will be at most 36px, but will decrease to 3vw if the the viewport is less than 1200px wide (where 3vw computes to a value less than 36px )
That being said, using viewport units for font-size
in the above way is problematic because when the viewport width is much smaller – say 320px – then the rendered font size will become 0.03 x 320 = 9.6px which is very (too) small.
In order to overcome this problem, I can recommend using a technique called Fluid Type AKA CSS Locks.
A CSS lock is a specific kind of CSS value calculation where:
- there is a minimum value and a maximum value,
- and two breakpoints (usually based on the viewport width),
- and between those breakpoints, the actual value goes linearly from the minimum to the maximum.
So let’s say we want to apply the above technique such that the minimum font-size is 16px at a viewport width of 600px or less, and will increase linearly until it reaches a maximum of 32px at a viewport width of 1200px.
This can be represented as follows (see this CSS-tricks article for more details):
div { font-size: 16px; } @media screen and (min-width: 600px) { div { font-size: calc(16px + 16 * ((100vw - 600px) / 600)); } } @media screen and (min-width: 1200px) { div { font-size: 32px; } }
Alternatively, we could use this SASS mixin which does all of the math for us so that the CSS would look something like this:
/* 1) Set a min-font-size of 16px when viewport width < 600px 2) Set a max-font-size of 32px when viewport width > 1200px and 3) linearly increase the font-size from 16->32px between a viewport width of 600px-> 1200px */ div { @include fluid-type(font-size, 600px, 1200px, 16px, 32px); }
Update: We can use the new clamp() CSS function (caniuse) to refactor the above code to simply:
div { font-size: clamp(16px, 3vw, 32px); }
see MDN:
clamp() 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.
p { font-size: clamp(1rem, 2.5vw, 1.5rem); } <p> If 2.5vw is less than 1rem, the font-size will be 1rem. If 2.5vw is greater than 1.5rem, the font-size will be 1.5rem. Otherwise, it will be 2.5vw. </p>
—
Further Reading
How Do You Do max-font-size in CSS?