一般来说我们遇到高度自适应动画,内容固定差距不大的话,可使用maxHeight设置
css
div{
max-height: 0;
transition: 1s
}
.wrap :hover div{
max-height: 800px /*大概的值,需要超过元素高度*/
}
但是有一个局限性,高度差异越大,过渡效果越糟糕,假设元素真实高度只有 100px
,如果 max-height
为800px
,那只有前1/8
有动画
那么,有没有更好的方式来解决这个问题呢?
在Css Grid中,我们可以使用grid-auto-rows来解决问题。
主要是利用了grid
弹性布局可以实现过渡动画的特点,下面总结一些实现要点
- 高度在设置成
auto
关键词时不会触发transition
过渡动画 grid
布局中的fr
单位,可以用于定义网格轨道大小的弹性系数grid
布局的尺寸计算规则是由最小高度决定的,默认是min-content
,也就是由内部文本决定的,可以通过手动设置min-height
来实现0fr
grid
布局也支持过渡动画(0fr=>1fr
),这样就实现高度不固定的过渡动画- 要使过渡动画生效,必须是
fr
单位,其他单位不行,也不能通过calc
计算 - 这种方法只能实现初始高度为
0
到自适应高度
的过渡变化,略微遗憾
代码如下
ini
<div :class="['option-box', { 'show-v': show }]">
<div>
<el-row :gutter="20">
<el-col
v-for="(item, index) in optionsList"
:span="item.span || 24"
:key="index"
>
<template v-if="item.tag === 'input'">
<el-input
v-bind="{
...commonProps,
...(item.props || {}),
}"
v-on="item.listeners"
v-model="formData[item.code]"
>
<template v-if="item.unit" slot="append">{{
item.unit
}}</template>
</el-input>
</template>
<template v-if="item.tag === 'select'">
<el-select
v-bind="{
...commonProps,
...item.props,
}"
v-on="item.listeners"
v-model="formData[item.code]"
popper-class="tal-info-index-special-option-class"
>
<el-option
v-for="(item, index) in item.options ||
optionsObj[item.dictKey]"
:key="index"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</template>
</el-col>
</el-row>
</div>
</div>
css
css
.option-box {
width: 100%;
display: grid;
grid-template-rows: 0fr;
transition: 0.3s;
overflow: hidden;
&.show-v {
grid-template-rows: 1fr;
}
> div {
min-height: 0;
}
}
注意:必须是0fr,并且0fr不支持`calc`计算
例如你希望默认有一个固定高度(非0),然后展开到自适应高度,这种方法是无法实现过渡动画的