JSFiddle - React, Tailwind, and code Playground

HTML

<div id="form">
  <input id="outline-width" type="number" placeholder="outline width (px)" />
  <input id="outline-blur" type="number" placeholder="outline blur (px)" /> 
  <input id="outline-color" type="text" placeholder="outline color" />
</div>
<hr>
<div id="example-bg">
  <div class="example-text">The quick brown fox jumps over the lazy dog.</div>
  <div class="example-text resizing">The quick brown fox jumps over the lazy dog.</div>
</div>
<hr>
<div id="css">
  <div class="heading">Click to copy this CSS style property</div>
  <div class="css-property"></div>
</div>

CSS

#form {
  display: flex;
  flex-direction: column;
}

input {
  width: 100%;
}

#css {
  background: #d5d5d5;
  border: 1px solid dimgray;
  padding: 0.5rem;
  cursor: pointer;
}

#css .heading {
  text-align: center;
  color: dimgray;
}

#example-bg {
  padding: 0.5rem;
}

JavaScript

var width;
var color;

function luminanace(r, g, b) {
    var a = [r, g, b].map(function (v) {
        v /= 255;
        return v <= 0.03928
            ? v / 12.92
            : Math.pow( (v + 0.055) / 1.055, 2.4 );
    });
    return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
}

function contrast(color1, color2) {
		var rgb1 = colorToArray(color1);
		var rgb2 = colorToArray(color2);
    return (luminanace(rgb1[0], rgb1[1], rgb1[2]) + 0.05)
         / (luminanace(rgb2[0], rgb2[1], rgb2[2]) + 0.05);
}

function colorToArray(color) {
	var e = document.createElement('div');
  e.style.color = color; document.body.append(e);
  var array = getComputedStyle(e).color.match(/\d+/g).map((e)=>{return Number.parseInt(e)});
  e.remove();
  return array
}

function getOppositeColor(color) {
	var e = document.createElement('div');
  e.style.color = color;
  document.body.append(e);
  color = getComputedStyle(e).color;
  e.remove();
	var colors = color.match(/\d+/g);
  var opposite = 'rgb(';
  for (var i = 0; i < colors.length; ++i) {
  	opposite += 255 - colors[i] + ",";
  }
  opposite = opposite.replace(/,$/, ')');
  return opposite;
}

function computeStyle() {
	var width = document.querySelector('#outline-width').value;
  width = (width === '') ? 0 : Number.parseFloat(width);
  var blur = document.querySelector('#outline-blur').value;
  blur = (blur === '') ? 0 : Number.parseFloat(blur);
  var color = document.querySelector('#outline-color').value;
  if (width < 1 || color === '') {
  	document.querySelector('.css-property').innerText = '';
    return;
  }
	var style = 'text-shadow: ';
  var indent = false;
	for (var i = -1 * width; i <= width; ++i) {
  	for (var j = -1 * width; j <= width; ++j) {
    	if (! (i === 0 && j === 0 && blur === 0)) {
      	var indentation = (indent) ? '\u00a0\u00a0\u00a0\u00a0' : '';
	    	style += indentation + i + "px " + j + "px " + blur + "px " + color + ',\n';
        indent = true;
      }
    }
  }
  style = style.substring(0,...