Подтвердить что ты не робот

CSS3 порядок преобразования имеет значение: самая правая операция сначала

Когда мы используем CSS3 transform: operation1(...) operation2(...), какой из них выполняется первым?

Первая сделанная операция, похоже, самая большая справа., то есть здесь operation2 выполняется до operation1. Чтобы быть уверенным, это правда?

Примечание. Я прочитал одну вещь и ее противоположность в некоторых местах (ответы, статьи в Интернете), поэтому вопрос здесь.

4b9b3361

Ответ 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%.

введите описание изображения здесь