How To Always Have Something Been Animated In Css
Being able to animate the CSS width
and height
properties would be super useful. Unfortunately at the moment it's a cinch mode to become your browser to scream in agony. In this 5 infinitesimal tutorial we'll explore using the transform
property to simulate animating the width of an element.
Don't Breathing the Width and Height Properties
Browsers don't like it when they have to calculate the positions and sizes of elements on the webpage. Most elements in some style affect the rendering of other elements, they push siblings to another position, or when their size is inverse a parent element also changes size. Modifying the dimensions of i element can therefore have lots of unforeseen consequences.
Irresolute the width
and/or height
of an element will trigger the browser to decide which other elements (children, siblings, or parents) are impacted past the change and how those elements should be updated. This process is called a reflow and information technology volition be followed by a repaint.
These operations are very taxing on the CPU, so to keep a website fast we should avoid triggering them every bit much as possible.
Using Transforms Instead
To run performant animations we need to utilize the CSS transform
or opacity
properties. In this article nosotros'll focus on transform
The transform belongings instructs the GPU to make some last minute updates to the texture of an element earlier cartoon information technology to the screen. These updates tin for example exist rotating, moving, and scaling of an element.
You tin can compare the GPU texure of an element with a picture you took of the element with your mobile phone. This picture only consists of pixels, all other data nearly the element is gone.
The GPU but has to deal with the pixels that nowadays the chemical element. Considering GPUs are very skillful at dealing with pixels, the transform
operations are super fast.
This also has a downside. We tin only manipulate the pixels, not the contents of the element. Call up we but have the pic of the element, all other data is gone.
Y'all can see beneath how this deviation impacts the edge-radius
property. In the transform
example the radius is not redrawn (like in the width
case), information technology is simply scaled. Redrawing would require a repaint, the GPU cannot do that, it only deals with pixels.
.square { width : 200px; acme : 200px; border-radius : 40px; } .square-resized { width : 100px; } .square-transformed { transform : scaleX (0.5) ; }
Animating the transform
property is a million times faster than animative width
, height
, or any of the other properties that impact layout and will trigger a reflow
Simply if we animate information technology, the result will be that weirdly stretched shape. It might be fast, but information technology doesn't expect peachy. It always reminds me of those aliens in Duke Nukem 3D getting squished past a door.
9-Slice Scaling To The Rescue
Earlier border-radius
was a thing we had to create an image for each corner and/or edge of an element to "fake" border radius. Depending on the design that could yield upwardly to 8 images for a single element. These images would be layed out like this:
This is called the 9-slice scaling method. Tis method allows you to scale the element and stretch prototype ii, iv, 6, and 8, while linking ane, 3, 7, and 9 to their respective corners using absolute positioning.
Now our corners aren't stretched when scaled, come across below:
Luckily we alive in a solar day and age where browsers support edge-radius
, we no longer have to rely on this technique for cartoon rounded corners.
Nosotros tin still use this technique to resize elements using the transform
holding. For the sake of brevity this instance will only explore scaling the width of the element.
We'll offset with a structure like this:
Allow's apply this to our foursquare. We'll need one container and three child elements to stand for the square left (1), center (2), and right (three) parts.
<div course = "square" > <div class = "left" > </div > <div form = "eye" > </div > <div class = "correct" > </div > </div >
Let's await at the CSS
/* children volition exist positioned relativly to this element */ .square { position : relative; pinnacle : 100px; } .left, .centre, .right { position : accented; superlative : 0; lesser : 0; } .left { groundwork : red; } .eye { background : yellowish; } .right { background : bluish; } /* we need room for a xx pixel border radius (on 1 side) */ .left, .right { width : 20px; } .left { border-radius : 20px 0 0 20px; } .correct { border-radius : 0 20px 20px 0; } /* child layout definitions */ .middle { /* centre needs to exist 20 pixels from the left, so information technology doesn't overlap with the .left chemical element */ left : 20px; /* needs a width of ane pixel, this causes scaleX(60) is equal to sixty pixels */ width : 1px; transform : scaleX (lx) ; /* we need to scale the texture from the left side for it to align correctly, default is center */ transform-origin : left; } .correct { /* we demand to move the right element to marshal with the right side of the .eye element 20px + 60px = 80px */ transform : translateX (80px) ; }
The event is a nicely colored square.
I've colored to element parts to make them individually recognizeable.
Now for our next fob, we can breathing the .center
and .right
elements of the square.
.heart { blitheness : centre-animate 1s ease infinite alternate; } .right { animation : right-breathing 1s ease infinite alternate; } @keyframes right-animate { 0% { transform : translateX (140px) ; } 100% { transform : translateX (20px) ; } } @keyframes center-animate { 0% { transform : scaleX (120) ; } 100% { transform : scaleX (0) ; } }
Looks good to me, let's set the background colour back to blackness.
If yous're on Firefox, this should look slap-up. If yous're using Safari or Chrome y'all might observe a slight flickering betwixt the center and right part.
I'm not sure why this happens. It might be a problem with alpha blending OR rounding of pixels. Anyway. By slightly overlapping the middle element with the right element nosotros tin can resolve this return issue. We'll make sure the chemical element is at least 1
pixel wide and scales to 121
pixels.
@keyframes middle-animate { 0% { transform : scaleX (121) ; } 100% { transform : scaleX (i) ; } }
Huray! Nosotros got ourselves an animatable non-squishy square!
We could accept this further and make it more flexible by moving the animation to JavaScript, creating a web component, or by using CSS variables, simply for the purpose of this article this example should suffice.
View a demo of cease result on CodePen
Agree Your Horses
Earlier you lot run of and start using this technique everywhere, delight annotation that:
- We're still scaling the middle square over the X axis so background images applied to the square will be stretched.
- A
box-shadow
can be done but is a bit tricky to pull off. - The square cannot cut off other elements, every bit in,
overflow: subconscious
won't work.
Withal, with a fleck of trickery, yous can use this to create some crawly furnishings. The file items and the drib area of the FilePond file upload library all employ this technique to smoothly animate their pinnacle.
Pintura Image Editor used this technique on both the ten and y centrality to render and animate the white crop rectangle on height of the image. This has since been partly replaced with WebGL.
Decision
The default width
and height
CSS backdrop are (forth with most other properties) not suitable for blitheness. They bear upon render operation too much because updating them triggers the browser to re-evaluate related element positions and sizes.
If we employ the transform
property instead we can performantly animate our square on the GPU. While super fast this also introduces some limitations because the GPU simply deals with pixels.
By applying the 9-slice technique we can work around some of these limitations and create an element that nosotros tin animate in a performant way.
Source: https://pqina.nl/blog/animating-width-and-height-without-the-squish-effect/
Posted by: nolandrowend.blogspot.com
0 Response to "How To Always Have Something Been Animated In Css"
Post a Comment