Масштабирование: scale, scaleX, scaleY

scale(), scaleX() и scaleY() увеличивают или уменьшают элемент через transform, не занимая (и не освобождая) место в потоке документа. Одно число - это степень растяжения по одной оси, а не пиксели: scale(1) - как есть, scale(2) - вдвое крупнее, scale(0.5) - вдвое меньше. Рост идёт от центра элемента в обе стороны одновременно.

Попробуй прямо сейчас: наведи курсор на синий блок - он вырастет ровно в 1.6 раза, и по клеточкам фона видно, что верхний, нижний, левый и правый края отодвигаются от центра поровну. Затем замени scale(1.6) на scale(2, 1) - блок растянется только по горизонтали, а на scale(-1) - отразится зеркально.

scaleX() и scaleY(): растяжение по одной оси

scaleX() растягивает элемент строго по горизонтали, scaleY() - строго по вертикали, вторая ось при этом не меняется. Число внутри скобок - это множитель, а не длина: у него нет единиц измерения. 1 - размер как есть, больше 1 - элемент крупнее, от 0 до 1 - мельче. Проверено на практике: блок 100×60px с transform: scaleX(2) занимает на экране ровно 200×60px - ширина удвоилась, высота не тронута, а поскольку точка трансформации по умолчанию - центр элемента, блок «съезжает» на 50px влево от исходного положения, ничего не меняя в left или top.

.avatar:hover { transform: scaleY(1.15); } - аватар слегка «вытягивается» по вертикали при наведении, ширина не меняется.

Неправильное ожидание - что scaleY() принимает пиксели, как height:

.avatar:hover { transform: scaleY(15px); } - значение с единицами измерения здесь недопустимо, браузер отбрасывает всё объявление transform целиком, и элемент не меняется вовсе.

scale(): один или два аргумента, отрицательные значения и зеркало

scale() с одним числом растягивает элемент сразу по обеим осям одинаково - scale(1.5) полностью равносилен scaleX(1.5) вместе с scaleY(1.5). Если указать два числа через запятую, первое отвечает за X, второе - за Y, и растяжение получается разным по осям: проверено на практике, что scale(2, 1) на блоке 100×60px даёт те же 200×60px, что и один scaleX(2), а scale(1, 2) - те же 100×120px, что и scaleY(2). Отдельная и часто неожиданная особенность - отрицательное число. Оно не «переворачивает» элемент, а зеркально отражает его: собственный тест показал, что метка, стоящая в 10px от левого края карточки, после transform: scaleX(-1) оказывается на том же расстоянии от ПРАВОГО края - вся карточка отражается, как в зеркале, а не поворачивается.

.icon-share { transform: scaleX(-1); } - иконка «поделиться» отражается зеркально, что часто нужно для RTL-версий сайта или альтернативного варианта значка.

Неправильное ожидание - что для зеркального отражения нужен поворот:

.icon-share { transform: rotate(180deg); } - это перевернёт иконку «вверх ногами», а не отразит её слева направо: для несимметричных иконок и текста результат выглядит совсем иначе, чем зеркало.

Отдельно стоит крайний случай - scale(0). Элемент визуально схлопывается в точку (0×0px), но не исчезает из документа: он остаётся в DOM, его computed display по-прежнему block, а не none. Больше того - поскольку, как мы разбирали в уроке о том, что такое CSS-трансформации, transform никогда не влияет на поток документа, схлопнутый в точку элемент продолжает резервировать своё исходное место в разметке. Собственная проверка это подтвердила: сосед рядом с блоком шириной 100px, к которому применили scale(0), остаётся на прежнем расстоянии - как будто блок всё ещё занимает свои 100px, просто стал невидимым.

Частые ошибки новичков

ОшибкаЧто происходитКак исправить
Писать scale(150px) вместо scale(1.5) Значение с единицами измерения недопустимо - браузер отбрасывает всё объявление transform, элемент остаётся без изменений Указывать просто число-множитель без единиц: scale(1.5) (проценты вроде scale(150%) тоже работают и равны 1.5)
Ожидать, что элемент растёт только в одну сторону (например, вниз-вправо) Рост идёт от центра элемента сразу во все стороны, потому что точка трансформации по умолчанию - центр (50% 50%) Оставлять вокруг элемента свободное место со всех сторон, а не только с одной
Путать отрицательный scale с поворотом на 180 градусов scale(-1) зеркально отражает элемент, а rotate(180deg) переворачивает его - для несимметричного содержимого (текста, стрелок) результат выглядит по-разному Для зеркала использовать scale(-1) / scaleX(-1) / scaleY(-1), для переворота - rotate(180deg)
Считать, что scale(0) убирает элемент из документа, как display: none Элемент визуально сжимается в точку, но остаётся в DOM и по-прежнему занимает своё место в потоке - трансформации не меняют layout Для полного скрытия с освобождением места использовать display: none, а не scale(0)

Шпаргалка

ЗаписьЧто означает
transform: scaleX(1.5);Растяжение только по горизонтали, в 1.5 раза
transform: scaleY(1.5);Растяжение только по вертикали, в 1.5 раза
transform: scale(1.5);Растяжение по обеим осям одинаково (то же самое, что scaleX(1.5) и scaleY(1.5) вместе)
transform: scale(2, 1);Два числа через запятую - разное растяжение по X и по Y
transform: scale(-1);Зеркальное отражение по обеим осям, без изменения размера
transform: scale(150%);Проценты тоже допустимы: 150% равно 1.5

Коротко: отвечаем на вопросы

Как отразить картинку зеркально с помощью CSS?

Самый простой способ - transform: scale(-1, 1) для зеркального отражения по горизонтали (слева направо, как в зеркале), scale(1, -1) - для отражения по вертикали (вверх ногами), а scale(-1, -1) отражает сразу по обеим осям, что визуально равносильно повороту на 180 градусов. Дополнительный HTML или JavaScript для этого не нужен.

Почему картинка или текст становится немного размытым после transform: scale()?

Это известная особенность рендеринга браузеров (особенно Chrome) при увеличении через transform: браузер масштабирует уже отрисованные пиксели вместо того, чтобы перерисовать элемент заново в новом размере. Полностью убрать эффект нельзя, но его можно смягчить свойством will-change: transform - оно заранее подсказывает браузеру подготовить отдельный слой для трансформации.

Категория
Поделиться в социальных сетях

Отправить комментарий

0 Комментарии

Отправить комментарий (0)

#buttons=(Хорошо) #days=(20)

Мы используем файлы cookie для улучшения работы сайта. Подробнее
Хорошо
×