ResizeObserver to detect style changes...

Use a Resize observer in a "hidden" div so we can detect global style changes, for accessibility.

by David Iglesias

HTML

<div id="measurement">
<p id="stylebase" style="all:initial!important">This text should not be affected<p>
<p id="styletarget">This is some text</p>
</div>

<p>
This is some web content! <em>With emphasis!</em>
</p>

<input type="button" value="Set style" id="styleSetter" />
<input type="button" value="Unset style" id="styleRemover" />

<p>(Look at the JS console!)</p>

CSS

* { box-sizing: border-box; margin: 0; padding: 0 }

#measurement {
  position: fixed;
  top: -10000px;
}

JavaScript

// The theory is that the "#measurement"
// div will change sizes when some
// of the text properties of its
// contents change.
// We observe the resize events, and
// extract the computed styles we
// want from its contents.
let resizeObserver = new ResizeObserver((changes, observer) => {
  // console.log(changes);
  for (let change of changes) {
    let rect = change.contentRect;
  	console.log('Resize', rect);
    // Log the computed styles of the measurement target, and the reset element
    logComputedStyle(styletarget, stylebase);
  }
});

resizeObserver.observe(measurement);

/// Logs some properties of `el` as a table with `description`.
function logComputedStyle(el, reset) {
  let style = window.getComputedStyle(el);
  let base = window.getComputedStyle(reset);
  let relativeToBase = getToRelative(base.fontSize);
  let relativeToSize = getToRelative(style.fontSize);

  console.table({
    'base font-size': pretty(base.fontSize, relativeToBase),
    'font-size': pretty(style.fontSize, relativeToBase),
    'line-height': pretty(style.lineHeight, relativeToSize),
    'letter-spacing': pretty(style.letterSpacing, relativeToSize),
    'word-spacing': pretty(style.wordSpacing, relativeToSize),
    'margin-bottom': pretty(style.marginBottom, relativeToSize),
  });
}

// Returns an object that contains an absolute size in px, and
// its relative value
function pretty(size, relativeTo) {
	return {
    'px': size,
    'em': `${relativeTo(size)}em`,  
  }
}

// Returns a function that converts a dimension (in px)
// to a ratio over unitString.
//
// `let relativeTo20 = getToRelative('20px')` is a function that:
// `relativeTo20('40px')` returns 2.00 (precision limited to 2)
//
// This is useful to convert px to em measurements.
function getToRelative(unitString) {
  let unit = parseFloat(unitString);
  return (dimensionString) => {
    let dimension = parseFloat(dimensionString);
    return (dimension/unit).toPrecision(2);
  };
}

let...