display controls whether an element participates in layout and what layout model it uses. visibility and opacity control whether it can be seen, but they do not behave the same way as display: none.
This difference matters for menus, modals, tabs, accordions, validation messages, and responsive content. A hidden element may still take space, receive pointer events, or be available to assistive technology depending on the hiding method.
The display property is the most important CSS property for controlling layout. It determines how an element is rendered in the document flow.
Changing display can completely change how children behave. For example, display: flex turns direct children into flex items, while display: grid turns direct children into grid items.
| Value | Behavior | Examples |
|---|---|---|
| block | Full width, starts on new line, respects width/height | div, p, h1, section |
| inline | Flows with text, ignores width/height, no line break | span, a, strong, em |
| inline-block | Flows inline but respects width/height/margin | Buttons, badges |
| none | Removed from layout entirely - no space taken | Hidden elements |
| flex | Block-level flex container | Navigation, card rows |
| inline-flex | Inline-level flex container | Inline toolbars |
| grid | Block-level grid container | Page layouts |
| inline-grid | Inline-level grid container | Inline grids |
| table | Behaves like a table element | Legacy layouts |
| contents | Element itself disappears, children remain | Wrapper removal |
/* block - full width, new line */
.block-element {
display: block;
width: 300px; /* respected */
margin: 10px 0; /* top/bottom respected */
}
/* inline - flows with text */
.inline-element {
display: inline;
/* width/height ignored */
/* top/bottom margin/padding ignored */
padding: 0 5px; /* left/right padding works */
}
/* inline-block - best of both */
.badge {
display: inline-block;
width: 80px; /* respected */
height: 24px; /* respected */
padding: 2px 8px;
background: #3498db;
color: white;
border-radius: 12px;
text-align: center;
vertical-align: middle;
}
/* none - completely removed from layout */
.hidden { display: none; }
/* Show/hide with JavaScript */
.modal { display: none; }
.modal.active { display: flex; }
/* Responsive show/hide */
.mobile-only { display: none; }
.desktop-only { display: block; }
@media (max-width: 768px) {
.mobile-only { display: block; }
.desktop-only { display: none; }
}
Use display: none when the element should be removed from layout and interaction. Use visibility: hidden when the element should keep its space but disappear. Use opacity: 0 when you need fade animations, but also manage pointer-events and accessibility state when necessary.
| Method | Space in layout | Accessible | Events | Animatable |
|---|---|---|---|---|
| display: none | No - removed | No | No | No |
| visibility: hidden | Yes - space kept | No | No | Yes (discrete) |
| opacity: 0 | Yes - space kept | Yes | Yes | Yes (smooth) |
/* visibility - hides but keeps space */
.invisible { visibility: hidden; }
.visible { visibility: visible; }
/* Parent hidden, child visible - possible with visibility */
.parent { visibility: hidden; }
.parent .child { visibility: visible; } /* child shows through! */
/* This is NOT possible with display:none or opacity:0 */
/* opacity - transparent but still interactive */
.ghost { opacity: 0; } /* invisible but still clickable! */
.semi { opacity: 0.5; }
/* Fade in/out animation - use opacity + visibility together */
.tooltip {
opacity: 0;
visibility: hidden;
transition: opacity 0.2s, visibility 0.2s;
}
.tooltip.show {
opacity: 1;
visibility: visible;
}
/* Accessible hiding - visually hidden but screen-reader accessible */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.lesson-box:empty::before {
content: "CSS Display Visibility block flex none: add visible content";
}
display: none removes the element from layout. visibility: hidden hides it but keeps its layout space.
Yes, unless pointer-events or another interaction rule prevents it.
A span is inline by default. Use inline-block or block if it needs width and height.
Explore 500+ free tutorials across 20+ languages and frameworks.