CSS transition width from center

I'm working on animating a small menu, not innovative, but just an experiment. This is what I have now:

HTML

<div class="menu">
  <div class="bar"></div>
  <div class="bar"></div>
  <div class="bar"></div>
  <div class="bar"></div>
</div>

SCSS

div.menu {
  width: 24px;
  height: 24px;
  position: relative;
  margin: 48px;
  cursor: pointer;

  div.bar {
    display: block;
    width: 100%;
    height: 2px;
    background-color: #444;
    position: absolute;
    transition: all 0.25s ease-in-out;

    &:nth-child(1) {
    }

    &:nth-child(2) {
     top: 11px;
    }

    &:nth-child(3) {
     top: 11px;
    }

    &:nth-child(4) {
     bottom: 0;
    }
  }

  &.active {

    div.bar {
      &:nth-child(1) {
        width: 0;
    }

    &:nth-child(2) {
      transform: rotate(-45deg);
    }

    &:nth-child(3) {
     transform: rotate(45deg);
    }

    &:nth-child(4) {
     width: 0;
    }
    }
  }
}

JAVASCRIPT

var menu = document.querySelector('.menu');

menu.addEventListener('click', function(){
    menu.classList.toggle('active');
  });

And this is the handle of it in action: https://codepen.io/mikehdesign/pen/eWJKKN

Currently, when menus are active, the top and bottom div.bardecrease their width to 0 to the left. I would like to adjust this so that they reduce their width to the center. I tried spoiling them with fields, but no luck if someone could shed some light or suggest a different approach, if necessary, that would be great.

Mike

+4
source share
2 answers

You can use transform-originfor this:

12px (+ -), :

&.active {
  div.bar {
    &:nth-child(1) {
      transform-origin:12px 12px;
      transform: scale(0);
    }

    &:nth-child(2) {
      transform: rotate(-45deg);
    }

    &:nth-child(3) {
      transform: rotate(45deg);
    }

    &:nth-child(4) {
      transform-origin:12px -12px;
      transform: scale(0);
    }
  }
}

: JsFiddle Link

0

. ( script)

HTML ( )

<input type="checkbox" id="toggle-menu" hidden>
<label for="toggle-menu" class="menu">
  <div class="bar"></div>
  <div class="bar"></div>
  <div class="bar"></div>
</label>

SCSS

//  two step transition    
//  as translate and rotation can't (yet) be animated individually 
//  we use the pseudo elements to split up the animation
// 
//  - bar elements will handle the vertical transform
//  - :after elements will handle rotation/scale

//  variables to control transition time and delay
$transition-time:  300ms;
$transition-delay: 300ms;

.menu {
    width: 24px;
    height: 24px;
    position: relative;
    cursor: pointer;
    display: block;
}
.bar {
    height: 2px;
    position: absolute;
    top: 50%;
    width:100%;

    //  Entering `hamburger` state 
    //  1) add a delay on bars to wait for the :after elements to rotate/scale back 
    //  2) the :after elements have no delay 
    transition: $transition-time $transition-delay; // 1

    &:after { 
        content:''; 
        display:table; 
        background: black; 
        position: inherit; width: inherit; height:inherit;
        transition: $transition-time; // 2
    }

    //  transform the bars into hamburger 
    &:nth-child(1){ transform: translateY(-8px); }
    &:nth-child(3){ transform: translateY(8px);}    
}

//    when toggle-menu checkbox is checked transform to `X`  
[id="toggle-menu"]:checked ~ .menu {
    .bar {
        //  Entering `X` state 
        //  1) to animate bars to the center we simply remove the transform
        //  2) as we are now animating backwards we switch the transition
        //     on the bars and their :after elements
        transform: none;  // 1  
        transition: $transition-time; // 2
        &:after { transition: $transition-time $transition-delay } // 2

        //  rotate the top and bottom :after elements
        &:nth-child(1):after{ transform: rotate(-45deg); }
        &:nth-child(3):after{ transform: rotate(45deg);}         

        //  hide the middle :after by scaling to zero
        //  (when all bars are at the center)
        &:nth-child(2):after{ transform: scale(0); }        
    }
}
0

Source: https://habr.com/ru/post/1675213/


All Articles