Search code examples
javascripthtmlcssanimation

css animate from top to center


This is my setup. I want content to be hidden just above the top, then on demand animate it to center. Obviously with following css opened class, this animation does not have desired effect (but content is centered when opened class is added).

Can I achieve this with css or I need javascript?

var content = document.querySelector('.content')

document.querySelector('#toggle').addEventListener('click', function() {

  if (content.classList.contains('opened')) {
    content.classList.remove('opened')
  } else {
    content.classList.add('opened')
  }

})
.wrap {
  position: relative;
  width: 300px;
  height: 300px;
  background: #ddd;
  overflow: hidden;
}

.content {
  position: absolute;
  bottom: 100%;
  transition: all 0.5s;
}

.opened {
 transform: translateY(-50%);
 bottom:auto;
 top:50%;
}

#toggle {
  position: absolute;
  top: 0;
  left: 340px;
}
<div class="wrap">
  <div class="content">
    Maecenas eu erat condimentum neque molestie tincidunt. Fusce egestas, est ut fringilla facilisis, quam purus blandit dui, eget egestas mauris nibh ut diam. Phasellus volutpat. Sed fringilla tellus in sem. Curabitur dignissim nunc id arcu. Nulla facilisi.
  </div>
</div>

<a href="#" id="toggle">toggle</a>


Solution

  • You can't animate/transition to auto. It must have a start and end number value.

    The red line is for demo purposes only showing the center of the parent.

    var content = document.querySelector('.content')
    
    document.querySelector('#toggle').addEventListener('click', function() {
    
      if (content.classList.contains('opened')) {
        content.classList.remove('opened')
      } else {
        content.classList.add('opened')
      }
    
    })
    .wrap {
      position: relative;
      width: 300px;
      height: 300px;
      background: #ddd;
      overflow: hidden;
    }
    
    .wrap:after {
      content: "";
      width: 100%;
      background: red;
      position: absolute;
      top: 50%;
      height: 1px;
    }
    
    .content {
      position: absolute;
      bottom: 100%;
      transform: translatey(0%);
      transition: all 0.5s;
    }
    
    .opened {
      bottom: 50%;
      transform: translatey(50%);
    }
    
    #toggle {
      position: absolute;
      top: 0;
      left: 340px;
    }
    <div class="wrap">
      <div class="content">
        Maecenas eu erat condimentum neque molestie tincidunt. Fusce egestas, est ut fringilla facilisis, quam purus blandit dui, eget egestas mauris nibh ut diam. Phasellus volutpat. Sed fringilla tellus in sem. Curabitur dignissim nunc id arcu. Nulla facilisi.
      </div>
    </div>
    
    <a href="#" id="toggle">toggle</a>