Skip to content
Advertisement

Laggy css :hover transitions on newest version of Chrome

I am developing a pretty simple website. On the computer on which I work, I was using chromium for quite a while now, and have not updated it, so it stayed at version 67. Now, I have moved to the newest version of Chrome (79) and I became quite frustrated seeing, that all of a sudden, without me changing any code, the CSS transitions pretty much do not work anymore. It’s as if it was very laggy. ( sometimes it registers hover on element after a very long delay, sometimes not, when it does it usually does not register the end of the hover … ). Yet, I once again checked on old version of chromium, I even checked on IE too, and it works perfectly on those browser.

Here’s the html of the sidebar on which the elements I talk about are located ( it’s not only on the sidebar, but I think it’s the best example ):

<div id="sidebar">
    <h1 class="special-fx-opacity invisible">CONSTRUCTION REALIZATIONS</h1>
    <div class="sidebar-el">
        <h2 onclick="location.href = '[censored]';" class="special-fx-opacity invisible">Novus&Mediucs Clinic, Oslo</h2>
    </div>
    <div class="sidebar-sep special-fx-opacity invisible"></div>
    <div class="sidebar-el">
        <h2 class="special-fx-opacity invisible">House, Hvistenveien</h2>
    </div>
    <div class="sidebar-sep special-fx-opacity invisible"></div>
    <div class="sidebar-el">
        <h2 class="special-fx-opacity invisible">Krewetka Cinema, Gdańsk</h2>
    </div>
    <div class="sidebar-sep special-fx-opacity invisible"></div>
    <div class="sidebar-el">
        <h2 class="special-fx-opacity invisible">Houses in Mateblewo, Gdańsk</h2>
    </div>
    <div class="sidebar-sep special-fx-opacity invisible"></div>
    <div class="sidebar-el">
        <h2 class="special-fx-opacity invisible">House, Sweden</h2>
    </div>
    <div class="sidebar-sep special-fx-opacity invisible"></div>
    <button class=" button special-fx-opacity invisible">See all</button>

    <div id="social-media">
        <a href="[link censored]" target="_blank"><img src="../../imgs/fb-transparent-icon.png" alt="" class="social-media-icon special-fx-opacity invisible"></a>
        <a href="[link censored]" target="_blank"><img src="../../imgs/yt-logo-transparent.png" alt="" class="social-media-icon special-fx-opacity invisible"></a>
    </div>
</div>

and here are the styles for the elements which are supposed to change color on hover ( added z-index to try fix the problem, but it didn’t help nothing):

.sidebar-el h2{
    text-align: center;
    cursor: pointer;
    font-family: "Montserrat";
    color: #808080;
    line-height: 1.3em;
    font-size: 1.2em;
    font-weight: 200;
    transition-duration: 0.3s;
    z-index: 3;

}

.sidebar-el h2:hover{
    color: #cd1120;
}

along with this, my page has some simple jQuery which is checking the scroll offset, so when an element appears on the screen, it slowly appears with an animation ( somehow this animation works perfect… ), along with making a sidebar sometimes fixed and sometimes not, dependent on offset.

$(window).scroll(function() {
   var hT = $('#photo-gallery-container').offset().top,
       wH = $(window).height(),
       wS = $(this).scrollTop();
    console.log((hT-wH) , wS);

    $('.special-fx-opacity').each(function(i,obj){
        if(wS > ($(obj).offset().top - wH)){
            $(obj).addClass('visible')
            $(obj).removeClass('invisible')
        }
    });
    if (wS > 100){
        $('#sidebar-container').addClass('visible')
        $('#sidebar-container').removeClass('invisible')
    }
    if (wS > wH){
        $('#sidebar-container').addClass('sidebar-container-fixed')
        $('#sidebar-container').removeClass('sidebar-container-stopped-top')
    }
    else{
        $('#sidebar-container').addClass('sidebar-container-stopped-top')
        $('#sidebar-container').removeClass('sidebar-container-fixed')
    }
    if (wS > (hT-wH) ){
        $('#sidebar-container').addClass('sidebar-container-stopped-bottom')
        $('#sidebar-container').removeClass('sidebar-container-fixed')
    }
   //if (wS > (hT- wH) && )
});

I do not know how this JS could affect the whole thing, especially that the whole thing runs just perfect on every other browser ( or even on older versions of chrome ), but I suspect it might actually be correlated, because on my index.html, where there is no sidebar and no scroll offset tracking, every :hover transition works nice even on up-to-date Chrome.

Here’s Chrome 79:
damn thing doesn't work

and here’s Chrome 67:
smooth as butter

I’m totally lost by now, any help appreciated, I’ve got no errors in console by the way…

Advertisement

Answer

Turns out it is a kind of paranormal issue coming from the deeply philosophical inner workings of CSS…

I made a slideshow script (you can actually see it on the gifs), and it changes the width of the photos displayed, thus changing a layout style, which causes the lag. This issue is very nicely described in an excellent article i read recently browsing dev blogs, so it actually came to mind when i started checking if my JS was at fault. ( huge thanks to the author, José Rosário, this is actually very little known, i have never seen this anywhere, and as i just found out, it definetely is practical )

I did all the tests and it indeed turns out that while the animation, transition of the width style is taking place on the Layout rendering phase, the rendering of the box-shadow, color, and other styles in the Painting phase are delayed. These layout changes occured pretty much all the time, every 1.5 seconds, and the animation took about 0.8 seconds.

Still, it’s a very nice looking effect, so i’m going to have to rewrite the whole thing using the super fancy cutting-edge Composite styles, which are faster and will not delay the style changes rendered in the Painting phase, aswell as use truly awe-inspiring GPU-rendering technology, as described in the article if time allows ( deploying the website today ).

Once again, shoutout to the author of that article, you should definetely read it if you deal with advanced front-end. Nobody ever mentioned this to me before, i stumbled upon the article by chance a while ago… The rendering order The order of style rendering in web browsers

EDIT: Instead of making a whole new thing, i made something almost identical very quickly using glide.js, which uses all the fancy tricks described above

EDIT#2: (just to not mislead anybody) seeing the slideshow stuttering i’m not entirely sure glide.js uses ALL the tricks from the article, namely i don’t think the animation is GPU rendered, it looks a litte bit laggy sometimes, but it’s very minimal

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement