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

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

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

import * as React from "react";import { Component } from "react";interface AppProps { }interface AppState {
	count: number;
}
export default class App extends Component {	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 <>
			

Hello World!

- {count} +
; } }

接下来我们创建一个组件

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

import * as React from "react";import { Component } from "react";import "./CollapseBody.scss";export interface CollapseBodyProps {
	open?: boolean;
}export class CollapseBody extends Component {
	render() {		let { open, children } = this.props;		let classList = ["collapse-body"];		if(open) {
			classList.push('collapse-body_open');
		} else {
			classList.push('collapse-body_close');
		}		return 
			{children}		
; } }

接下来我们引入组件

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

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 {	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 <>
			

Hello World!

- {count} +
asdasdas ; } }

接下来我们看看效果

我们可以看到按钮时 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 个问题。

我们可以使用 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;
	}
}


请使用浏览器的分享功能分享到微信等