Scale Typography from Screen Width. With Easing Functions
by Hugo Vale Pereira
HTML
<!--
From: [https://9to5.hfbk.hamburg/] (7 fev 2024)
-->
<div class="blue"></div>
<div class="red"></div>
<h1 id="t1">Title</h1>
<h1 id="t2">Title</h1>
CSS
.blue {
width: 200px;
background: blue;
}
.red {
width: 400px;
background: red;
}
div {
height: 10px;
}
/* 1. Register a property so atan2 works correctly */
@property --100vw {
syntax: "<length>";
initial-value: 0px;
inherits: true;
}
:root {
--100vw: 100vw;
--vw-unitless: tan(atan2(var(--100vw), 1px)); /* This gets a unitless value */
--sm-w: 200;
--bg-w: 400;
--min-f: 16;
--max-f: 64;
/* Normalize progress to 0-1 */
--progress: calc((var(--vw-unitless) - var(--sm-w)) / (var(--bg-w) - var(--sm-w)));
--eased: calc((1 - cos(var(--progress) * 180deg)) / 2);
}
/* ------------------------------------ With Animation approach --- */
/* 4. Define font range */
@keyframes fluid-font {
0% { font-size: 16px; }
100% { font-size: 64px; }
}
#t1 {
animation-name: fluid-font;
animation-duration: 1s;
animation-timing-function: ease-in-out; /* ← your easing here */
animation-fill-mode: both;
animation-play-state: paused;
animation-delay: calc(var(--progress) * -1s);
}
/* ------------------------------------ With Cosine math function approach --- */
/*
This approach would need a media query as well or a function that always have a positive or negative slope. Sin and Cos alternates
*/
#t2 {
/* Apply cosine easing to progress */
font-size: clamp(
calc(var(--min-f) * 1px),
calc((var(--min-f) + (var(--max-f) - var(--min-f)) * var(--eased)) * 1px),
calc(var(--max-f) * 1px)
);
}
JavaScript
let h = document.querySelectorAll('h1');
h.forEach((h1) => {
let size = h1.style.fontSize;
h1.textContent = 'Title ' + window.getComputedStyle(h1).fontSize;
window.addEventListener('resize', () => {
h1.textContent = 'Title ' + window.getComputedStyle(h1).fontSize;
});
});