3

Let's say we have a button with an input field where the input field grows to occupy the available space:

enter image description here

When the button is clicked, extra context appears next to the button:

enter image description here

The width of the content is dynamic - we can't hard code it. The input naturally shrinks.

How would you animate the appearance of the dynamic content so it slides from behind the button?

I'm looking for a CSS animations solution.

Playground

Misha Moroshko
  • 166,356
  • 226
  • 505
  • 746
  • Only one way that I know of... It is not CSS only, but almost: https://aerotwist.com/blog/flip-your-animations/ – Josep Feb 21 '19 at 00:42

1 Answers1

4

You can do this with a keyframe animation. The key is setting a max-width greater than how big the element will be. Note that the animation timing takes into account the total max-width.

CSS

.test {
  animation-name: test;
  animation-duration: 1s;
  animation-direction: forwards;
  overflow: hidden;
  white-space: nowrap;
}
@keyframes test {
  0% {
    max-width: 0;
  }
  100% {
    max-width: 200px;
  }
}

and then you need to add the class to your dynamic object

function App() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <div className="container">
      <button onClick={() => setIsOpen(!isOpen)}>
        {isOpen ? "Hide" : "Show"}
      </button>
      {isOpen && <div class='test'>Dynamic Content</div>}
      <input type="text" />
    </div>
  );
}

You can toggle the animation duration and make it happen on removal too if you want but I'll leave it to you to play with.

https://codesandbox.io/s/6wj6z1ppxr

Hinrich
  • 13,485
  • 7
  • 43
  • 66
nathan.medz
  • 1,595
  • 11
  • 21
  • 1
    Very nice nathan. – Bibberty Feb 21 '19 at 00:58
  • @nathan.medz Interesting idea! Mind sharing a full example that includes the removal animation? – Misha Moroshko Feb 21 '19 at 01:12
  • 1
    @MishaMoroshko I've edited the sandbox – nathan.medz Feb 21 '19 at 01:32
  • It's a nice idea but can be problematic if the content is very dynamic. It's especially noticeable when you are hiding the content and `max-height` is way larger than the actual content. There is a noticeable delay in this case. – Misha Moroshko Feb 21 '19 at 04:12
  • @MishaMoroshko That is the downside. One can always work with a cubic-bezier curve to optimize the timing function, though for a perfect solution you will need a script that set the width or height value to animate against. – Asons Feb 21 '19 at 19:29
  • @MishaMoroshko Added a link to the dupe link list to an answer explaining how cubic-bezier work when used in a timing function. – Asons Feb 21 '19 at 19:40
  • @MishaMoroshko As you use Flexbox, this answer might be useful, though animate flex properties is buggy: https://stackoverflow.com/questions/29625037/transition-flex-grow-of-items-in-a-flexbox – Asons Feb 21 '19 at 19:47