unexpected use of low performance transition property (height) - css

.sampleClass {
transition: height 1s cubic-bezier(0.19, 01, 0.1, 0.01);
}
I am trying to use the transition property like above but when I run the lint checks it throws the following error and similar errors when using width or all
126:15 ⚠ Unexpected use of plugin/no-low-performance-animation-properties
low performance
transition property
(height).

Some ways of transitioning encourage the system to use the GPU where possible - though this is a complex subject so difficult to lay down hard and fast rules for all cases.
In this particular instance you may like to try transition on a scaleY rather than a height and see if that is more acceptable. This specific idea is discussed in https://www.smashingmagazine.com/2016/12/gpu-animation-doing-it-right/ where they give this example -
<div id="a"></div>
<div id="b"></div>
<style>
#a, #b {
will-change: transform;
}
#a {
width: 100px;
height: 100px;
}
#b {
width: 10px;
height: 10px;
transform: scale(10);
}
</style>
the second (scale) version being 100 times smaller than the first (separated out). Of course you will want to use scaleY for your height example.
It's worth reading the article and picking up a few tips on what may be best in a particular instance. One thing that is stated is that CSS animations use the GPU, I don't know enough to recommend definite ways forward, try it and lint will tell you I guess.

That's telling you that a transition on the "height" property is a really expensive operation from a performance standpoint.
Animating height, width, or child content that impacts the size of an element, forces the browser to re-calculate positions of all elements and repaint the page. If you're trying to do that calculation for each frame of animation it's likely to get janky.
This is a bit old, but the main concepts still apply HTML5Rocks High-Performance Animations.
The goal is to animate properties that can be done with minimal layout changes. Typically this means changing things outside the DOM flow (scale(), translate(), etc)

Related

High render usage with animations on mouse move

I found some interesting behavior when testing the performance of some CSS animations. For example, I can animate these 1,000 elements and on my PC they are barely using any resources.
It's honestly impressive that it preforms that well, but if I'm moving the mouse, it's a completely different story.
The only difference is that I am constantly moving my mouse. I want to know why this happens, and if there is anything I can do to improve it. None of these elements have any mouse interaction, no JavaScript listeners, no CSS hover effects or anything like that. I am confused why moving the mouse would then have such a major effect. This high resource usage also happens even when the elements aren't visible and are scrolled past. The window is focused for all benchmarks.
The animation that I am talking about are using transforms and opacity. When using other properties like width, height, margin I get high resource usage no matter what.
Here are several things that I have tried to change this with no noticeable difference in performance.
pointer-events: none, unsurprisingly no effect. I didn't think it worked like that.
will-change
display: inline-block vs position: absolute layout
transform vs opacity animations
translate3d vs translate
Elements outside of the viewport (scrolled past)
I'm guessing this has to do with a GPU and as soon as the mouse moves, it requires the CPU to do something. This would explain the lack of difference on properties that require to CPU to calculate, and properties that can use the GPU are effected so dramatically.
I'm noticing this using Brave and Edge for sure. I don't under the Firefox tool enough to confidently say the same for them, although it appears to happen as well.
How can I make this always run as in the first case? I am never using any mouse interaction, so these elements could careless what it happening with the mouse from my perspective.
Here is a code snippet that should be able to produce the effect. I also have here on a GitHub pages site.
https://jack-stoller.github.io/so_demo.html
<style>
body {
padding-bottom: 150vw;
}
div {
position: absolute;
height: 50px;
width: 50px;
pointer-events: none;
will-change: transform;
background-color: red;
animation: Animation 2s ease infinite;
}
#keyframes Animation {
from {
transform: scale(0);
}
to {
transform: scale(1);
}
}
</style>
<body></body>
<script>
const size = 50 + 8 + 8;
const count = Math.floor(window.innerWidth / size);
[...Array(1000)].forEach((_, i) => {
let div = document.createElement('div');
div.style.top = Math.floor(i / count) * size + 'px';
div.style.left = Math.floor(i % count) * size + 'px';
document.body.appendChild(div);
});
</script>

