CSS3 transform order matters: rightmost operation first

Kiedy używamy CSS3 transform: operation1(...) operation2(...), który z nich jest zrobiony pierwszy?

Pierwsza wykonana operacja wydaje się być najbardziej po prawej stronie., tzn. tutaj {[1] } robi się przed operation1. Dla pewności, czy to prawda?

Uwaga: przeczytałem jedną rzecz i jej przeciwieństwo w niektórych miejscach( odpowiedzi, artykuły w Internecie), stąd pytanie tutaj.

Author: Basj, 2014-12-24

3 answers

Tak, pierwsza operacja jest najbardziej po prawej., tzn. tutaj {[4] } robi się przed operation1.

Ten artykuł MDN stwierdza rzeczywiście:

Funkcje transformacji są mnożone w kolejności od lewej do prawej, co oznacza, że transformaty złożone są skutecznie stosowane w kolejności od prawej do lewej.

Oto dokumentacja: http://www.w3.org/TR/css-transforms-1/.


Przykład 1

Tutaj skalowanie jest wykonywane najpierw , a następnie tłumaczenie 100px w pionie (jeśli tłumaczenie zostało wykonane jako pierwsze, skalowanie sprawi, że tłumaczenie będzie 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>

Przykład 2

Tutaj tłumaczenie jest wykonane najpierw , a następnieskalowanie (skalowanie wykonane po sprawia, że tłumaczenie wygląda jak tłumaczenie 500px!)

#container { 
  	position: absolute; 
  	transform: scale(5) translate(0,100px); 
  	transform-origin: 0 0; }
<div id="container"><img src="https://i.stack.imgur.com/xb47Y.jpg"></img></div>
 42
Author: Basj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-25 08:59:48

Transformacje są wykonywane od lewej do prawej. Transformaty odpowiadają operacjom macierzy, które są wykonywane od lewej do prawej.

Za tym stoi intuicja, nie chodzi tylko o to, że jest to dosłownie w spec jako reguła normatywna (punkt 3 Tutaj: https://drafts.csswg.org/css-transforms-1/#transform-rendering )

Oto długopis do wypróbowania: https://codepen.io/monfera/pen/YLWGrM

Wyjaśnienie:

Każdy krok transformacji ustanawia swój własny układ współrzędnych. Więc

transform: translateX(500px);

Ustanawia nowy układ współrzędnych 500px wzdłuż osi X jego rodzica, a element będzie tam renderowany.

Podobnie,

background-color: blue;
transform: translateX(500px) rotate(60deg);

Najpierw ustanawia nowy układ współrzędnych 500px wzdłuż osi X (po prawej) swojego rodzica, a dopiero wtedy , W ramach tego (przetłumaczonego, ale teraz nie ma to znaczenia) układu współrzędnych wykonuje obrót. Więc będzie to kształt, który jest 500px w prawo, i obrócony w miejscu (wokół tzw. transform-origin, który jest interpretowany w lokalnym układzie współrzędnych, a domyślne 50% 50% dla rotacji oznacza obrót wokół środka prostokąta, ale jest to odstęp).

Odwrotna kolejność

background-color: orange;
transform: rotate(60deg) translateX(500px);

Najpierw ustanawia nowy układ współrzędnych, który jest obrócony o 60 stopni względem nadrzędnika, a następnie tłumaczy 100px wzdłuż osi X obecnie obróconego układu współrzędnych, w kierunku, który nie jest w rzeczywistości w prawo z globalnego punktu widzenia układu współrzędnych. dokument (lub użytkownik). Tak więc, w tym przypadku, to tak, jakbyś najpierw obrócił papier, a następnie zsunął kształt 500 jednostek wzdłuż boku papieru (od początku, który jest w tym przypadku w lewym górnym rogu).

Tutaj wpisz opis obrazka

Dla bardziej zaawansowanej dyskusji i zrozumienia, jak to możliwe, aby intuicyjnie zrozumieć to w obu kierunkach, sprawdź Composing Transformations - transformacje CSS postępuj zgodnie z modelem Post-mnożenia, więc poszukaj strony z nagłówek "myśl o przekształceniach jako o przekształcaniu lokalnej ramki współrzędnych" (ilustracje wydają się być trochę dziwne) {]}

Local coordinate frame-Post-multiply

 7
Author: Robert Monfera,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-25 09:44:45

Zostało to wspomniane w innych odpowiedziach i komentarzach, ale moim zdaniem nie z wystarczającym naciskiem: krótka odpowiedź to obie drogi są ważne .

Wszystko zależy od tego, czy weźmiemy pod uwagę współrzędne dołączone do elementu (od lewej do prawej), czy ustalone na stronie w oparciu o początkową pozycję elementu (od prawej do lewej).

Oto artykuł pokazujący różnicę z animacjami (co ułatwia zrozumienie): transformacje łańcuchowe .

Oto fragment pokazujący animacje z Artykułu:

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>

Nie ma znaczenia, czy implementacja używa lewej do prawej, czy prawej do lewej, obie są jednakowo ważne podczas tworzenia animacji, o ile masz na uwadze różnicę.

 1
Author: Bali Balo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-09 18:05:42