如何将元素的最大高度从底部向上动画?

6

我有一个HTML菜单元素,目前正在使用JavaScript和CSS进行动画处理。该菜单的最大高度设置为0,使用overflow: hidden隐藏。

<div class="menu">

目前的CSS动画:

.menu {
    -webkit-transition: max-height 0.4s ease;
    -moz-transition: max-height 0.4s ease;
    transition: max-height 0.4s ease;
}

在JavaScript中,当单击按钮时,我正在更改菜单的最大高度。这一切都很好,但是我想要从底部向上显示菜单,而不是自上而下。是否可以在简单的CSS或JS中实现?
3个回答

14
你可以使用 scaleY() 进行转换,然后使用 transform-origin
div {
  transform-origin: 0 100%;
  width: 100px;
  height: 100px;
  background: black;
  transition: transform .5s;
  transform: scaleY(0);
}
body:hover div {
  transform: scaleY(1);
}
<div></div>


1
非常优雅的解决方案!喜欢它! - Christoph
请注意,scaleY() 会扭曲文本。菜单将出现被挤压而不是滑动。 - Joseph Marikle
@JosephMarikle 如果你的意思是“比例尺”,那么是的。然而,它解决了问题,而你的解决方案并没有完全解决 ^_^ - Christoph
我的菜单只包含图像,没有文本。这个解决方案会压缩图像吗? - crestinglight
我提供了另外两种方法,它们各自都有独特的优缺点。如果这个缩放方案不适用于您,也许其中一种可以帮助您。 - Christoph
显示剩余4条评论

5

Michael已经提供了一个非常优雅的解决方案,但它存在一个缩放所有内容的问题。

我想提供另一种方法:当使用position:absolute时,您可以设置bottom:0使其从底部显示。在演示中,我使用了height,因为更容易得到所需的尺寸,但是max-height通常也可以很好地工作。

优点:内容不会缩放
缺点:需要定位和一些固定高度声明

选用最适合您的方法。

.menu {
    background:#bada55;
    transition: all 0.4s ease;
    height:0;
    overflow:hidden;
    position:absolute;
    bottom:0;
    width:100%;
}
.container:hover .menu {
    height:30px;
}
.container{
  position:relative;
  border:1px solid red;
  height:30px;
}
<div class="container">

  <div class="menu">
  Menu content
  </div>
</div>

另一种可能性是通过动画来控制位置。在这里,您只需要操纵 top 属性即可实现滑动效果。

.menu {
  background: #bada55;
  transition: all 0.4s ease;
  overflow: hidden;
  position: relative;
  width: 100%;
  padding:10px;
  height:40px;
  box-sizing:border-box;
  top:100%;
}

.container:hover .menu {
  top:0;
}

.container {
  border: 1px solid red;
  overflow:hidden;
  height:40px;
}
<div class="container">

  <div class="menu">
    Menu content
  </div>
  
</div>


1
你可以使用flexbox。你需要使用align-items: flex-end;将其与底部对齐。

var btn = document.querySelector('button');

btn.addEventListener('click', function(){
  document.querySelector('.menu').classList.toggle('active');
});
.menu {
  max-height: 0;
  overflow: hidden;
  -webkit-transition: max-height 1s ease;
  -moz-transition: max-height 1s ease;
  transition: max-height 1s ease;
  
  background: #eee;
  display: flex;
  align-items: flex-end;
}

.menu.active {
  max-height: 300px;
}

ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
  width: 100%;
}

ul li {
  
}
<button>Toggle Menu</button>

<div class="menu">
  <ul>
    <li>item 1</li>
    <li>item 2</li>
    <li>item 3</li>
    <li>item 4 (last item)</li>
  </ul>
</div>

作为参考,这是没有使用Flexbox对齐的菜单工作方式:

var btn = document.querySelector('button');

btn.addEventListener('click', function(){
  document.querySelector('.menu').classList.toggle('active');
});
.menu {
  max-height: 0;
  overflow: hidden;
  -webkit-transition: max-height 1s ease;
  -moz-transition: max-height 1s ease;
  transition: max-height 1s ease;
  
  background: #eee;
}

.menu.active {
  max-height: 300px;
}

ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
}

ul li {
  
}
<button>Toggle Menu</button>

<div class="menu">
  <ul>
    <li>item 1</li>
    <li>item 2</li>
    <li>item 3</li>
    <li>item 4 (last item)</li>
  </ul>
</div>


1
除非我误解了问题,否则我认为你的解决方案并没有解决问题;) - Christoph
@Christoph 我完全同意。我觉得这三个答案都对 OP 的意思有不同的理解。 - Joseph Marikle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接