Setting overflow on container breaks translateZ

I want a cool scrolling effect on my website like this:
There are two background images that scroll much slower than the rest of the page, divided by another element with a higher z-index value and unmodified scroll speed.
I have managed to do so in Firefox using 3d transform and overflow: hidden (as you can see, the two background images do not overlap). Here's the significant part of the code:
HTML:
<div class="container-container">
<div class="container">
<div class="slow-scroll">
<img src="...">
</div>
</div>
</div>
CSS:
.container-container {
perspective: 100px;
}
.container {
transform-style: preserve-3d;
overflow: hidden;
}
.slow-scroll {
transform: translateZ(-900px) scale(10.5);
}
My intention was to do the same as in the GIF - have a container with regular scroll speed that would contain the slower scrolling background, so that the overflow could be hidden, thus making it impossible for the two background images to overlap.
However, this doesn't work for Chrome or Microsoft Edge - the background images act as if the translateZ() value was absent (the scale still works normally though). This happens if I set overflow: hidden to any value except initial, revert, or unset.
Can this be fixed? Is there a workaround?
Note: I have looked around and saw this question, but it's outdated and the accepted answer does not work for me.
Based on your description, and the sample images provided, I think what you're looking for is a parallax scrolling effect. Simply refer to this tutorial below, which contains a simple example. I think it will help you.
How TO - Parallax Scrolling
Edit:
And according to your description, you mentioned that translateZ() not work in Edge, I created a simple demo and tested it, and I found it works normally in Edge(version 97.0.1072.55). I think maybe there is some problem with the code, such as this line:
transform: transform: translateZ(-900px) scale(10.5);
And if you want to implement this requirement, you could try to create multiple layers and set different translateZ() values for them. Simply refer to this example: Pure CSS Parallax Websites - Demo3

Difference between Transform and Position

I will start by apologising, in case my question is not relevant to the forum.
I am building a website, I am totally self taught and only been doing it a short time.
I an slightly scared i have been doing things wrong with regards to positioning objects.
I have been positioning with CSS like so:
.object{
position:relative;
left:100px;
top:20px;
}
However, lately, I have seen posts advising to use:
.object
transform:translate(100px, 20px)
but then using the transform, I am seeing other things that apparently need to be added to condition for different browsers, i.e:
-ms-transform: translate(100px, 20px); /* IE 9 */
-webkit-transform: translate(100px, 20px); /* Safari */
Would anyone be able to shed a bit of light as to the difference between position and transform?
I have looked on google but have not been able to find anything which actually explains when one should be used and when to use the other.
Thanks in advance
Transform attribute is more specific for pages that requires to manipulate an object such as a div. For example, if you want to rotate a div, you use transform:rotate(degrees) as CSS3 site shows here: CSS3 play rotation example. Also, transform lets you to move elements and scale them as it's explained here. Instead, position is more static meaning that you can choose where to put elements inside a web page. For example, if you are trying to position a div inside another div than you will use
position: absolute;
left: 20px;
right: 30px;
whereas to position an element relating to the normal border of the browser you will use
position: fixed;
and so on. Different types of position are shown here.
Hence, your code is correct in both ways and there is no difference. You should choose between one way or the other depending on what you want to do because transform is better to implement different kinds of effects to the elements while position is better to move elements inside another ones.

Css div height/width transition for dynamic content

