Fluid Responsive CSS Font Size: Difference between revisions
(26 intermediate revisions by the same user not shown) | |||
Line 2: | Line 2: | ||
== Introduction == | == Introduction == | ||
Making Responsive Websites is not easy. | Making Responsive Websites is not easy. | ||
Many examples are just made for just one part of the problem and seldom on the entire problem. | <br>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. | <br>Let me try to help, by creating this page, which is, of course, at-the-moment under construction. | ||
== Summary == | == 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.'' | {{FormBorder|blue|12px|950px|''Embracing fluid typography might be easier than you think.<br>It has wide browser support, is simple to implement and can be achieved without losing control over many important aspects of design.''}} | ||
{{ | {{FormBorder|black|10px|550px| ''Source: Smashing Magazine, 2016, Fluid Typography'' <ref>[https://www.smashingmagazine.com/2016/05/fluid-typography Smashing Magazine, 2016] Fluid Typography, an article by Michael Riethmuller.</ref>}} | ||
== Viewport == | == Viewport == | ||
Line 28: | Line 28: | ||
## Result in (not your real viewport, just an example): | ## Result in (not your real viewport, just an example): | ||
Viewport vh x vh : 836px x 1638px | Viewport vh x vh : 836px x 1638px | ||
</pre> | |||
|} | |} | ||
<br> | <br> | ||
Line 47: | Line 48: | ||
| Larger value of the viewport’s width and height | | Larger value of the viewport’s width and height | ||
|} | |} | ||
<br> | |||
{| class="wikitableharm" width="1450px" | |||
|- | |||
! width="35%" | Text | |||
! width="65%" | Code Javascript + jQuery | |||
|- style="vertical-align:top;" | |||
| | |||
Easiest way to start fluid typography is to set the {{FormFCTW|8|blue|bold|font-size}} on an {{FormFCTW|8|blue|bold|html}} element. | |||
<br> | |||
The root element is set to {{FormFCTW|8|blue|bold|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. | |||
| | |||
<pre> | |||
html { font-size: 2vw; } | |||
</pre> | |||
|- style="vertical-align:top;" | |||
| 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 {{FormFCTW|8|blue|bold|precise control over the rate of scale}}; | |||
* We don’t have {{FormFCTW|8|blue|bold|min}} or {{FormFCTW|8|blue|bold|max}} font sizes; | |||
* Just like pixels, a {{FormFCTW|8|blue|bold|declaration}} might override the user’s font-size preferences. | |||
Luckily, there are ways to overcome all of these limitations. | |||
| | |||
<pre> | |||
h1 { font-size: 2em; } | |||
</pre> | |||
|} | |||
== CSS for Fluid == | |||
{| class="wikitableharm" width="1450px" | |||
|- | |||
! width="35%" | Text | |||
! width="65%" | Code Javascript + jQuery | |||
|- style="vertical-align:top;" | |||
| | |||
A {{FormFCTW|8|blue|bold|minimum font size}} property is missing in CSS, but there is workaround using the CSS {{FormFCTW|8|blue|bold|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. | |||
| | |||
<pre> | |||
html { font-size: calc(1em + 1vw); } | |||
</pre> | |||
|- style="vertical-align:top;" | |||
| | |||
We can handle this using {{FormFCTW|8|blue|bold|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. | |||
| | |||
<pre> | |||
@media screen and (min-width: 50em) { | |||
html { | |||
font-size: 2vw; | |||
} | |||
} | |||
</pre> | |||
|- style="vertical-align:top;" | |||
| | |||
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. | |||
| | |||
<pre> | |||
@media screen and (min-width: 75em) { | |||
html { | |||
font-size: 1.5em; | |||
} | |||
} | |||
</pre> | |||
|- style="vertical-align:top;" | |||
| | |||
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. | |||
| | |||
{| class="wikitableharmcenter" width="550px" | |||
|- | |||
! | |||
! 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 == | |||
{| class="wikitableharm" width="1450px" | |||
|- | |||
! width="35%" | Text | |||
! width="65%" | 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, {{FormFCTW|8|blue|bold|not choosing}} them. | |||
How do we get around these limitations? The answer is to use {{FormFCTW|8|blue|bold|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. | |||
| | |||
[[File:Fluid-CSS-with-Calc.png|thumb|450px|left|Fluid Responsive design using CSS calc().]] | |||
|- style="vertical-align:top;" | |||
| | |||
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''. | |||
<br>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. | |||
<br>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. | |||
<br>Though the calculation looks slightly complex, it is fairly simple. | |||
<br>Choose the minimum and maximum font size and the screen sizes over which the font should scale and then plug them into the equation. | |||
<br>Any unit type can be used, including ems, rems or pixels. | |||
|} | |} | ||
== Controlling the width == | |||
{| class="wikitableharm" width="1450px" | |||
|- | |||
! width="35%" | Text | |||
! width="65%" | Math | |||
|- style="vertical-align:top;" | |||
| Create a CSS-schema for the complete website for the following HTML | |||
<pre> | |||
<html> | |||
<head></head> | |||
<body> | |||
<div class="container"> | |||
<app-header></app-header> | |||
<app-content></app-content> | |||
<app-footer></app-footer> | |||
</div> | |||
</body> | |||
</html> | |||
</pre> | |||
| | |||
<pre> | |||
<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> | |||
</pre> | |||
|} | |} | ||
== Ideal Line Length == | |||
Robert Bringhurst suggest that a comfortable line has around 45 to 70 characters <ref>''The Elements of Typographic Style'' by Robert Bringhurst</ref>. | |||
<br>However, with fluid typography, adjustment at specific breakpoints becomes unnecessary. | |||
<br>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: | |||
# {{FormFCTW|25.632|blue|bold|Modular Scale}} | |||
# {{FormFCTW|22.784|blue|bold|Modular Scale}} | |||
# {{FormFCTW|20.256|blue|bold|Modular Scale}} | |||
# {{FormFCTW|18.000|blue|bold|Modular Scale}} | |||
* See an example on codepen: https://codepen.io/MadeByMike/pen/bEEGvv?editors%3D0100 | |||
== Min, Max and Clamp == | |||
{| class="wikitableharm" width="1450px" | |||
|- | |||
! width="35%" | Text | |||
! width="65%" | Syntax | |||
|- style="vertical-align:top;" | |||
| | |||
Recently, CSS introduced {{FormFCTW|8|blue|bold|min()}} and {{FormFCTW|8|blue|bold|max()}} which are now available in every major browser. | |||
<br>And the wrapper {{FormFCTW|8|blue|bold|clamp()}} for the combination of the two aforementioned functions, {{FormFCTW|8|blue|bold|clamp(MIN, VAL, MAX)}}. | |||
Note that using {{FormFCTW|8|blue|bold|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. | |||
<br>It has the same effect as the code in Fluid Typography but in one line, and without the use of media queries. | |||
| | |||
<pre> | |||
/* 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); | |||
</pre> | |||
|} | |||
* [https://developer.mozilla.org/en-US/docs/Web/CSS/clamp Developer Mozilla], clamp(). | |||
* [https://css-tricks.com/snippets/css/fluid-typography CSS-Tricks], Fluid Typography. | |||
=== Fluid calc() vs clamp() === | |||
As you can see in the function signatures the {{FormFCTW|8|blue|bold|clamp()}} that | |||
* The viewports minimum and maximum are missing. | |||
So both functions will '''not''' have the same impact. | |||
<br>Choose whatever you want but remind that using {{FormFCTW|8|blue|bold|Sass}} will need adjustments. | |||
== See also == | == See also == | ||
<span class="editsection">[[#content|top]]</span> | <span class="editsection">[[#content|top]]</span> | ||
* [https://trentwalton.com/2011/05/10/fit-to-scale Trent Walton], Fit to Scale | |||
* [https://trentwalton.com/2012/06/19/fluid-type Trent Walton], Fluid Type | |||
* [https://css-tricks.com/viewport-sized-typography CSS-Tricks], Viewport Sized Typography with SASS Maps by Chris Coyier | |||
* [https://www.smashingmagazine.com/2015/06/responsive-typography-with-sass-maps Smashing Magazine 2015/6], Responsive Typography by Jonathan Suh | |||
* [https://www.smashingmagazine.com/2015/05/benton-modern-typography-case-study Smashing Magazine 2015/5], Benton Modern: A Case Study on Art-Directed Responsive Web Typography by Marko Dugonjić. | |||
* [https://www.elliotjaystocks.com/blog/responsive-web-typography Elliot Jay Stocks], Advanced Web Typography: Responsive Web Typography by Elliot Jay Stocks. | |||
* [https://chriskirknielsen.com/blog/modern-fluid-typography-with-clamp Chris Knielsen Blog], Modern Fluid Typography with Clamp. | |||
* [https://www.madebymike.com.au/writing/fluid-type-calc-examples Made by Mike], Fluid Typography Examples ({{FormFCTW|9|blue|bold|''Tip''}}). | |||
== Reference == | == Reference == |
Latest revision as of 17:54, 27 August 2023
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.
|
## 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.
|
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 :
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. |
|
Controlling the rate of Scale
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:
- Modular Scale
- Modular Scale
- Modular Scale
- Modular Scale
- See an example on codepen: https://codepen.io/MadeByMike/pen/bEEGvv?editors%3D0100
Min, Max and Clamp
Text | Syntax |
---|---|
Recently, CSS introduced min() and max() which are now available in every major browser.
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.
|
/* 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); |
- Developer Mozilla, clamp().
- CSS-Tricks, Fluid Typography.
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
- Trent Walton, Fit to Scale
- Trent Walton, Fluid Type
- CSS-Tricks, Viewport Sized Typography with SASS Maps by Chris Coyier
- Smashing Magazine 2015/6, Responsive Typography by Jonathan Suh
- Smashing Magazine 2015/5, Benton Modern: A Case Study on Art-Directed Responsive Web Typography by Marko Dugonjić.
- Elliot Jay Stocks, Advanced Web Typography: Responsive Web Typography by Elliot Jay Stocks.
- Chris Knielsen Blog, Modern Fluid Typography with Clamp.
- Made by Mike, Fluid Typography Examples (Tip).
Reference
- ↑ Smashing Magazine, 2016 Fluid Typography, an article by Michael Riethmuller.
- ↑ The Elements of Typographic Style by Robert Bringhurst