Modern CSS has great ways to position and move a group of elements relative to each other, such as anchor positioning. That said, there are cases where it might be better to turn to the old ways for a bit of animation, which will save time and effort.
We have always been able to influence the structure of an element, such as resizing and rotating it. And if we change the intrinsic size of an element, its children are also affected. This is something we can use to our advantage.
Let’s say a pair of circles need to move towards and over each other. Something like this:
Our formatting can be as simple as a element containing four children .circle elements:
As far as rotating things goes, there are two options. We can (1) the parent container, or (2) animate them all .circle individually.
Tackling that first option is probably best because you’ll be animating them all .circle requires defining and setting up multiple animations instead of a single animation. Before we do that, we need to make sure everyone does .circle is in the element and then place absolutely all of them in it:
main {
contain: layout;
}
.circle {
position: absolute;
&:nth-of-type(1){
background-color: rgb(0, 76, 255);
}
&:nth-of-type(2){
background-color: rgb(255, 60, 0);
right: 0;
}
&:nth-of-type(3){
background-color: rgb(0, 128, 111);
bottom: 0;
}
&:nth-of-type(4){
background-color: rgb(255, 238, 0);
right: 0;
bottom: 0;
}
}If we use the element that contains the circles, then we can create a specific element .animate class only for the rotation:
/* Applied on (the parent element) */
.animate {
width: 0;
transform: rotate(90deg);
transition: width 1s, transform 1.3s;
} …and then put it on the element with JavaScript when the button is clicked:
const MAIN = document.querySelector("main");
function play() {
MAIN.className = "";
MAIN.offsetWidth;
MAIN.className = "animate";
}It looks like we’re animating four circles, but what we’re actually doing is rotating the parent container and changing its width, which also rotates and compresses all the circles within it:
Each .circle is attached to a respective corner of the parent with absolute positioning. When the animation is triggered in the parent element, ie gets the .animate class when the button is clicked — the its width shrinks and it rotates 90deg. That shrinking appeals to everyone .circle closer to the the center of the element, and the rotation causes the circles to change places as they pass through each other.
This approach makes animations easier to create and manage for simple effects. You can even layer the animations for each individual element for more variations, such as two squares crossing each other during the animation.
/* Applied on (the parent element) */
.animate {
transform: skewY(30deg) rotateY(180deg);
transition: 1s transform .2s;
.square {
transform: skewY(30deg);
transition: inherit;
}
} Do you see that? The parent element makes a 30deg skew and rotate along the Y axis, while the two children .square elements counteract that distortion with the same skewness. The result is that you will see the child squares change position as they move away from each other.
If we want the squares to form a separation without flipping, you can do it like this:
/* Applied on (the parent element) */
.animate {
transform: skewY(30deg);
transition: 1s transform .2s;
.square {
transform: skewY(-30deg);
transition: inherit;
}
} This time the element is crooked 30degwhile the .square children cancel that with a -30deg crooked.
Setting skew() on a parent element helps rearrange the child elements beyond what typical rectangular geometry allows. Any change in the parent can be supplemented, counteracted or canceled by the children, depending on the effect you are looking for.
Here is an example where scaling plays a role. Notice how the element skewY() is denied by his children and scale()s to a different value to compensate it a bit.
/* Applied on (the parent element) */
.animate {
transform: rotate(-180deg) scale(.5) skewY(45deg) ;
transition: .6s .2s;
transition-property: transform, border-radius;
.squares {
transform: skewY(-45deg) scaleX(1.5);
border-radius: 10px;
transition: inherit;
}
} The parent element () turns counterclockwise (rotate(-180deg)), scales down (scale(.5)), and vertically skewed (skewY(45deg)). The two children (.square) cancels the deformation of the parent element by using the negative value of the parent element’s skew angle (skewY(-45deg)), and horizontal scaling (scaleX(1.5)) to change from a square to a horizontal bar shape.
There are many of these combinations you can think of. I’ve created a few more below where, instead of triggering the animation with a JavaScript interaction, I create a
[open] once stands the
element is clicked. And each
contains a .icon child demonstrates another animation when the
switches between open and closed.Click on one
That’s all I wanted to share. It’s easy to forget that we gain some scope for writing efficient animations when we consider how transforming a parent element intrinsically affects its size, position, and orientation. This way, for example, instead of having to write complex animations for each individual child element, you can take better advantage of what the parent can do and then adjust the child-level behavior as necessary.
#CSS #animations #leverage #parentchild #relationship #CSS #tricks


