The display property in CSS is the rule that decides how a box behaves within the page flow.
So far we have seen that in HTML there are block-level elements, like <div> or <p>, and inline elements, like <span> or <a>. That’s their default behavior. But with CSS we can change it.
display is one of those properties that seems simple at first, and then turns out to be everywhere.
It defines whether an element breaks the line, whether it sits next to others, whether it accepts width and height, whether it disappears, or whether it activates layout systems like Flexbox and Grid.
The normal document flow
By default, the browser places elements following the normal flow. It reads the HTML from top to bottom and draws each box according to its type.
Block-level elements take up all available width and push the following content down.
<div>First box</div>
<div>Second box</div>
Inline elements only take up what is necessary and sit on the same line if they fit.
<p>Text with <span>a highlighted part</span> inside the paragraph.</p>
With display, we can alter this behavior.
display: block
An element with display: block behaves like a block box. It takes up all available width of its container and starts on a new line.
a {
display: block;
}
This is very useful for vertical menus. A link (<a>) is inline by default, so you can only click exactly on the text. If we turn it into a block and add padding, the whole area becomes comfortable to use.
<nav>
<a href="/">Home</a>
<a href="/projects/">Projects</a>
<a href="/contact/">Contact</a>
</nav>
nav a {
display: block;
padding: 12px;
}
This pattern appears very often in side navigation, clickable cards, and buttons built from links.
display: inline
An element with display: inline behaves like text within a line. It doesn’t force a line break and only takes up the space of its content.
li {
display: inline;
}
This could make several list items appear one after another on the same line.
<ul>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
But inline elements have an important limitation: they don’t accept width and height like a normal box.
span {
display: inline;
width: 200px; /* This doesn't behave as you expect */
height: 80px; /* This doesn't either */
}
The browser treats that element as part of the text, not as an independent block.
display: inline-block
inline-block is a pretty handy mix. The element sits inline with others, but internally behaves like a box to which we can give dimensions.
.etiqueta {
display: inline-block;
padding: 0.4rem 0.7rem;
border-radius: 999px;
background-color: #e0f2fe;
}
<p>
Technologies:
<span class="etiqueta">HTML</span>
<span class="etiqueta">CSS</span>
<span class="etiqueta">JavaScript</span>
</p>
This pattern is perfect for badges, tags, small buttons, or elements that need to be on the same line but shaped like a box.
Before Flexbox, inline-block was used extensively for column layouts. Today we use it less for large layouts, but it’s still very useful for small interface pieces.
display: none
display: none removes the element from rendering. The browser acts as if that box didn’t exist.
.oculto {
display: none;
}
This has two important consequences:
- The element takes up no space on the page.
- The element does not appear visually nor is it part of the layout flow.
<p>Before</p>
<p class="oculto">This text is hidden</p>
<p>After</p>
The paragraph “After” will move up to fill the gap. No space is reserved.
An element with display: none will also not be accessible to screen readers under normal conditions. If you want to hide something only visually but keep it available for accessibility, a different technique is needed.
display: flex and display: grid
display also serves to activate modern layout systems.
.contenedor {
display: flex;
}
.galeria {
display: grid;
}
When we set display: flex, the element becomes a flex container and its direct children obey Flexbox rules.
When we set display: grid, the element becomes a grid and its direct children can be placed in rows and columns.
We won’t dive into Flexbox and Grid here, as they will have their own entries. For now, hold onto this idea: display doesn’t just decide if a box is block or inline; it also decides which layout algorithm governs its children.
Hiding elements
visibility: hidden
visibility is not the same as display, but it’s worth seeing here because it’s often confused with it.
.invisible {
visibility: hidden;
}
With visibility: hidden, the element is not visible, but it still occupies its space on the page.
<p>Before</p>
<p class="invisible">This text is not visible, but takes up space</p>
<p>After</p>
The paragraph “After” doesn’t move up because the invisible box is still there.
display: none: disappears and takes up no space.visibility: hidden: disappears, but keeps its space.opacity: 0: not visible, keeps its space and can still receive interaction if we don’t control it.
opacity: 0
Another way to visually hide an element is to make it completely transparent.
.transparente {
opacity: 0;
}
This does not change the layout. The box remains there, takes up space, and can still capture clicks.
.transparente {
opacity: 0;
pointer-events: none;
}
If you don’t want the user to interact with a transparent element, you can add pointer-events: none.
opacity is very useful for fade-in and fade-out animations. display does not animate well because an element cannot gradually go from “doesn’t exist” to “exists”. CSS doesn’t negotiate with ghosts.
