Как сделать блок scaleble неадаптивным, но масштабируемым под родителя

    В веб-разработке часто возникает задача: сохранить фиксированные пропорции блока, но при этом заставить его уменьшаться, чтобы полностью поместиться в родительский контейнер, не нарушая расположение соседних элементов. В вашем примере с scaleble, dinamicSize и dinamicSize-2 требуется, чтобы scaleble не был адаптивным (то есть его содержимое не перестраивалось под ширину), а просто масштабировался как единое целое, а соседние блоки прижимались к его границам. Это реально реализовать с помощью CSS-трансформаций и флексбокса.

    Проблема адаптивности и масштабирования

    Обычно адаптивная вёрстка подразумевает изменение размеров элементов в зависимости от ширины экрана (через @media или относительные единицы). Однако если блок должен оставаться неадаптивным (его внутренние элементы не меняют своих размеров и расположения), но при этом уменьшаться, чтобы вписаться в родителя, нужно использовать свойство transform: scale().

    Основная сложность - масштабирование через transform не влияет на поток документа: соседние блоки не узнают об изменении видимого размера. Поэтому требуется дополнительная обёртка с фиксированными размерами, чтобы флекс-контейнер корректно распределял пространство.

    Решение: обёртка с фиксированными размерами и scale

    Создайте для блока scaleble родительскую обёртку с фиксированной шириной и высотой (например, 500×300 пикселей). Затем примените к самому scaleble трансформацию scale так, чтобы он поместился в эту обёртку. Для автоматического расчёта коэффициента масштабирования можно использовать JavaScript или CSS-функцию min() с 100%.

    Пример CSS-кода

    .wrapper-scaleble {
      width: 100%;
      height: 100%;
      overflow: hidden;
      position: relative;
    }
    
    #scaleble {
      width: 500px; /* фиксированная ширина */
      height: 300px; /* фиксированная высота */
      transform-origin: top left;
      transform: scale(calc(100% / 500));
    }

    Здесь calc(100% / 500) пытается вычислить коэффициент, но в чистом CSS это не сработает для произвольных размеров. Лучше использовать JavaScript для точного расчёта.

    JavaScript для автоматического масштабирования

    Напишите функцию, которая при загрузке и ресайзе окна вычисляет, насколько нужно уменьшить блок, чтобы он влез в родителя:

    function scaleBlock() {
      const wrapper = document.querySelector('.wrapper-scaleble');
      const block = document.getElementById('scaleble');
      const scaleX = wrapper.offsetWidth / block.offsetWidth;
      const scaleY = wrapper.offsetHeight / block.offsetHeight;
      const scale = Math.min(scaleX, scaleY);
      block.style.transform = `scale(${scale})`;
      block.style.transformOrigin = 'top left';
    }
    window.addEventListener('resize', scaleBlock);
    scaleBlock();

    Этот код гарантирует, что блок полностью впишется в обёртку, сохраняя пропорции, и не повлияет на соседние элементы, так как обёртка имеет фиксированные размеры.

    Работа с соседними блоками dinamicSize

    Чтобы блоки dinamicSize и dinamicSize-2 корректно прижимались к границам scaleble, поместите все три элемента в общий флекс-контейнер:

    .container {
      display: flex;
      align-items: flex-start;
    }
    
    .wrapper-scaleble {
      flex-shrink: 0;
      width: 60%; /* или другая доля */
    }
    
    .dinamicSize, .dinamicSize-2 {
      flex: 1;
    }

    Теперь соседние блоки будут занимать оставшееся пространство, а обёртка scaleble - фиксированный размер, внутри которого масштабируется сам блок. При уменьшении ширины окна обёртка тоже может уменьшаться, если задана в процентах, но блок внутри будет масштабироваться динамически.

    Альтернатива: viewport-единицы и object-fit

    Если содержимое блока - изображение или видео, можно использовать object-fit: contain. Для обычного HTML-контента этот метод не подходит, но можно применить iframe или svg с viewBox.

    Также рассмотрите вариант с aspect-ratio и max-width: 100%, но это сработает только если контент адаптивный.

    Заключение

    Сделать блок неадаптивным, но масштабируемым под родителя - реально. Используйте обёртку с фиксированными размерами и JavaScript для динамического scale. Соседние блоки прижмутся к границам через флексбокс. Главное - не забыть про transform-origin. Этот подход работает во всех современных браузерах.

    Часто задаваемые вопросы