Opacity & Visibility
CSSThree ways to hide an element — only one of them actually animates. Watch the 'content after' line to see which properties collapse the layout and which preserve it.
opacity
fades smoothly — element still takes up space and still receives pointer events
opacity: 1; transition: opacity 0.5s ease;
visibility
snaps instantly — element still takes up space but receives no pointer events
visibility: visible; /* no interpolation — snaps */
display
snaps and collapses — element removed from layout entirely, 'content after' shifts up
display: block; /* can't transition — instant removal */
concepts
opacity is a numeric value the browser can tween between 0 and 1. visibility and display are keyword properties with no intermediate state — they can only snap.
opacity: 0 and visibility: hidden both keep the element in the layout flow — its space is preserved and siblings don't shift. display: none removes it entirely, collapsing its space.
An opacity: 0 element is invisible but still interactive — it receives clicks and stays in the tab order. Add pointer-events: none to opt out. visibility: hidden removes interactivity automatically.
For animated show/hide: transition opacity for the visual fade, and pair with visibility or pointer-events: none so hidden elements don't trap keyboard focus or intercept clicks.
core pattern
/* Only opacity actually animates */
.fade { opacity: 1; transition: opacity 0.4s ease; }
.fade.hidden { opacity: 0; }
/* visibility snaps — but delay keeps layout until fade is done */
.fade-hide {
opacity: 0;
visibility: hidden;
transition: opacity 0.4s ease,
visibility 0s 0.4s; /* delay matches opacity duration */
}
/* opacity: 0 elements still receive clicks — opt out explicitly */
.hidden-accessible {
opacity: 0;
pointer-events: none;
}