Animation transforms only one property (scale), overrides others (translate)

The problem is that the value of the transform property has several parts, such as translate , scale , etc.

This is a theoretical question about an element, let .loader have transform:translate(10px, 10px) , and in the animation I want to animate the scale property. In this case, the browser will not accept transform:translate(10px, 10px) and will only accept scale .

I am looking for a way to solve this problem.

Here is an example of this question. Please note that I am not looking for an answer to this specific example (for example: wrap an element or add a translate value in the animation definition), but a general solution (if it exists, of course).

 .loading { position: relative; width: 100px; height: 100px; background: #eee; } .loading:before, .loading:after { content: ""; width: 50%; height: 50%; -moz-border-radius: 50%; -webkit-border-radius: 50%; border-radius: 50%; background-color: #fff; opacity: 0.6; position: absolute; top: 0; left: 0; /* the broswer doesn't take this */ transform: translate(100px, 300px); -webkit-animation: bounce 2s infinite ease-in-out; animation: bounce 2s infinite ease-in-out; } .loading:after { -webkit-animation-delay: -1s; animation-delay: -1s; } @keyframes bounce { 0%, 100% { transform: scale(0); -webkit-transform: scale(0); } 50% { transform: scale(1); -webkit-transform: scale(1); } } 
 <div class="loading"></div> 
+4
css css3 animation css-transforms css-animations
source share
2 answers

Usually, when you add animation with changes to the transform property, then the transforms that are specified in the base element must also be carried over to be present in the keyframes of the animation. That is, new transforms (which are part of the animation) must be added on top of the existing transform and not overwrite it. The following describes how this should be done.

 .loading { position: relative; width: 200px; height: 200px; background: #eee; } .loading:before, .loading:after { content: ""; width: 50%; height: 50%; border-radius: 50%; background-color: #fff; opacity: 0.6; position: absolute; top: 0; left: 0; transform: translate(100px, 300px); animation: bounce 2s infinite ease-in-out; } .loading:after { animation-delay: -1s; } @keyframes bounce { 0%, 100% { transform: scale(0) translate(100px, 300px); } 50% { transform: scale(1) translate(100px, 300px); } } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script> <div class="loading"></div> 

I wrote a similar answer here to the question of adding several animations to an element with each of these animations that change the values โ€‹โ€‹of the transform properties that are independent of the other. I am linking it here for reference only and do not think that they are duplicates.


Having said the above, adding the original transformation to each animated kefir is not possible if you are trying to create animation libraries or trying to split each animation into a separate class. Say, for example, you want to add the same bounce animation to several elements, and each of them has a different initial transform parameter, then it becomes impossible to add it to the keyframe of the animation.

In such cases, you can still achieve the desired result using CSS, but it would be very difficult (almost impossible, in my opinion) to do this with a single element.

What are your options? Well, one option is to add animation to the shell element.

 .loading-wrapper { position: relative; width: 200px; height: 200px; background: #eee; } .loading-before, .loading-after { position: absolute; width: 50%; height: 50%; top: 0px; left: 0px; animation: bounce 2s infinite ease-in-out; } .loading-before:before,.loading-after:before { content: ""; width: 100%; height: 100%; border-radius: 50%; background-color: #fff; opacity: 0.6; position: absolute; top: 0; left: 0; transform: translate(100px, 300px); } .loading-after { animation-delay: -1s; } @keyframes bounce { 0%, 100% { transform: scale(0); } 50% { transform: scale(1); } } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script> <div class="loading-wrapper"> <div class="loading-before"></div> <div class="loading-after"></div> </div> 

The solution is quite general , and you can apply it to almost all such cases . The disadvantage is that if you want to compose several such transformations, then you most likely will get several such wrappers. There is no pure CSS method other than adding source transformations to keyframes of the animation.

The following snippet is another sample.

 .move-n-scale { position: relative; height: 100px; width: 100px; background: sandybrown; border: 1px solid chocolate; transform: scale(0.5); animation: move 1s linear infinite alternate-reverse; } .move { position: relative; display: inline-block; animation: move-only 1s linear infinite alternate-reverse; } .scale { position: absolute; height: 100px; width: 100px; top: 0px; left: 0px; background: sandybrown; border: 1px solid chocolate; transform: scale(0.5); } @keyframes move { from { transform: translateX(0px) scale(0.5); } to { transform: translateX(300px) scale(0.5); } } @keyframes move-only { from { transform: translateX(0px); } to { transform: translateX(300px); } } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script> <div class='move-n-scale'></div> <div class='move'> <div class='scale'></div> </div> 

Note. . To clarify, I noticed that you mentioned that you do not want a solution that is very specific to this problem, for example, wrap it, etc. But I still added this solution as an answer, because this is the only general solution that I know of. I added a second snippet to show that this is really common.

+3
source share

You can remove translate(100px, 300px); in .loading:after , and then set translate(100px, 300px) to @keyframes , as shown below:

 @keyframes bounce { 0%, 100% { transform: scale(0)translate(100px, 300px); -webkit-transform: scale(0)translate(100px, 300px); } 50% { transform: scale(1)translate(100px, 300px); ; -webkit-transform: scale(1)translate(100px, 300px); } } 
+1
source share

All Articles