Как добиться такой адаптивности блока?

Делаю автоподстройку постеров на своём проекте, но не получается сделать так, чтобы изображение подстраивались как нужно.

Имеется постер размером width 254px а height 360px стало быть, если мы изменим ширину скажем так: width 280px то высота постера должна быть: height 397px. Что тут можно придуамать? Хотелось бы сделать какую то формулу расчёта высоты от ширины, но я не пойму, как расчитать сколько нужно добавить к высоте, когда меняется ширина... Нужно чтобы при любой ширине увеличивалась и высота так, как я описал выше. Также, прошк учесть, что используется display grid - может при помощи него можно сделать. Я знаю о @media но так выходит, что нужно учесть кучу разрешений и нужно описать кучу вариантов изменений, чтобы добится нормальной подстройки.

Пример чего хочу добиться: пример


Ответы (2 шт):

Автор решения: Qwertiy

Старый способ - padding, новый aspect-ratio.

div {
  margin: 2.5%;
  width: 40%;
  border: 1px solid;
  float: left;
}

div:first-child::before {
  content: "";
  display: block;
  padding-top: 50%;
}

div:last-child {
  aspect-ratio: 2;
}
<main>
  <div></div>
  <div></div>
</main>

→ Ссылка
Автор решения: Daniil Loban

Основная фишка использование aspect-ratio в качестве задания размера, но при этом обязательно одна из сторон должна быть строго забита, если установлены 2 стороны aspect-ratio не работает, однако в программе я это решаю в updateSize. Можно использовать фиксированную высоту или ширину, тоже очень удобно если масштаб не нужен.

/*
Имеется постер размером width 254px а height 360px стало быть, если мы изменим ширину скажем так: width 280px то высота постера должна быть: height 397px. Что тут можно 
*/

const w = document.getElementById('width');
const h = document.getElementById('height');
const z = document.getElementById('zoom');
const p = document.getElementById('page');

let oldW = 254
let oldH = 360
let oldZ = 0.5
let aspect = oldW / oldH

function updateSize(){
  p.style.height = `${oldH * oldZ}px`
  p.style.width = `${oldW * oldZ}px`
  p.style.aspectRatio = `${oldW} / ${oldH}`
}
updateSize()

function updateHeight(target){
  if (oldW && oldH){
    oldH = target.value
    w.value = Math.round(oldH * aspect)
    oldW = w.value
    p.style.height = `${oldH * oldZ}px`
    updateSize()
  } else {
    oldH = event.target.value
  }
}
function updateWidth(target){
  if (oldW && oldH){
    oldW = target.value
    h.value = Math.ceil(oldW / aspect)
    oldH = h.value
    p.style.width = `${oldW * oldZ}px`
    updateSize()
  } else {
    oldW = event.target.value
  }
}

w.addEventListener('change', (event) => {
  updateWidth(event.target)
}, false)

h.addEventListener('change', (event) => {
  updateHeight(event.target)
}, false)

z.addEventListener('change', (event) => {
  oldZ = event.target.value
  if (oldW && oldH){
    updateSize()
  } 
}, false)
body {
 background: gray;
}

div {
  /* height:100px; фиксированная высота */
  margin: 0 auto;
  background: white;
  border: 1px solid black;
  aspect-ratio: 254 / 360;
}
<label>
ширина:
<input id="width" type="number" value="254" >
</label>
<label>
высота:
<input id="height" type="number" value="360">
</label>
<label>
масштаб:
<input id="zoom" type="range" min="0.1" value=".5" step="0.01" max="1">
</label>
<div id="page"></div>

→ Ссылка