normalising background positioning

by Richard Hunter

HTML

<div id="foo" class="foo"></div>

<input id="rangeInput" type="range"/>

CSS

.foo { 
  --top-offset: 50%;
  width: 200px;
  height: 300px;
  border: solid 1px red;
  background-image: url(https://i.imgur.com/AsS3s8o.jpg);
  background-size: 90% var(--image-height);
  background-repeat: no-repeat;
  background-position: top var(--top-offset) center;
}

JavaScript

function calculateBackgroundPosition(
  imageHeight,
  yOffsetValue
) {
  const containerHeight = 100; // container is always 100% of itself!
  return yOffsetValue / (containerHeight - imageHeight) * 100
}

const imageHeight = 50;
const yOffset = 3;

foo.style.setProperty('--image-height', imageHeight + '%');
foo.style.setProperty('--top-offset', calculateBackgroundPosition(imageHeight, yOffset) + '%');

rangeInput.addEventListener('input', (event) => {
  foo.style.setProperty('--top-offset', calculateBackgroundPosition(imageHeight, event.target.value) + '%');
});