3

CSS: The Bane of Display None Animations

5 months ago from , Crafting Meaningful Experiences

So I've been through pretty much every Stackoverflow on the topic, and realized that very few threads mention it clearly.

From what I see, the only "clean" CSS way to animate a DOM element when a wrapper goes from display: none to display: block is to explicitly assign an animation to a child element.

Am I missing something? Thanks!

12 comments

  • Erik Fanki, 5 months ago

    You can't animate to or from display: none because that code line takes that element totally out of the flow of content.. It can only be off or on. In other words, the CSS doesn't have any values to create animation "keyframes" from.

    opacity: 0, height: 0 and pointer-events:none takes you a long way.

    Animating height and/or width is to my knowledge easiest with jQuery, as you have to calculate the dimensions of an element in JS to actually animate that in a dynamic way.

    3 points
    • Dan B, 5 months ago

      Makes a ton of sense, thanks Erik!

      I saw some solutions revolving around max-height, but the resulting effect required more hacks since max-height has to be higher than any content height and a max-height value too high would make the animation feel "too fast".

      So yeah I guess you're right, the only clean way would be with some JS. Thanks again!

      0 points
    • Josh Sanders, 5 months ago

      +1 for everything in this post, except the jQuery notion. Relying on a large lib for just animation might be overkill... if 3rd party libs are acceptable in OP's scenario, ive found that this project is super useful and fairly straightforward to implement: https://animejs.com/documentation/

      1 point
      • Dan B, 5 months ago

        It is true that I tend to prefer vanilla JS over jQuery—even though my wordpress themes loads it already '-_-.

        PS: I love the spring functions and the overall structure of AnimeJS. I'm surprised I never heard of that library. Thanks for sharing! I'll definitely play around with it for an upcoming project.

        0 points
  • Jeff DoanJeff Doan, 5 months ago

    You can animate from display none to block, but you do need to use a custom keyframe animation for this. You can't solely transition this property however.

    No need for JS either -- here's a quick fiddle I created.

    You can animate via max-height, but I've never felt the UX is as crisp as a custom animation.

    1 point
    • Dan B, 5 months ago

      Yes, the max-height animation feels a bit wonky. Especially when the content can range from 500px to 1500px, it can make the animation speed very awkward.

      Thanks for the Fiddle too Jeff! The only problem is that my content is stacked so the position absolute part doesn't really apply.

      With that said, using an animation seems to work well with a few wrapper divs to cheat the eye. You can see it on the /psychology link below on this page (I don't want to reshare the link in this thread as that'd feel spammy, also just don't share the link since I'm still dev'ing _').

      Thanks again!

      0 points
      • Jeff DoanJeff Doan, 5 months ago

        Sure thing -- I see now; you're describing an accordion of sorts that you want to animate opening & closing, and for this JS is likely the best option here to be able to control it as crisply as you want =)

        Love your site however -- all the case studies are spot on.

        0 points
  • Fabian SocarrasFabian Socarras, 5 months ago

    If you want to handle animation transitions without the extra jQuery bloat, you might want to checkout Alpine.js https://github.com/alpinejs/alpine

    0 points
    • Dan B, 5 months ago

      Seems like a "Tailwind" but for JS. Interesting, thanks Fabian!

      0 points
  • Adam FuhrerAdam Fuhrer, 5 months ago

    Have you tried playing around with opacity?

    0 points
    • Dan B, 5 months ago

      Hey Adam! Yes I also did. I guess part of my problem was to animate the height while animating the opacity. Height transitions of block elements are bad for performance because of the repaints. I've seen many solutions revolving around this: https://developers.google.com/web/updates/2017/03/performant-expand-and-collapse .

      But my problem is that the element I want to animate isn't "over" the rest.

      It should "push" the blocks below.

      I resorted to an animation within the block it cheats the eye a bit.

      The result is this "instant expand" with the inner content animating: https://growth.design/psychology/ (don't share the link, it's still in dev). Not perfect but it does the job I guess.

      0 points