使用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),然后展开到自适应高度,这种方法是无法实现过渡动画的
相关推荐
—Qeyser6 小时前
html 可视化海报模板编辑器
css·html·js
我命由我1234515 小时前
CesiumJS 笔记 - 获取容器中心点、Cartesian3 clone 方法、修改 Cartesian3 对象的高度
前端·javascript·css·前端框架·html·html5·js
FFF_634560231 天前
简单的画板小工具,下载即用
前端·javascript·css
绝世唐门三哥1 天前
CSS 虚线下划线用法指南:text-decoration 完整解析
前端·javascript·css
DsirNg1 天前
用一个登录卡片讲清 CSS 盒模型:padding、border 与 box-sizing 到底如何影响布局
css·padding·box-sizing·表单布局·border·css 盒模型·登录卡片
用户059540174462 天前
把 AI Agent 记忆存储验证从 40 分钟手测压到 3 分钟,pytest + Docker 这套组合太顶了
前端·css
用户059540174463 天前
LangChain Memory 测试踩坑实录:用 pytest 自动化回归对话记忆,我折腾了整整一个周末
前端·css
jjw_zyfx3 天前
css vue vite实现闪烁的呼吸效果
javascript·css·vue.js
Mh4 天前
如何使用GSAP实现一个 `pinned` 滚动楼层叙事?
前端·javascript·css
郭wes代码5 天前
纯 CSS+JS 实战:手搓一张支持自定义的通用金色电子奖状(万字详细拆解)
前端·javascript·css