CSS3 порядок преобразования имеет значение: самая правая операция сначала
Когда мы используем CSS3 transform: operation1(...) operation2(...)
, какой из них выполняется первым?
Первая сделанная операция, похоже, самая большая справа., то есть здесь operation2
выполняется до operation1
. Чтобы быть уверенным, это правда?
Примечание. Я прочитал одну вещь и ее противоположность в некоторых местах (ответы, статьи в Интернете), поэтому вопрос здесь.
Ответы
Ответ 1
Да, первая сделанная операция - это самая правая, то есть здесь operation2
выполняется до operation1
.
Вот документация: http://www.w3.org/TR/css-transforms-1/ но я еще не нашел параграф об этом.
Пример 1
Здесь сначала выполняется масштабирование, а затем перевод 100px по вертикали (если перевод был сделан первым, масштабирование сделало бы перевод 500px!)
#container {
position: absolute;
transform: translate(0,100px) scale(5);
transform-origin: 0 0; }
<div id="container"><img src="https://i.stack.imgur.com/xb47Y.jpg"></img></div>
Ответ 2
Преобразования выполняются слева направо. Преобразования соответствуют матричным операциям, и они выполняются слева направо.
За этим стоит интуиция, это не просто то, что это буквально в спецификации как нормативное правило (пункт 3 здесь: https://drafts.csswg.org/css-transforms-1/#transform-rendering)
Вот ручка, чтобы попробовать: https://codepen.io/monfera/pen/YLWGrM
Объяснение:
Каждый шаг преобразования устанавливает свою собственную систему координат. Так
transform: translateX(500px);
устанавливает новую систему координат 500px вдоль оси X своего родителя, и элемент будет отображаться там.
Точно так же,
background-color: blue;
transform: translateX(500px) rotate(60deg);
сначала устанавливает новую систему координат 500px вдоль оси X (справа) своего родителя, и только затем, внутри этой (переведенной, но теперь неактуальной) системы координат, она выполняет вращение. Таким образом, это будет фигура, которая на 500px вправо и повернута на месте (вокруг так называемого transform-origin
, который интерпретируется в локальной системе координат, и по умолчанию 50% 50% для вращения означает, вращение вокруг центра прямоangularьника, но это в стороне).
Обратный порядок
background-color: orange;
transform: rotate(60deg) translateX(500px);
сначала устанавливает новую систему координат, которая повернута на 60 градусов относительно родителя, а затем переводит 100px вдоль оси X теперь повернутой системы координат в направлении, которое на самом деле не вправо от глобальной точки зрения документа (или пользователь). Таким образом, в этом случае, это как если бы вы сначала повернули бумагу, а затем сместили фигуру на 500 единиц вдоль стороны бумаги (от начала координат, в данном случае это левый верхний angular).
![enter image description here]()
Для более подробного обсуждения и понимания того, как можно интуитивно понять его для обоих направлений, ознакомьтесь с Составлением преобразований - преобразования CSS следуют модели постмножения, поэтому ищите страницу с заголовком "Подумайте преобразований как преобразование локальной системы координат "(хотя иллюстрации кажутся немного странными)
![Local coordinate frame - post-multiply]()
Ответ 3
Это было упомянуто в других ответах и комментариях, но, на мой взгляд, с недостаточным акцентом: краткий ответ: оба пути верны.
Все зависит от того, считаете ли вы свои координаты прикрепленными к элементу (слева направо) или фиксированными на странице на основе начальной позиции элемента (справа налево).
Вот статья, показывающая разницу с анимацией (которая облегчает понимание): Преобразование цепочек.
Вот фрагмент, показывающий анимацию из статьи:
html, body { height: 100%; }
body {
background: #aaa;
color: #000;
font-family: Calibri,Candara,Segoe,"Segoe UI",Optima,Arial,sans-serif;
overflow: hidden;
margin: 0;
}
.info {
text-align: center;
font-family: Consolas,monaco,monospace;
font-size: 20px;
font-weight: bold;
margin-bottom: 4px;
color: #fff;
}
.split { white-space: nowrap; }
.side {
display: inline-block;
width: 50%;
}
.label {
text-align: center;
font-size: 20px;
}
.container {
position: relative;
font-size: 50px;
margin: .6em auto 0;
width: 0; height: 0;
transform: translateX(-1em);
}
.ltr .object {
position: absolute;
left: 0; top: 0;
width: 1em; height: 1em;
margin: -.5em 0 0 -.5em;
background: rgb(114,34,34);
animation: ltrObj 5s infinite;
}
@keyframes ltrObj {
from, 10% { transform: rotate( 0deg) translateX(0em); }
40% { transform: rotate(45deg) translateX(0em); }
70%, to { transform: rotate(45deg) translateX(2em); }
}
.object.shadow {
animation: none;
opacity: .2;
}
.ltr .axes {
position: absolute;
left: .5em; top: .5em;
width: 1em; height: 1em;
color: #111;
box-sizing: border-box;
border-left: 2px solid;
border-top: 2px solid;
}
.ltr .axes::before, .ltr .axes::after {
content: '';
position: absolute;
width: .2em; height: .2em;
box-sizing: border-box;
border-left: 2px solid;
border-top: 2px solid;
transform-origin: top left;
}
.ltr .axes::before { top: 100%; left: 0; margin-left: -1px; margin-top: 1px; transform: rotate(225deg); }
.ltr .axes::after { top: 0; left: 100%; margin-top: -1px; margin-left: 1px; transform: rotate(135deg); }
.rtl .axes {
position: absolute;
left: 0; top: 0;
width: 2.5em; height: 2.3em;
color: #111;
box-sizing: border-box;
border-left: 2px solid;
border-top: 2px solid;
}
.rtl .axes::before, .rtl .axes::after {
content: '';
position: absolute;
width: .2em; height: .2em;
box-sizing: border-box;
border-left: 2px solid;
border-top: 2px solid;
transform-origin: top left;
}
.rtl .axes::before { top: 100%; left: 0; margin-left: -1px; margin-top: 1px; transform: rotate(225deg); }
.rtl .axes::after { top: 0; left: 100%; margin-top: -1px; margin-left: 1px; transform: rotate(135deg); }
.rtl .object {
position: absolute;
left: 0; top: 0;
width: 1em; height: 1em;
margin: -.5em 0 0 -.5em;
background: rgba(100,0,0,0.8);
animation: rtlObj 5s infinite;
}
@keyframes rtlObj {
from, 10% { transform: rotate( 0deg) translateX(0em); }
40% { transform: rotate( 0deg) translateX(2em); }
70%, to { transform: rotate(45deg) translateX(2em); }
}
.helper-mask {
position: absolute;
left: 0; top: 0;
width: 3em; height: 3em;
overflow: hidden;
}
.helper {
position: absolute;
left: 0; top: -2em;
width: 0; height: 2em;
margin-top: 2px;
box-sizing: border-box;
border: 2px solid #00c;
border-left: none;
border-radius: 0 100% 0 0;
transform-origin: bottom left;
animation: helper 5s infinite;
}
@keyframes helper {
from, 10% { width: 0em; transform: rotate( 0deg); }
40% { width: 2em; transform: rotate( 0deg);}
70%, to { width: 2em; transform: rotate(45deg);}
}
<div class="info">rotate(45deg) translateX(2em)</div>
<div class="split">
<div class="side ltr">
<div class="label">Left to Right</div>
<div class="container">
<div class="object shadow"></div>
<div class="object">
<div class="axes"></div>
</div>
</div>
</div>
<div class="side rtl">
<div class="label">Right to Left</div>
<div class="container">
<div class="axes"></div>
<div class="object"></div>
<div class="helper-mask">
<div class="helper"></div>
</div>
</div>
</div>
</div>
Ответ 4
Это делается из Влево в Вправо
Из Проект редакторов W3C
div {
height: 100px; width: 100px;
transform: translate(80px, 80px) scale(1.5, 1.5) rotate(45deg);
}
Это преобразование перемещает элемент на 80 пикселей в направлениях X и Y, затем масштабирует элемент на 150%, затем поворачивает его на 45 ° по часовой стрелке относительно оси Z. Обратите внимание, что масштаб и вращение действуют вокруг центра элемента, так как элемент имеет значение по умолчанию - 50% 50%.
![введите описание изображения здесь]()