Search code examples
cssresponsive-designmedia-queriescss-transitions

Apply transition only on hover in and out


I have a following section of css:

.navbar {
  position: fixed;
  display: flex;
  z-index: 3;
  width: 70px;
  background-color: black;
  height: 100%;
  transition: 0.5s;
}

.navbar:hover {
  width: 200px;
}

@media (width < 1080px) {
  .navbar {
    position: sticky;
    transition: none;
    flex-direction: row;
    width: 100%;
    height: 100px;
  }
  
  .navbar:hover {
    width: 100%;
  }
}

It describes a navigation bar that is a sidebar when the viewport is bigger than 1080px. When I hover over it, it stretches to 200px. If the vieport becomes smaller than 1080px, the sidebar becomes horizontal navigation bar.

What I wanted to achieve was a smooth transition of stretching the sidebar on hover and on hover leave. At this moment this works as intended.

What I also wanted was snappy transition from sidebar to horizontal navigation bar and vice versa. Unfortunately it works only partialy. Although I have achieved the snappy transition from sidebar to horizontal navigation bar, I cannot figure out how can I create snappy transition from horizontal navigation bar to sidebar.

I understand what is the problem here (when changing from horizontal navigation bar to sidebar the transtion is set again to 0.5s hence the animation) but I am struggling to figure out how to achieve two-way snappines from sidebar to navbar while maintaining the "hover-in-and-out" transition.

What would be the correct way of achieving such effect ?

Here is example of current state of the sidebar/navbar in jsfiddle: https://jsfiddle.net/mz29afyh/2/


Solution

  • Edited:

    I have no luck either with purely CSS and I think it might have no solution by just in CSS way because the transition is in effect all the time while window resizing.

    When transition is from transition:0.5s to transition:none (screen < 1080, sidebar to navbar), it see a snappy transition because the transition:none is taking effect immediately. Same goes to when transition:none is remove (screen > 1080px, navbar to sidebar), the transition:0.5s is taking effect immediately and that's why it is a smooth transition for all properties.

    But there is a workaround with the help of JS, if you don't mind. Here the result sample : https://jsfiddle.net/qog0s7wb/1/

    The solution is taking from this article: stop animations during window resize. The idea is stop to the transition while window is resizing with a little help from timer function as shown below :

    let resizeTimer;
    
    window.addEventListener("resize", function() {
        $('.navbar').addClass('stop-transition');
      
      window.clearTimeout(resizeTimer);
      
      resizeTimer = setTimeout(() => {
        console.log('remove')
        $('.navbar').removeClass('stop-transition');
      }, 100);
    });
    

    And an additional .stop-transition class :

    .stop-transition {
      transition: none !important;
    }
    

    If you want to remain all transition smoothly, then it is simple, just remove the transition: none; when @media (width < 1080px).

    Hope it helps!