使用display: grid解决动态高度动画问题

原文链接

一般来说我们遇到高度自适应动画,内容固定差距不大的话,可使用maxHeight设置

css 复制代码
div{
  max-height: 0;
  transition: 1s
}
.wrap :hover div{
  max-height: 800px /*大概的值,需要超过元素高度*/
}

但是有一个局限性,高度差异越大,过渡效果越糟糕,假设元素真实高度只有 100px,如果 max-height800px,那只有前1/8有动画

那么,有没有更好的方式来解决这个问题呢?

在Css Grid中,我们可以使用grid-auto-rows来解决问题。

主要是利用了grid弹性布局可以实现过渡动画的特点,下面总结一些实现要点

  1. 高度在设置成auto关键词时不会触发transition过渡动画
  2. grid布局中的fr单位,可以用于定义网格轨道大小的弹性系数
  3. grid布局的尺寸计算规则是由最小高度决定的,默认是min-content,也就是由内部文本决定的,可以通过手动设置min-height来实现0fr
  4. grid布局也支持过渡动画(0fr=>1fr ),这样就实现高度不固定的过渡动画
  5. 要使过渡动画生效,必须是fr单位,其他单位不行,也不能通过calc计算
  6. 这种方法只能实现初始高度为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),然后展开到自适应高度,这种方法是无法实现过渡动画的
相关推荐
鸽鸽程序猿1 小时前
【前端】CSS
前端·css
爱上语文11 小时前
HTML和CSS 表单、表格练习
前端·css·html
小肚肚肚肚肚哦12 小时前
盘点浏览器盒模型中各种 width、height 、边距和位置属性
css·html
NightCyberpunk12 小时前
HTML、CSS
前端·css·html
南城FE12 小时前
12个更现代化的CSS单行优化技巧
前端·css
啵咿傲15 小时前
重绘&重排、CSS树&DOM树&渲染树、动画加速 ✅
前端·css
前端Hardy15 小时前
HTML&CSS:数据卡片可以这样设计
前端·javascript·css·3d·html
流烟默15 小时前
CSS中Flex布局应用实践总结
前端·css·flex布局
大G哥17 小时前
我用豆包MarsCode IDE 做了一个 CSS 权重小组件
前端·css
Au_ust21 小时前
css:感觉稍微高级一点的布局
前端·css