JSFiddle - React, Tailwind, and code Playground
HTML
<h3>
Demo: Matching Playfair Display metrics with <span style="color:red">Times New Roman</span>.
</h3>
<div>
Font size: <input type=number value=16 id=fontSizeInput>
</div>
<div>
Width: <input type=number value=800 id=widthInput>
</div>
<div>
Animate <input type=checkbox id=animateCheck>
</div>
<div style="height: 20px"></div>
<div class=container>
<div class=reference></div>
<div class=target></div>
</div>
CSS
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display&display=swap');
@font-face {
font-family: Times New Roman;
/* Playfair Display has 138.496px ascent and 32.128px
* descent and 0 leading at 128px font size.
*/
ascent-override: calc(138.496 / 128 * 100%);
descent-override: calc(32.128 / 128 * 100%);
line-gap-override: 0%;
advance-override: 0.049;
src: local(Times New Roman);
}
.container {
position: relative;
width: calc(var(--w) * 1px);
height: calc(500px * var(--f) * var(--f) / var(--w));
font-size: calc(var(--f) * 1px);
}
.reference {
font-family: Playfair Display;
position: absolute;
}
.target {
font-family: Times New Roman;
color: red;
position: absolute;
}
.hidden {
visibility: hidden;
}
JavaScript
const text = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse gravida nisl ac velit dignissim lacinia. Etiam eu commodo augue. Duis in elementum felis. Fusce eget vehicula odio. Suspendisse ullamcorper mattis velit, non sodales est hendrerit in. Vivamus leo sem, tempor quis interdum et, maximus varius lacus. Ut sed nibh risus. Pellentesque ullamcorper tortor pellentesque quam malesuada, euismod feugiat ligula varius. Phasellus lobortis diam ut metus tempor, sed hendrerit tellus posuere. Duis tincidunt felis in diam fermentum, in mattis sem rhoncus. Cras velit tellus, facilisis non elementum ut, accumsan ac dolor. Proin feugiat nunc in bibendum efficitur.`
document.querySelectorAll('.reference').forEach(e => e.innerHTML = text);
document.querySelectorAll('.target').forEach(e => e.innerHTML = text);
function modify() {
const container = document.querySelector('.container');
container.setAttribute('style', `--w: ${widthInput.value}; --f: ${fontSizeInput.value}`)
}
widthInput.onchange = modify;
fontSizeInput.onchange = modify;
modify();
let intervalId;
function startAnimate() {
function toggle() {
document.querySelector('.reference').classList.toggle('hidden');
document.querySelector('.target').classList.toggle('hidden');
}
document.querySelector('.reference').classList.add('hidden');
intervalId = setInterval(toggle, 500);
}
function stopAnimate() {
clearInterval(intervalId);
}
animateCheck.onchange = function() {
if (animateCheck.checked)
startAnimate();
else
stopAnimate();
}