Home > other >  Recommended way of hiding elements until animation is complete Tailwind CSS?
Recommended way of hiding elements until animation is complete Tailwind CSS?

Time:11-19

Demo

The text expands in width with the sidebar, when ideally, the transition is much smoother. Maybe delayed so it tricks the eye to thinking it appears only when fully expanded.

How should I think about achieving this?

<div className="flex flex-col items-center space-y-4 w-full mt-8">
<Logo open={open} />
 {open && <div className="h-auto w-3/4 text-xs text-slate-400">This looks weird when the line is super long</div>}

....

Should I attach a delay? transition-delay does nothing on the inner div.

CodePudding user response:

I made an over simplified example, hopefully can help finding a good solution.

This one uses a cross delay approach to make the transition smooth when opening and closing the drawer.

There is a state open controls the drawer. On the drawer container:

open ? "w-52 delay-0" : "w-12 delay-300"

And the inside element uses a reversed delay value, something like:

open ? "opacity-100 delay-300" : "opacity-0 delay-0"

This way, during both opening and closing transition, parent and child elements will have properly ordered animation.

Live demo is here: stackblitz

import React, { useState } from "react";
import "./App.css";

const list = ["Option 1", "Option 2", "Option 3", "Option 4", "Option 5"];

const ListItem = ({ open, text, index }) => {
  return (
    <li className={`bg-teal-100 h-12 flex justify-end`}>
      <div
        className={`${
          open ? "w-24" : "w-12"
        } flex justify-center align-center p-3 transition-all duration-300 ease-in-out`}
      >
        {index   1}
      </div>
      <div
        className={`${
          open ? "opacity-100 delay-300" : "opacity-0 delay-0"
        } flex justify-center align-center p-3 flex-1 transition-all duration-300 ease-in-out`}
      >
        {text}
      </div>
    </li>
  );
};

const SlideDrawer = ({ open }) => {
  return (
    <div
      className={`${
        open ? "w-52 delay-0" : "w-12 delay-300"
      } absolute left-0 top-0 bottom-0 transition-all duration-300 ease-in-out overflow-hidden flex justify-start bg-pink-200`}
    >
      <div className={`w-52 flex flex-col justify-start align-end`}>
        <div
          className={`${
            open ? "w-52 p-6 delay-300" : "w-12 p-3 delay-0"
          } h-72 flex flex-col justify-start align-center transition-all duration-300 ease-in-out `}
        >
          <figure
            className={`${
              open ? "w-40 h-40 delay-300" : "w-6 h-6 delay-0"
            } transition-all bg-teal-100 rounded-full duration-300 ease-in-out`}
          ></figure>
        </div>
        <ul className="w-full flex flex-col list-none">
          {list.map((item, index) => (
            <ListItem key={item} open={open} index={index} text={item} />
          ))}
        </ul>
      </div>
    </div>
  );
};

function App() {
  const [drawerOpen, setDrawerOpen] = useState(false);

  return (
    <>
      <div className="w-full flex justify-end">
        <button
          className="m-6 p-3 rounded-lg bg-slate-300"
          onClick={() => setDrawerOpen((prev) => !prev)}
        >
          Open drawer
        </button>
      </div>
      <SlideDrawer open={drawerOpen} />
    </>
  );
}

export default App;
  • Related