Galanthus
Galanthus

Reputation: 2290

FadeOut pseudo element transition not working?

I am always able to add fadeIn with a transition. But for some reason, fadeOut never works. Even after setting the opacity to 0 and transition on the parent body/class element.

I am wondering if it is possible to fade out the same like fade in works on click?

Can someone explain what I am doing wrong and if it is possible to do this?

body {
    height: 100%;
    padding: 0;
    margin: 0;
    color: $text-body;
    overflow-x: hidden;
    overflow-y: auto;

    &:after {
        content: '';
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: -10;
        visibility: hidden;
        opacity: 0;
        transition: opacity 1.2s ease-out;
    }

    &.bg-dark {
        &:after {
            background: rgba($color-black, 0.7);
            visibility: visible;
            opacity: 1;
            z-index: 100;
            transition: opacity 1.2s ease-out;
        }
    }

    @if $use-custom-fonts == true {
        font-family: $font-body-custom;
    } @else {
        font-family: $font-body;
    }
}

My JS:

(() => {
    const menuToggle = document.querySelector('[rel="js-menu"]');
    const body = document.body;

    if (!menuToggle) {
        return;
    }

    const sideNav = document.querySelector('[rel="js-side__nav"]');
    const sideNavClose = document.querySelector('[rel="js-side__close"]');

    const openMenu = (e) => {
        sideNav.classList.add('side__nav--open');
        body.classList.add('bg-dark');

        e.preventDefault();
    };

    const closeMenu = (e) => {
        if (sideNav.classList.contains('side__nav--open')) {
            sideNav.classList.remove('side__nav--open');
            body.classList.remove('bg-dark');
        }

        e.preventDefault();
    };

    document.addEventListener('keyup', (e) => {
        if (e.keyCode === 27) {
            if (sideNav.classList.contains('side__nav--open')) {
                sideNav.classList.remove('side__nav--open');
                body.classList.remove('bg-dark');
            }
        }
    });

    menuToggle.addEventListener('click', openMenu);
    sideNavClose.addEventListener('click', closeMenu);
})();

Upvotes: 0

Views: 55

Answers (1)

Jax-p
Jax-p

Reputation: 8551

The problem is visibility: hidden;. It hides your element instantly without transition which has effect only for opacity.

Another problem is that background-color is set only on .bg-dark and transition is set only for opacity. So opacity works but change of background color is instant.

I've provided example with removed visibility and applied background for initial state (without .bg-dark)

(() => {
    const menuToggle = document.querySelector('[rel="js-menu"]');
    const body = document.body;

    if (!menuToggle) {
        return;
    }

    const sideNav = document.querySelector('[rel="js-side__nav"]');
    const sideNavClose = document.querySelector('[rel="js-side__close"]');

    const openMenu = (e) => {
        sideNav.classList.add('side__nav--open');
        body.classList.add('bg-dark');
        e.preventDefault();
    };

    const closeMenu = (e) => {
        if (sideNav.classList.contains('side__nav--open')) {
            sideNav.classList.remove('side__nav--open');
            body.classList.remove('bg-dark');
        }
        e.preventDefault();
    };

    
    menuToggle.addEventListener('click', openMenu);
    sideNavClose.addEventListener('click', closeMenu);
})();
body {
  height: 100%;
  padding: 0;
  margin: 0;
  overflow-x: hidden;
  overflow-y: auto;
}
body:after {
  content: '';
  position: fixed;
  /* moved background style here */
  background: rgba(0, 0, 0, 0.7);
  /* removed visibility */
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  opacity: 0;
  transition: opacity 1.2s ease-out;
}
body.bg-dark:after {
  opacity: 1;
  z-index: -1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div rel="js-side__nav"></div>
<button rel="js-side__close">close</button>
<button rel="js-menu">open</button>

Upvotes: 1

Related Questions