Search code examples
jquerycssflexboxfadeinuser-experience

How do I use jQuery fadeToggle() and CSS flexbox together?


I’ve found some similar answers, but nothing specifically addressing my challenge. I’m sure there’s a simple solution to my question, but I’m a newb with jQuery, so I apologize in advance if I'm being a chucklehead for asking it.

That said…

I have a basic content div with a fadeIn() effect handled by a button click. Currently the content div is styled with flexbox and looks fairly nice. What I’d like to do is to be able to toggle the content div with a fadeIn/fadeOut effect every time the user clicks the button. However, the jQuery fadeToggle() method doesn’t seem to play nice thanks to the flex value of the display property. In similar cases -- minus a toggle -- I’ve just changed the display value from none to flex by doing something like:

$(‘#someElement’).css(‘display’, ‘flex’).hide().fadeIn()

Clunky and probably wrong, but it works. Just not with fadeToggle(). Is there a better way to handle this or should I just skip fadeToggle() and use fadeIn()/fadeOut()?

Thanks in advance for your help.

JSFiddle

<style>
body {
    font-size: 16px;
    color: white;
    padding: 20px;
}

.about-btn {
    background: #0069a6;
    width: 135px;
    height: 35px;
    text-align: center;
    padding-top: 20px;
}
.about-wrapper {
    background: #0069a6;
    box-shadow: 0 20px 80px 0 rgba(0, 0, 0, .45);
    position: absolute;
    bottom: 130px;
    height: 200px;
    width: 500px;
    display: none;
    flex-direction: column;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
}
.about {
    width: 80%;
    height: 50%;
    float: left;
    text-align: justify;
}
.about-close {
    position: absolute;
    top: 10px;
    right: 10px;
    width: 30px;
    height: 30px; 
}
</style>

<div class="about-btn">
  CLICK ME
</div>

<div class="about-wrapper">
  <div class="about-close">
    <span class="about-icon">X</span>
  </div>
  <div class="about">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent a auctor turpis. Aenean eleifend augue eget ex laoreet, eget cursus ante lobortis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent dapibus enim nec nunc bibendum, quis consequat urna laoreet. 
  </div>
</div>

<script>
$('.about-btn').on('click', function(){
  $('.about-wrapper').css("display", "flex").hide().fadeToggle();
})

$('.about-close').on('click', function() {
    $('.about-wrapper').fadeOut();
});
</script>

Solution

  • fadeToggle restores the display type when fading in the element(to the one before it faded out), but only when the initial display is not none. If it's none, jquery has no way to know what display you want after fading in, thus it uses the default block. So yes you have to use fadeIn and fadeOut here as long as you want the element to be hidden initially.

    Also, since you're using flexbox from the new standard, I suggest using css transitions to do animations like fading, which has a better performance since it's natively supported by browsers, while jquery changes the opacity value bit by bit using javascript, which saved our ass in the old times but can be replaced with better solutions now.