CSS transitions in sync with display property

Update: I don’t recommend using this technique anymore for managing keyboard focus, because changing it triggers browser to recalc styles/layout. There is a better way to do this – with tabindex=-1

Positioning an navigation block outside the visible screen area does not prevent focusing elements resting inside with Tab key. This behavior causes confusion about the current focus position.

Disabling mouse interactions on given element is easy to achieve via pointer-events:none; To disable keyboard interaction for any focusable UI element we need to either set tabindex=-1 or remove it from the DOM with display: none;  property. As we know display property is not animatable for a good reason – changing display property to none removes element from the DOM and as a consequence – triggers browser to recalculate layout, paint and composite. In other words – too many dependencies to take into account for browser to make a smooth transition.

So I decided to go with a simple JS solution, based on transitionEnd event for that. The algorithm is very simple:

Showing:
  1. Change display to block (element is still off screen);
  2. Make a CSS transition;
Hiding:
  1. Make a CSS transition;
  2. Change display to none;

See the Pen CSS transition with display property by Giedrius Karaliunas (@gka) on CodePen.