<div>Text here</div>
Let say I have a div with a textfield in it and I want the div to smoothly make Height/Width transition as I type in more text and make linebreaks. Is there any simple way to do this transition with css without Javascript involved?
How would the text be edited? Javascript or AJAX call.
Clever solution, albeit with caveats:
you must know a height you can set at the beginning (0 will work)
not exactly the cleanest.
use max-height, not height. start with something small, whatever the default height of the div's content is, then set it to something rather high, as it will only expand to match your content. you will probably also want overflow: hidden so you can actually see the masking as it transitions.
.test{
overflow: hidden;
transition: 1s linear;
}
.test.begin{
max-height: 15px;
}
.test.end{
max-height: 400px;
}
note that the animation speed is based off of the difference between the max heights. even if you are only animating over 100px of content in 1 sec, the speed of the reveal will be as if you were animating over 385px in 1 second.
edit: I havent had my morning coffee yet, but are you sure you don't want a, you know...
<textarea>
?
The easiest way to get a box that expands as you type is with the contenteditable attribute.
<div contenteditable>Type here...</div>
Here is a demonstration.
I don't think a smooth, gradual transition effect can be achieved as text is typed into the contenteditable element, though. Transitioning on dynamic element heights is already quite difficult due to the lack of browser support for transitioning height: auto and percentage heights.
Sadly the transition effect you're looking for will most likely require JavaScript, unless someone comes up with a very clever CSS solution.

CSS transform vs position

Can some please explain to me the difference in transitioning the positional left or right properties or the -transform: translateX(n), as the both seem to achieve the same thing yet can be applied independently. I understand about the possibility of hardware acceleration but that's dependent on implementation.
// psuedo code;
#box {
-transition-property: all;
-transition-duration: 1s;
}
// javascript
box.style.transform = "translateX(200px)";
vs
box.style.left = "200px";
What's the advantage of one over the other?
Thanks,
p
The drawing order of rendering layers is:
layout layer
paint layer
compositor layer
A redraw in a layer will trigger redraw in subsequent layers.
Changing left or margin will trigger a redraw in layout layer (which, in turn, will trigger redraws in the other two layers) for the animated element and for subsequent elements in DOM.
Changing transform will trigger a redraw in compositor layer only for the animated element (subsequent elements in DOM will not be redrawn).
The difference in performance (hence in frames per second or, in simple terms, in animation smoothness) is tremendous. Using the first technique will often result in jittery animations even on good machines (when the processor is busy), while the second will likely run smoothly even on systems with limited resources.
Another advantage of using transforms is compositor redraws are heavily optimized (animations to multiple elements result in one redraw for all), while changing layout layer will trigger a redraw after each change of each element.
For a more detailed explanation on rendering techniques and rendering performance I recommend Google's Web Fundamentals.
Position is dependant on what the position is set to, transform works from the element itself. So you could see transform as being identical to position:relative;.
However, you can still use transform on an absolutely positioned element (to position it relatively without needing an additional element or resorting to margins), as well as transform being CSS3 so if you can use position instead you should.
top and left CSS properties work only on elements positioned relative, absolute or fixed. Also, top and left properties rely on the parent's position (relative it, absolute or static). Translations are not affected by that settings.
Translation transformations are "identical" to applying top and left when element has position: relative. In any other case they aren't the same operations.
As mention above:
position:relative and translate can achieve the same effect in a different way
position:relative happen in the layout phase which means it can interact with other elements in terms of layout
while translate happens when all the layout process complete, further it even already painted, what is remaining is a matter where to put the element, so it has no interaction with the existing layout
consider the following example which will present an obvious visual difference by using the two methods
.container {
width: 300px;
height: 300px;
overflow: scroll;
background: red;
}
.child {
width: 280px;
height: 280px;
background: green;
}
<div class="container">
<div class="child"></div>
</div>
By setting position:relative;top:100px to the child element, the container has no enough space to hold the child, and because of the fact that overflow is set as scroll, the scroll bar will present
On the other hand, By setting transform:translateY(100px), it has nothing to do with the layout, so the scrollbar will not present
Like the spec said:
However, if relative positioning causes an 'overflow:auto' or
'overflow:scroll' box to have overflow, the UA must allow the user to
access this content (at its offset position), which, through the
creation of scrollbars, may affect layout
To conclude, position is involved in layout, while transform not, which means transform can have better performance.
prefer transform to position when the layout is not your concern

Resources