Точка трансформации: transform-origin

transform-origin - это точка, вокруг которой происходит поворот, масштабирование или наклон элемента через transform. По умолчанию она находится точно в центре блока (50% по горизонтали и по вертикали), поэтому scale() и rotate() из прошлых уроков всегда работали симметрично. Сдвинув эту точку к краю или углу, можно заставить элемент расти или поворачиваться не от середины, а от нужного места.

Попробуй прямо сейчас: пунктирная рамка - это флаг в состоянии покоя. Наведи курсор - флаг поворачивается на 15 градусов, как будто его треплет ветер. Обрати внимание: левый верхний угол флага, прибитый к флагштоку, вообще не двигается - поворот происходит именно вокруг него, потому что там стоит transform-origin: top left. Попробуй убрать transform-origin из кода (или поменять на center) - флаг начнёт поворачиваться вокруг своей середины и оторвётся от флагштока.

Как задать точку трансформации

По умолчанию transform-origin равен 50% 50% - центр элемента по обеим осям, именно поэтому rotate() и scale() из прошлых уроков всегда крутили и растягивали элемент строго от середины. Значение можно задать числом, процентом или ключевым словом (left, center, right, top, bottom), а собственная проверка вскрыла тонкость, которую легко понять неправильно: если указано ОДНО число или процент (например 20px), это ВСЕГДА горизонтальная ось - точка сдвигается на 20px от левого края, а по вертикали остаётся в центре. Но если указано одно КЛЮЧЕВОЕ СЛОВО вертикальной оси - top или bottom, - оно задаёт именно вертикаль, а горизонталь сама становится center: transform-origin: top на самом деле означает "center top", а не "20px" в буквальном смысле "первое значение - это всегда горизонталь". Два ключевых слова можно писать в любом порядке: right bottom и bottom right - это одно и то же. А ещё точку можно вынести ЗА пределы блока - отрицательным значением или числом больше 100%, - это пригодится, например, для эффекта вращения по орбите вокруг далёкой точки.

.badge { transform-origin: 50% 20px; transform: rotate(20deg); } - обе оси заданы явно: точка ровно по центру по горизонтали и в 20px от верхнего края по вертикали.

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

.badge { transform-origin: 20px; /* хотели: на 20px ниже верхнего края */ transform: rotate(20deg); } - на самом деле точка окажется в 20px от ЛЕВОГО края, а по вертикали останется точно по центру - совсем не там, где хотели.

Как точка меняет поворот и масштабирование

Как ты уже видел в уроке про scale, по умолчанию рост идёт строго от центра - элемент увеличивается симметрично во все стороны. Если задать transform-origin: top left, эффект меняется: собственная проверка показала, что верхний левый угол блока остаётся АБСОЛЮТНО неподвижным (те же координаты до и после), а сам блок растёт только вправо и вниз - именно так должно вести себя настоящее выпадающее меню, прикреплённое к углу кнопки. То же самое верно для rotate(): элемент поворачивается вокруг угла, а не вокруг середины. Важно и обратное: сам по себе transform-origin ничего не делает - собственная проверка подтвердила, что без единой функции внутри transform (rotate/scale/translate/skew) элемент выглядит и стоит ровно так же, как если бы transform-origin вообще не было задано. И ещё одна деталь: проценты в transform-origin считаются от размеров СОБСТВЕННОГО блока элемента, точно как и в transform: translate() - не от родителя и не от окна браузера.

.menu { transform-origin: top left; transform: scale(0); transition: transform .2s; } .wrapper:hover .menu { transform: scale(1); } - меню появляется, разворачиваясь именно из угла кнопки, к которому оно прикреплено.

Неправильное ожидание - что меню само "поймёт", откуда ему появляться:

.menu { transform: scale(0); transition: transform .2s; } .wrapper:hover .menu { transform: scale(1); } - transform-origin не задан, значит используется значение по умолчанию (центр) - меню будет расти во все стороны от середины, а не из угла кнопки.

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

ОшибкаЧто происходитКак исправить
Считать, что одно число в transform-origin сдвигает точку по вертикали Одно число или процент без ключевого слова - это всегда горизонтальная ось, вертикаль остаётся в центре Указывать обе оси явно (transform-origin: 50% 20px), если нужен именно сдвиг по вертикали
Думать, что ключевые слова top/bottom обязательно писать вместе с center Одно ключевое слово вроде top само задаёт свою ось - вторая ось автоматически становится center, "top" и "center top" это одно и то же Не дублировать center - одного ключевого слова достаточно, если вторая ось и так должна быть по центру
Задать transform-origin и ждать, что элемент сам сдвинется или изменит вид transform-origin ничего не меняет сам по себе - это только точка отсчёта; без rotate/scale/translate/skew внутри transform она никак не проявляется Проверять эффект только вместе с реальной функцией трансформации, в блокноте
Думать, что проценты в transform-origin считаются от родителя или от экрана Проценты всегда считаются от размеров СОБСТВЕННОГО блока элемента, как и в transform: translate() Для точки за пределами блока (например, для орбитального вращения) использовать отрицательные значения или числа больше 100%, а не проценты "от родителя"

Шпаргалка

ЗаписьЧто означает
transform-origin: 50% 50%;Значение по умолчанию - центр элемента
transform-origin: 20px;Одно число - всегда горизонталь (X), вертикаль остаётся center
transform-origin: top;Одно ключевое слово само задаёт свою ось - равно "center top"
right bottom = bottom rightПорядок ключевых слов не важен
transform-origin: -50% 50%; или 150% 50%;Точка выходит за пределы блока - пригодится для орбитального вращения
transform-origin без rotate/scale/translate/skewНикакого эффекта - точка "молчит", пока нет самой трансформации

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

Можно ли задать transform-origin относительно центра окна браузера, а не самого элемента?

Нет - transform-origin всегда считается относительно собственного блока элемента, других вариантов у свойства просто нет. Если нужна точка вне блока (например, чтобы элемент вращался по орбите вокруг далёкой точки), придётся сдвинуть саму точку отрицательным значением или числом больше 100% - но отсчёт всё равно идёт от размеров и позиции элемента, а не от окна.

Как сделать, чтобы элемент вращался по кругу вокруг другого объекта, а не вокруг своего центра?

Сдвинуть transform-origin далеко за пределы самого элемента - например, на расстояние будущего радиуса орбиты - а затем применить rotate() с анимацией. Раз точка находится не в центре элемента, а где-то в стороне, поворот превращается в движение по кругу вокруг этой удалённой точки, а не вращение элемента на месте.

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

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

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

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

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

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