How to do a real css/javascript slide up/down effect

So most people do this wrong or incomplete. You can't do pure css reliably. You can't rely on JavaScript alone. You have to do both but utilize the GPU so its smooth like butter and auto-sizes appropriately for the size of the content or after if things are dynamically added, not needing a max-height property or any crazy workaround. This even works nested inside itself.

Here's how in React but the idea is the same for all:

    componentDidMount() {
        this.wrapper.style.height = this.props.show ? 'auto' : 0
    }

    componentWillReceiveProps(nextProps) {
        if (this.props.show !== nextProps.show) {
            if (nextProps.show) {
                this.wrapper.style.height = `${this.content.offsetHeight}px`
                setTimeout(() => {
                    this.wrapper.style.height = 'auto'
                }, 500)
            } else {
                this.wrapper.style.height = `${this.content.offsetHeight}px`
                setTimeout(() => {
                    this.mySlider.style.height = 0
                }, 100)
            }
        }
    }

and in your CSS

.wrapper {
  overflow: hidden;
  transition: height 0.25s;
}

and your html/jsx is like so

<div className="slider">  
  <div ref={el => this.wrapper = el} className="wrapper">
    <div ref={el => this.content = el} className="content">
      {this.props.children}
    </div>
  </div>
</div>  

You are just setting the height based off the measured inner content and waiting just a moment for the browser to calculate, then set to allow the GPU to do its thing. Setting the height to "auto" after the transition then allows any content placed in dynamically to auto-size without causing further side effects.

Caveat is you must avoid using margins on the outer-most children inside the content area as it screws up the offsetHeight value. The work around is to wrap <div> tags around things you would need margins for and use padding on the wrapper.

You're welcome.