如何使用css将元素向上移动到它的可变高度

时间:2014-11-07 22:24:55

标签: html css stylesheet markup

主要问题

我有两个div,一个嵌套在另一个内部,我希望将内部div移到外部div的外部(向上)并在悬停中滑入。

Markup看起来像这样:

<div class="body">
    <div class="inner">Green is variable-height text which slides in on viewport hover</div>
    Blue is a viewport (&lt;body&gt;, visible part of a page), which content should be compressed upon green slide-in
</div>

和(有点伪)css:

.body {
    background: #aaf;
    height: 300px;
    width: 300px;
    overflow: hidden;
}

.inner, .body:hover .inner {
    -webkit-transition:all linear 0.2s;
    transition:all linear 0.2s;
}

.inner {
    background: #afa;
    width: 300px;
    margin-top:-some-magic-to-get-this-div-height;
}

.body:hover .inner {
    margin-top: 0;
}

最终结果动画我想得到,而不使用固定高度的绿色div:

example.gif

此外,这个示例(猜测和硬编码的高度值为2.5em)在jsfiddle上试验:

http://jsfiddle.net/n7vyLoh4/20/

可能部分解决(不满意)

可以部分实现我想要的,使用转换最大高度而不是转换margin-top,max-height: 0; - &gt; max-height: 100%;的转换{ {1}}始终设置 有效,但有两个缺点:

  1. 它没有滑入,它更像是落下窗帘
  2. 它不会在绿色div的末尾停止转换,它会转移到外部蓝色div的末尾,这在反向过渡时特别明显,当它首先从蓝色div的底部一直移动到底部在任何效果可见之前的绿色div。此外,这意味着尽管转换时间设置为0.2秒,但它只会花费一小部分时间来转移绿色div,因为这100%是父div的100%,而不是内部div(我的问题可以回答,如果有的话是一种计算内部div高度100%的方法。
  3. 以下是插图:

    example2.gif

    然后小提琴:

    http://jsfiddle.net/bsd7vnwu/1/

4 个答案:

答案 0 :(得分:4)

我认为这就是你想要的效果。 CSS不允许你在calc()中获得要在定位和边距中使用的元素的高度,因此需要一点JS。

CSS

.body {
    background: #aaf;
    height: 300px;
    width: 300px;
    overflow: hidden;
}

.inner, .body:hover .inner {
    -webkit-transition:all linear 0.2s;
    transition:all linear 0.2s;
}

.inner {
    background: #afa;
    width: 300px;
    overflow: hidden;
}

.body:hover .inner {
    margin-top : 0 !important;
}

JS

Array.prototype.forEach.call(document.getElementsByClassName('inner'), function (item) {
    item.style.marginTop = (item.clientHeight * -1) + 'px';
});

演示

http://jsfiddle.net/09tyLr9b/

答案 1 :(得分:4)

这是纯css解决方案,这意味着它不需要任何脚本,只是支持转换的浏览器:

.body {
    background: #aaf;
    height: 300px;
    width: 300px;
    overflow: hidden;
}

.inner {
    -webkit-transition:all cubic-bezier(0,.81,.4,1) 0.5s;
    transition:all cubic-bezier(0,.81,.4,1) 0.5s;
}

.inner {
    background: #afa;
    width: 300px;
    position: absolute;
    margin-top: -100%;
    float: left;
}

.body:hover .inner {
    position: relative;
    margin-top: 0;
}

而小提琴是here

答案 2 :(得分:3)

我将transition添加到您的小提琴中,以获得我认为您正在寻找的内容

.inner {
    background: #afa;
    width: 300px;
    overflow: hidden;
    max-height: 0;
    transition:0.5s ease-out;
}

.body:hover .inner {
    max-height: 100%;
    transition:0.5s ease-in;
}

JSFIDDLE

并且通过缩短transition:ease-out的时间,当您将鼠标移出div

时,您将获得更具响应性的向上滑动

像这样JSFIDDLE

答案 3 :(得分:1)

2.5年后的另一个CSS解决方案,使用flex layout

&#13;
&#13;
.body {
    background: #aaf;
    height: 300px;
    width: 300px;
    overflow: hidden;
}

.inner {
    display: flex;
    align-items: flex-end;
    -webkit-transition: all cubic-bezier(0, 1, 0, 1) 0.5s;
    transition: all cubic-bezier(0, 1, 0, 1) 0.5s;
    background: #afa;
    max-height: 0;
    overflow: hidden;
}

.body:hover .inner {
    -webkit-transition: all ease-in-out 0.5s;
    transition: all ease-in-out 0.5s;
    max-height: 100%;
}
&#13;
<div class="body">
    <div class="inner">Green is variable-height text which slides in on viewport hover</div>
    Blue is a viewport (&lt;body&gt;, visible part of a page), which content should be compressed 
&#13;
&#13;
&#13;

同样在JSFiddle