Как сделать блок 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. Этот подход работает во всех современных браузерах.