<h1>h1: Almost before we knew it, we had left the ground.</h1>
<h2>h2: Almost before we knew it, we had left the ground.</h2>
<h3>h3: Almost before we knew it, we had left the ground.</h3>
<h4>h4: Almost before we knew it, we had left the ground.</h4>
// Learn more about what's going on here:
// @link https://moderncss.dev/generating-font-size-css-rules-and-creating-a-fluid-type-scale/
// Select a ratio to preview
// Default is "perfectFourth"
$type-ratios: (
"minorSecond": 1.067,
"majorSecond": 1.125,
"minorThird": 1.2,
"majorThird": 1.25,
"perfectFourth": 1.333,
"augmentedFourth": 1.414,
"perfectFifth": 1.5,
"goldenRatio": 1.618
);
@function type-ratio($key) {
@return map-get($type-ratios, $key);
}
// Recommended
$type-base-size: 1rem;
// Select by key of map, or use a custom value
$type-size-ratio: type-ratio("perfectFourth");
// List in descending order to prevent extra sort function
// Limited to high-touch heading styles
$type-levels: 4, 3, 2, 1;
// Create map with h[x] as key
// and computed font-size as value
$type-styles: ();
$level-size: $type-base-size;
@each $level in $type-levels {
$level-size: $level-size * $type-size-ratio;
$type-styles: map-merge($type-styles, (#{"h"}$level: $level-size));
// Output heading styles
// Assign to element and create utility class
h#{$level},
.h#{$level} {
// Fallback for browsers that don't support min / max
font-size: $level-size;
// Recommendation courtesy of this brilliant work:
// @link https://kittygiraudel.com/2020/05/18/using-calc-to-figure-out-optimal-line-height/
line-height: calc(2px + 2ex + 2px);
// Set with `em` to be relative to current `font-size`
margin-bottom: 0.65em;
// Limit in place based on testing -> smaller ratios are
// prematurely or unnecessarily reduced
@if ($type-size-ratio > 1.2) {
// Fluid type styles
// Remove unit for calculations
$level-unitless: $level-size / ($level-size * 0 + 1);
// Set minimum size to a percentage less than $level-size
// Reduction is greater for large font sizes (> 4rem) to help
// prevent overflow due to font-size on mobile devices
$fluid-reduction: if($level-size > 4, 0.5, 0.33);
$fluid-min: $level-unitless - ($fluid-reduction * $level-unitless);
// Prevent dropping lower than 1rem (body font-size)
$fluid-min: if($fluid-min > $type-base-size, $fluid-min, 1);
// Adjust max modifier slightly per level to prevent "same" size
// or lower levels appaering larger than higher levels
// 4vw was selected by testing from $type-ratios map, YMMV 🙃
$fluid-scaler: ($level-unitless - $fluid-min) + 4vw;
font-size: clamp(
#{$fluid-min}rem,
#{$fluid-scaler} + 1rem,
#{$level-size}
);
}
}
}
@function type-style($key) {
@return map-get($type-styles, $key);
}
// Test retrieving heading style value from the map
// @debug "h3:" #{type-style(h3)};
p,
li,
h1,
h2,
h3,
h4 {
// Help prevent overflow of long words/names/URLs
word-break: break-word;
// Optional, not supported for all languages:
hyphens: auto;
// Clear top margin
margin-top: 0;
}
* {
box-sizing: border-box;
}
body {
// Ensure base applied as default for all other elements
font-size: $type-base-size;
font-family: "Merriweather Sans", sans-serif;
line-height: 1.5;
// Demo styles
min-height: 100vh;
display: grid;
place-content: center;
margin: 0 2rem;
color: #333;
}
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.