How to Apply Multiple Transforms in Css

How to apply multiple transforms in CSS?

You have to put them on one line like this:

li:nth-child(2) {
transform: rotate(15deg) translate(-20px,0px);
}

When you have multiple transform directives, only the last one will be applied. It's like any other CSS rule.


Keep in mind multiple transform one line directives are applied from right to left.

This: transform: scale(1,1.5) rotate(90deg);

and: transform: rotate(90deg) scale(1,1.5);

will not produce the same result:

.orderOne, .orderTwo {  font-family: sans-serif;  font-size: 22px;  color: #000;  display: inline-block;}
.orderOne { transform: scale(1, 1.5) rotate(90deg);}
.orderTwo { transform: rotate(90deg) scale(1, 1.5);}
<div class="orderOne">  A</div>
<div class="orderTwo"> A</div>

How to apply multiple transforms to the same element

Without seeing your code it is hard to answer. BUT I think the reason this is happening is because transform is being overwritten in the animation.

Here is simple working example:

<div class="triangle"></div>
.triangle {
border: 20px transparent solid;
border-right-color: red;
display: inline-block;
animation-name: example;
animation-duration: 1s;
transform: rotate(45deg);
animation-fill-mode: forwards;

}

@keyframes example {
from {
transform: translate(0px, 0px) rotate(45deg);
}
to {
transform: translate(1000px, 0px) rotate(45deg);
}
}

[EDIT] Here are my suggestions after the author shared the code.

Basically, you are declaring transform more than once for a given element. in CSS the last occurrence overrides all previous occurrences. In order to solve this, you need to work around this. There is four ways you can do this:

  1. Convert
<div class="triangle topleft green column7 row2"></div>

to something like

<div class="triangle-holder topleft column7 row2">
<div class="triangle green"></div>
</div>

This allows you to have two different transforms on two different elements without overriding each other (as what's happening in the original code) The transform: rotate() is applied to .triangle, while transform: translate() is applied to .triangle-holder


  1. Get rid of transform: rotate() completely (as well as the background image), by using borders (see above for an example). This will only work for 90 degree rotations

  2. Get rid of transform: translate() and use margin or top/left for positioning.

  3. Animate each triangle explicitly in order to combine your transforms into one transformation.

I would recommend the second option, as it requires minimal changes to your code, and AFAIK is browser compatible way of creating CSS triangles.

How can I apply multiple transform declarations to one element?



I'm guessing this does not work because the classes override each other's transform property?

Correct. This is an unfortunate limitation as a side-effect of how the cascade works.

You will have to specify both functions in a single transform declaration. You could simply chain both class selectors together instead of creating a new class for a combined transform:

.doublesize.rotate {
-webkit-transform: scale(1) rotate(0deg);
}

.doublesize.rotate:hover {
-webkit-transform: scale(2) rotate(360deg);
}

... but as you can see, the issue lies in the transform property rather than in the selector.


This is expected to be rectified in Transforms level 2, where each transform has been promoted to its own property, which would allow you to combine transforms simply by declaring them separately as you would any other combination of CSS properties. This means you would be able to simply do this:

/* Note that rotate: 0deg and scale: 1 are omitted
as they're the initial values */

.rotate:hover {
rotate: 360deg;
}

.doublesize:hover {
scale: 2;
}

... and take advantage of the cascade rather than be hindered by it. No need for specialized class names or combined CSS rules.

CSS3 Multiple Transforms: translate() and scale()

How do I alter this so that the top and left of the div does not move up and left?

You stop moving it around in the first place … and specify where you want the origin of the transformation(s) to be instead:

#box {  width: 100px;  height: 100px;  font-family: "Arial";  display: flex;  align-items: center;  justify-content: center;  color: white;  background-color: red;  border-radius: 25%;  transition: 0.5s ease-in-out;  transform-origin: top left; /* add this in */}            #box:hover {  transform: scale(2, 2); /* no translate here */}
<div id="box">Text</div>

How do I connect html transforms in multiple classes?

You may look at CSS var(--X) (see links below snippet's demo) and , set all transformation you intend to 0 by default and update them via the className :(mind support before use : https://caniuse.com/#feat=mdn-css_properties_custom-property_var and eventually a polyfill https://github.com/nuxodin/ie11CustomProperties )

possible exemple without JavaScript https://codepen.io/gc-nomade/pen/RwWLOWr :

.foo {
--rotate: 20deg;
}

.bar {
--skewY: 20deg;
}

div[class] {
transform: rotate( var(--rotate, 0)) skewY( var(--skewY, 0));/* fallback value is here 0 */
}


/* demo purpose */

div[class] {
float: left;
border: solid;
}

html {
display: flex;
height: 100%;
}

body {
margin: auto;
}
<div class="foo bar">foo bar</div>
<div class="foo ">foo</div>
<div class="bar">bar</div>
<div class="nop">no transform</div>

Set CSS transform in multiple places

Unfortunately, you cannot do it. Syntax for transform is as follows,

transform: none|transform-functions|initial|inherit;

So when you call multiple classes on your HTML element, only the last class declared in your CSS is applied. (class order doesn't matter in HTML)

The best you can do is use CSS preprocessor with a function which will generate a string of these transform functions called in one declaration so that they don't override.

Using multiple .style.transform on same element

When applying multiple transforms to the same element, they should be added as space separated values to the same property like below. Otherwise, they would get overwritten (only the rotateY will be applied because it is the latest).

object.style.transform = "rotateX(" + x + "deg)";
object.style.transform += "rotateY(" + y + "deg)";

I have added an alert of the object.style.transform to both the original snippet and the modified version and we can see how the original one always outputs only the rotateY whereas the changed one outputs both rotateX() and rotateY() together.

Original Code with Alerts added |
Modified Code with Alerts added

Apply two different CSS transforms simultanesouly

transform is a single property, so you can't target from CSS for only part of it, e.g, you cannot set different CSS transition-duration for two transform-functions applied in the same transform property.

You could write everything through js, updating yourself both transform-functions values over time, but that would be a lot of work, for a potentially non-hardware accelerated result, while there is a simple workaround.

The easiest solution is to change a little bit your structure so that you apply the scale on a wrapper element, and the translate on the inner-one.

This way, both transforms are applied on your inner <img>, but they don't conflict each other.

// JavaScript source codevar catchX = 0,  catchY = 0,  x = 0,  y = 0,  burn = 1 / 28;
function imageWatch() { x += (catchX - x) * burn;
translate = 'translate(' + x + 'px, ' + y + 'px)';
$('.image-area img').css({ '-webit-transform': translate, '-moz-transform': translate, 'transform': translate });
window.requestAnimationFrame(imageWatch);}
$(window).on('mousemove click', function(e) {
var mouseX = Math.max(-100, Math.min(100, $(window).width() / 2 - e.clientX)); catchX = (26 * mouseX) / 100;
});
imageWatch();
html,body {  height: 100%}
body { margin: 0; padding: 0;}
*,*::before,*::after { content: "\0020"; box-sizing: border-box;}
.poster { display: inline-block; width: 32vw; height: 100vh; position: relative; overflow: hidden !important}
.image-area { position: absolute; width: 100%; height: 100vh; opacity: .24; transition: 2.5s ease;}
.image-area { opacity: 1;}
.image-area img { margin-top: -312px; margin-left: -913px; width: auto; /* height: auto */ height: 1000px; /* here we can remove the transition */}

/* scaling on hover is only applied on the parent elmt */
.image-area>.scaler { transform: scale(1, 1); transition: 8s transform;}
.poster:hover .image-area>.scaler { transform: scale(1.3, 1.3);}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><div class="poster">  <div class="image-area">    <!-- the scaling wrapper-->    <div class="scaler">      <img class="poster" src="https://vignette1.wikia.nocookie.net/logopedia/images/f/fc/Sky_Believe_in_better_logo.jpg/revision/latest?cb=20110910152552" alt="Sky" />    </div>  </div></div>
<div class="poster"> <div class="image-area"> <!-- the scaling wrapper--> <div class="scaler"> <img class="poster" src="https://vignette1.wikia.nocookie.net/logopedia/images/f/fc/Sky_Believe_in_better_logo.jpg/revision/latest?cb=20110910152552" alt="Sky" /> </div> </div></div>
<div class="poster"> <div class="image-area"> <!-- the scaling wrapper--> <div class="scaler"> <img class="poster" src="https://vignette1.wikia.nocookie.net/logopedia/images/f/fc/Sky_Believe_in_better_logo.jpg/revision/latest?cb=20110910152552" alt="Sky" /> </div> </div></div>


Related Topics



Leave a reply



Submit