前端如何优雅实现0到auto的高度过渡

简介: 各位好,相信大家都知道,最近更新 Chrome 已经支持了 0 到 auto 的高度过渡。但是很多人反映这种特性太新了,出于兼容考虑用不了的。而实际上 calc-size 是可以渐进增强的。今天我就给大家表演一下,0 到 auto 的渐进增强兼容所有浏览器。

各位好,相信大家都知道,最近更新 Chrome 已经支持了 0 到 auto 的高度过渡。但是很多人反映这种特性太新了,出于兼容考虑用不了的。而实际上 calc-size 是可以渐进增强的。今天我就给大家表演一下,0 到 auto 的渐进增强兼容所有浏览器。

我们先搭建一个空白工程化项目

这个示例工程。是一个计数器。

import * as React from "react";
import {
    Component } from "react";

interface AppProps {
    }
interface AppState {
   
    count: number;
}

export default class App extends Component<AppProps, AppState> {
   
    constructor(props: AppProps) {
   
        super(props);
        this.increase = this.increase.bind(this);
        this.decrease = this.decrease.bind(this);
        this.state = {
   
            count: 0
        };
    }

    private decrease() {
   
        this.setState({
   
            count: this.state.count - 1
        });
    }

    private increase() {
   
        this.setState({
   
            count: this.state.count + 1
        });
    }

    render() {
   
        var {
    count } = this.state;
        return <>
            <h1>Hello World!</h1>
            <div>
                <button type="button" onClick={
   this.decrease}>-</button>
                {
   count}
                <button type="button" onClick={
   this.increase}>+</button>
            </div>
        </>;
    }
}

接下来我们创建一个组件

这个组件有展开和收起 2 种状态。修改传入的属性,可以切换 className

import * as React from "react";
import {
    Component } from "react";
import "./CollapseBody.scss";

export interface CollapseBodyProps {
   
    open?: boolean;
}

export class CollapseBody extends Component<CollapseBodyProps> {
   
    render() {
   
        let {
    open, children } = this.props;
        let classList = ["collapse-body"];
        if(open) {
   
            classList.push('collapse-body_open');
        } else {
   
            classList.push('collapse-body_close');
        }
        return <div className={
   classList.join(" ")}>
            {
   children}
        </div>;
    }
}

接下来我们引入组件

直接在刚刚的计数器上改一下,这样在计数的时候就会切换展开收起状态。

import * as React from "react";
import {
    Component } from "react";
import {
    CollapseBody } from "./Components/Collapse/CollapseBody";

interface AppProps {
    }
interface AppState {
   
    count: number;
}

export default class App extends Component<AppProps, AppState> {
   
    constructor(props: AppProps) {
   
        super(props);
        this.increase = this.increase.bind(this);
        this.decrease = this.decrease.bind(this);
        this.state = {
   
            count: 0
        };
    }

    private decrease() {
   
        this.setState({
   
            count: this.state.count - 1
        });
    }

    private increase() {
   
        this.setState({
   
            count: this.state.count + 1
        });
    }

    render() {
   
        var {
    count } = this.state;
        return <>
            <h1>Hello World!</h1>
            <div>
                <button type="button" onClick={
   this.decrease}>-</button>
                {
   count}
                <button type="button" onClick={
   this.increase}>+</button>
            </div>
            <CollapseBody open={
   count % 2 === 0}>
                asdasdas
            </CollapseBody>
        </>;
    }
}

接下来我们看看效果

我们可以看到按钮时 class 在切换

接下来编写样式

展开时高度是 calc-size (auto , size);收起时,高度是 0;在加以 transition 和 overflow 就完成了。

我们试一下,在高版本正常过渡,低版本由于不支持 calc-size (auto, size),于是高度为默认值 auto,没有过渡动画,但是不影响使用。

.collapse-body {
   
    transition: height .3s;
    overflow-y: hidden;
    height: calc-size(auto, size);
}

.collapse-body_close {
   
    height: 0;
}

overflow 和 display 优化

上面代码虽然能用但是还不够完美,有 2 个问题。

  • 首先容器含有 overflow:hidden,会导致内部内容被截断,如果内部内容还有 box-shadow,很容易被截掉。最好是只在过渡时含有 overflow:hidden。
  • 还有收起后应当含有 disaplay:none,否则收起后仍然占据体积,在一些情况下会出现不必要的滚动条。

我们可以使用 animation 进行改造。

.collapse-body_close {
   
    display: none;
}

@supports(height: calc-size(auto, size)) {
   
    .collapse-body_open {
   
        animation: collapseBodyIn .3s;
    }

    .collapse-body_close {
   
        animation: collapseBodyOut .3s;
    }
}

@keyframes collapseBodyIn {
   
    from {
   
        overflow-y: hidden;
        height: 0;
    }

    to {
   
        overflow-y: hidden;
        height: calc-size(auto, size);
    }
}

@keyframes collapseBodyOut {
   
    from {
   
        overflow-y: hidden;
        display: block;
        height: calc-size(auto, size);
    }

    to {
   
        overflow-y: hidden;
        display: block;
        height: 0;
    }
}

出现动画

