Fit font size to element width

by Yaroslav Samardak

HTML

<link href="https://fonts.googleapis.com/css?family=Open+Sans&display=swap" rel="stylesheet">

<div class='parent' id="p1">
	<div class='children' id="c1">
		Short text
	</div>
</div>

<div class='parent' id="p2">
	<div class='children' id="c2">
		Lorem Ipsum is simply dummy text of the printing and typesetting industry
	</div>
</div>

<div class='parent' id="p3">
	<div class='children' id="c3">
		Bla bla bla bla bla bla bla
	</div>
</div>

<div class='parent' id="p4">
	<div class='children' id="c4">
		OK!
	</div>
</div>

<div class='parent' id="p5">
	<div class='children' id="c5"></div>
</div>

CSS

body {
	font-family: 'Open Sans', sans-serif;
}

div {
	font-size: 16px;
}

.parent {
	width: 100%;
	text-align: center;
	/* overflow-x: hidden; */
	/* background: rgba(255, 0, 0, 0.3); */
	margin-bottom: 2px;
}

.children {
	display: inline-block;
	white-space: nowrap;
  vertical-align: middle;
	line-height: 1;
	/* background: rgba(0, 255, 0, 0.3); */
}

JavaScript

const requests = {}
const h = {}

function fit(parentId, childrenId) {
	const parentEl = document.getElementById(parentId)
	const childrenEl = document.getElementById(childrenId)
	
	const cancel = () => {
		window.cancelAnimationFrame(requests[parentId])
		requests[parentId] = undefined
	}

	const update = () => {
		requests[parentId] = undefined

		const parentWidth = parentEl.offsetWidth
		const parentHeight = parentEl.offsetHeight
		const childrenWidth = childrenEl.offsetWidth
		const childrenHeight = childrenEl.offsetHeight

		const scale = parentWidth / childrenWidth * childrenHeight * (100 / childrenHeight)
		childrenEl.style.fontSize = `${scale}px`
	}
	
	const reset = () => {
		childrenEl.style.fontSize = `100px`
		requests[parentId] = window.requestAnimationFrame(update)
		h[parentId] = parentEl.offsetHeight
	}

	if (requests[parentId]) {
		return
	} else {
		reset()
	}
}

function apply() {
	fit('p1', 'c1')
	fit('p2', 'c2')
	fit('p3', 'c3')
	fit('p4', 'c4')
	fit('p5', 'c5')
}

apply()
window.addEventListener('resize', apply)