<header role="banner">
  <h1 class="banner-title">TypeLock</h1>
  <p class="banner-summary">Clamping typography with JS and CSS variables</p>
</header>

<main role="main">
  <article>
    <header>
      <h1>Lorem</h1>
    </header>

    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nihil tempore hic corporis accusamus expedita obcaecati eum magnam odit, eos repudiandae, maiores dolor aut esse non. Voluptate optio nesciunt fugit nam.</p>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nihil tempore hic corporis accusamus expedita obcaecati eum magnam odit, eos repudiandae, maiores dolor aut esse non. Voluptate optio nesciunt fugit nam.</p>
  </article>

  <article>
    <header>
      <h1>Ipsum Dalore</h1>
    </header>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nihil tempore hic corporis accusamus expedita obcaecati eum magnam odit, eos repudiandae, maiores dolor aut esse non. Voluptate optio nesciunt fugit nam.</p>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nihil tempore hic corporis accusamus expedita obcaecati eum magnam odit, eos repudiandae, maiores dolor aut esse non. Voluptate optio nesciunt fugit nam.</p>
  </article>

  <article>
    <header>
      <h1>Sit Amet</h1>
    </header>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nihil tempore hic corporis accusamus expedita obcaecati eum magnam odit, eos repudiandae, maiores dolor aut esse non. Voluptate optio nesciunt fugit nam.</p>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nihil tempore hic corporis accusamus expedita obcaecati eum magnam odit, eos repudiandae, maiores dolor aut esse non. Voluptate optio nesciunt fugit nam.</p>
  </article>
</main>

<footer role="contentinfo">
  <small>This has been a TypeLock® production.</small>
</footer>
// Variables Setup
// ==========================================================

:root {
	--js-font-lock: 26;
	--js-line-lock: 1.65;
	--js-heading-lock: 24;
}


// Base Styles
// ==========================================================

html {
  font: normal 112%/calc(var(--js-line-lock) * 0.1) 'Arvo', serif;
}

html,
body {
  height: 100%;
  width:100%;
}

body {
  background: #E6F0FA;
}

header[role="banner"] {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 50vh;
  max-height: 50vw;
  padding: 1rem;
  text-align: center;
  background: #4A009F;
  color: white;
}

main {
  padding: 1rem;
  margin: auto;
  max-width: 560px;
}

footer[role="contentinfo"] {
  text-align: center;
  background: #4F009C;
  color: white;
}

.banner-title {
  margin-top: 0;
  margin-bottom: 0;
  line-height: 1;
}

.banner-summary {
  line-height: 1.25;
}


// TypeLock Styles
// ==========================================================

.banner-title {
  font-size: calc(var(--js-font-lock) * 0.1rem);
}

h1 {
	font-size: calc(var(--js-heading-lock) * 0.1rem);
	line-height: 1;
}
View Compiled
(function (root, factory) {

	if (typeof define === 'function' && define.amd) {
    // AMD module
    define(factory);
  } else if (typeof exports === 'object') {
    // CommonJS-like environment (i.e. Node)
    module.exports = factory();
  } else {
    // Browser global
    root.addTypeLock = factory();
  }

}(this || window, function () {

	// Special Thanks To: Tommy Hodgins, Chris Wallis, Mathew Chase
	let isRegistered = false;
	const typeLockOptions = [];

	// setup clamp values
	function clamp(min, mid, max) {
		return Math.min(Math.max(min, mid), max);
	}

	// clamp values, define css variable
	function typeLock({ cssvar, min, max, factor }) {
		let clamp_value = clamp(min, window.innerWidth / factor, max); 
		document.documentElement.style.setProperty(cssvar, clamp_value);
	}

	// apply passed values from addTypeLock method
	function applyTypeLock() {
		typeLockOptions.forEach(typeLock);
	}

	// register our desires to the window's load and resize event
	function registerTypeLock() {
		let events        = [ 'load', 'resize' ],
				events_length = events.length;

		// Attach Events
		for(let i = 0, l = events_length; i < l; i++) {
			window.addEventListener( events[i], applyTypeLock );
		}
	}

	// check if registered and push values and to options array
	function addTypeLock(config) {
		if (!isRegistered) {
			registerTypeLock();
			isRegistered = true;
		}
		typeLockOptions.push(config);
	}

	// required only if you want to unregister one of the variables
	function remove(config) {
		let index = typeLockOptions.indexOf(config);
		if (index !== -1) {
			typeLockOptions.splice(index, 1);
		}
	}

	return addTypeLock;
}));

// Calls To Action
addTypeLock({
	cssvar: '--js-font-lock',
	min: 26, 
	max: 72, 
	factor: 10
});

addTypeLock({
	cssvar: '--js-line-lock',
	min: 16,
	max: 20,
	factor: 40
});

addTypeLock({
	cssvar: '--js-heading-lock',
	min: 14,
	max: 24, 
	factor: 40
});
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.