上面示例首次出现时也有动画,假如不想要首次出现的动画,只有切换时才有动画,可以在组件上控制。

import * as React from "react";
import {
    Component } from "react";
import "./CollapseBody.scss";

export interface CollapseBodyProps {
   
    open?: boolean;
}

export class CollapseBody extends Component<CollapseBodyProps> {
   
    private first = true;
    componentDidMount(): void {
   
        this.first = false;
    }
    render() {
   
        let {
    open, children } = this.props;
        let classList = ["collapse-body"];
        if(!open) {
   
            classList.push('collapse-body_close');
        } else if(!this.first) {
   
            classList.push('collapse-body_open');
        }
        return <div className={
   classList.join(" ")}>
            {
   children}
        </div>;
    }
}

最后看看效果

非常的完美

最后我们再看看低版本浏览器的效果

先点构建,我这里配置的构建脚本已经,包含了语法转义和 polyfill,也用了 anujs,因此 react 的兼容性可以不用操心,我们只看 CSS 效果。

我们直接上难度挑战 IE6,我们发现在在 IE6 中没有过渡效果,而是直接隐藏显示,并不影响实际使用,非常地优雅

视频版:【前端如何优雅实现 0到auto 的高度过渡-哔哩哔哩】 https://b23.tv/KBx7UoQ

目录
相关文章
|
6月前
|
前端开发
前端开发 之 15个页面加载特效下【附完整源码】
本篇文章内容展示了铜钱3D圆环加载、圆环显现加载、扇形百分比加载等页面炫酷加载特效,并给出了完整的代码及注释
342 9
|
6月前
|
存储 人工智能 NoSQL
理解 Agent 记忆:从无状态模型到持久化记忆架构
大语言模型本质无状态,对话历史无法自动留存。Agent需长期记忆支撑连续性任务,但简单堆砌上下文不可行。本文系统阐释Agent记忆的四层架构(工作/情景/语义/程序记忆),及其写入、检索与遗忘机制,并对比Mem0、Letta等主流方案,揭示记忆正成为AI Agent技术栈中独立、标准的关键基础设施。
1367 7
理解 Agent 记忆:从无状态模型到持久化记忆架构
|
6月前
|
存储 监控 数据处理
浏览器自动化能干嘛?三个零门槛实操案例
本文介绍零代码浏览器自动化工具如何解放重复劳动:教培老师作业归档、个人账单统计、打印店接单等场景,仅需拖拽配置即可实现全自动操作。无需编程,识别按钮、提取数据、处理文件、自动回复一气呵成,每天轻松省下数小时。(239字)
|
6月前
|
机器学习/深度学习 数据采集 人工智能
别再从零训练了:用迁移学习“借力打力”,小数据也能玩转大模型
别再从零训练了:用迁移学习“借力打力”,小数据也能玩转大模型
396 15
|
6月前
|
SQL 人工智能 弹性计算
阿里云快速部署OpenClaw,9.9元定制AI助理,快速拥有OpenClaw超级助理!
阿里云推出OpenClaw一键部署方案,新用户首月仅9.9元!零代码、10分钟极速搭建,即可拥有可执行任务、有记忆、高定制的本地优先AI智能体。支持文件管理、邮件处理、代码编写等实操,兼容通义千问等大模型,安全稳定、普惠易用。
635 6
|
6月前
|
数据采集 人工智能 atlas
云端算力新基建:解读 GPT-5.4 mini/nano 背后的业务效能革命
OpenAI于2026年3月推出的GPT-5.4 mini与nano,以卓越性能(OSWorld 72.1%、MCP Atlas 56.1%)和极致性价比(nano仅0.2美元/百万token),助力企业云端AI降本增效。支持主从协同架构与深度业务集成,推动算力新基建落地。
|
6月前
|
存储 弹性计算 网络协议
2026年阿里云服务器ECS购买自定义购买全攻略:从入门到精通
本文为2026阿里云ECS自定义购买全指南,涵盖核心价值、完整流程、配置详解(付费类型、地域网络、实例规格、存储、带宽安全组等)、后续部署及高频FAQ,助用户灵活定制、安全高效上云。
|
6月前
|
监控 BI
Quick BI使用案例15:交叉表中使用多字段组合实现累计利润率计算
本文详解交叉表中使用多字段组合计算月累计利润率计算方案。通过交叉表配置日期累计、多字段组合(利润/订单金额)及动态日期控件,实现月中实时监控经营健康度,助力及时决策纠偏。
|
6月前
|
人工智能 安全 API
OpenClaw(Clawdbot)喂饭级图文指南!阿里云/本地部署+API配置+集成1.5万Skills及避坑指南,打造全能AI助手
2026年,开源AI Agent领域迎来现象级产品——OpenClaw(原Clawdbot)。这款由奥地利独立开发者Peter于2025年11月推出的工具,仅用3个月就以史上最快速度登顶GitHub,Star数突破24万,超越React等经典开源项目,成为开发者与普通用户追捧的“数字世界分身”。其核心魅力在于“本地运行保障隐私+IM无缝接入+1.5万+Skills生态”,打破了传统AI助手“只对话不干活”的局限,真正实现从沟通到任务执行的闭环。
697 4