CSS Visibility
visibility: hidden makes an element invisible while
keeping its space in the layout — unlike display: none which removes it entirely, and
opacity: 0 which hides it but still allows interaction.
You already know two ways to hide something in CSS.
display: none removes it completely. The element is gone from the layout. Nothing. No space. Other
elements move to fill the gap.
opacity: 0 makes it invisible but keeps the space. The layout is unchanged. And — crucially — the
element is still technically there. You can still click it.
Visibility is the third option. And it sits right between the other two in terms of behavior.
How Visibility Works
.element {
visibility: visible; /* shown — this is the default */
}
.element {
visibility: hidden; /* invisible but space is kept */
}
When you set visibility: hidden the element disappears visually but its space in the layout is
completely preserved. Everything around it stays exactly where it is.
The second card is completely invisible. But the gap where it sits is still there. The first and third cards have not moved at all.
Here is what is happening.
visibility: hidden — the card is invisible. You cannot see it, you cannot click it, screen readers
ignore it. But its 160px width and 100px height are still sitting there in the layout holding space.
The Three Ways to Hide Things — Side by Side
This is the comparison that makes everything clear.
Look at the three rows carefully.
Row 1 — display: none — the Two box is completely gone. One and Three sit right next to each other. No gap. The box does not exist in the layout at all.
Row 2 — visibility: hidden — the Two box is invisible but the gap is there. One and Three are separated by empty space where Two used to be. The layout is unchanged.
Row 3 — opacity: 0 — exactly the same as visibility: hidden visually. The Two box is invisible but the space is kept. One and Three are separated.
Here is what is happening in each case.
display: none — removes the element from the layout entirely. It takes up zero space. Other elements
move to fill the gap.
visibility: hidden — hides the element visually but keeps it in the layout. Space is reserved. Nothing
moves.
opacity: 0 — makes the element fully transparent. Space is kept. Nothing moves. But unlike
visibility: hidden the element is still technically there — you can still click it and interact with it
even though you cannot see it.
When to Use Each One
Here is the honest guide for which to reach for.
display: none — when you want to completely remove something from the page. Menus that close, modals
that dismiss, elements that toggle on and off. This is the most common one.
visibility: hidden — when you want to hide something but keep its space. Like hiding a card in a grid
while keeping the grid structure intact. Or temporarily hiding a column in a table without collapsing the table
layout.
opacity: 0 — almost always paired with a transition for fade animations. You fade something from
opacity 1 to opacity 0 smoothly. Then use display: none after the animation finishes if you want to
remove it from layout too.
The most powerful pattern is combining opacity and visibility together for smooth hide and show animations. Set
opacity: 0 and visibility: hidden on the hidden state. Set opacity: 1 and
visibility: visible on the shown state. Add transition: opacity 0.3s, visibility 0.3s.
This gives you a smooth fade while also making the element truly non-interactive when hidden — unlike
opacity: 0 alone where invisible elements are still clickable.
.tooltip {
opacity: 0;
visibility: hidden;
transition: opacity 0.3s ease, visibility 0.3s ease;
}
.tooltip.show {
opacity: 1;
visibility: visible;
}
Have anything to say about this lesson?
Your feedback helps improve these tutorials. If something was confusing or missing, let us know.