CSS

What is the CSS display property and what are examples of its use?

The short answer

The display property controls how an element participates in the document flow — whether it behaves like a block, sits inline with text, generates a flex or grid container, or disappears from the layout entirely. It's arguably the most fundamental layout property in CSS because it determines the formatting context an element creates for itself and its children.

Block and inline: the two defaults

Every HTML element comes with a default display value. Most fall into one of two camps:

Block elements (display: block) take up the full width available, start on a new line, and stack vertically. Think <div>, <p>, <h1>, <section>. You can set their width, height, margin, and padding in all directions.

Inline elements (display: inline) flow within text, sitting side by side on the same line. Think <span>, <a>, <strong>, <em>. You can set horizontal margin and padding, but vertical margin has no effect, and width and height are ignored — the element is only as big as its content.

/* This won't do what you'd expect */
span {
width: 200px; /* ignored — inline elements can't have width */
height: 100px; /* ignored */
margin-top: 20px; /* ignored */
}

Inline-block: the best of both

display: inline-block gives you an element that flows inline (sits next to other content on the same line) but respects width, height, and vertical margin/padding like a block element.

.tag {
display: inline-block;
padding: 4px 12px;
margin: 4px;
border: 1px solid #ccc;
border-radius: 4px;
}

This is how you'd build something like a row of tags or badges — elements that sit side by side but have box-model dimensions you can control.

display: none vs visibility: hidden

These two look similar but behave very differently:

display: none removes the element from the layout entirely. It takes up no space. Other elements collapse into the gap as if it doesn't exist. Screen readers skip it too.

visibility: hidden hides the element visually, but it still occupies its space in the layout. There's a blank hole where the element would be. Screen readers also skip it.

.removed {
display: none;
} /* gone from layout */
.invisible {
visibility: hidden;
} /* invisible but still taking up space */

Use display: none when you want to fully remove something (like toggling a modal). Use visibility: hidden when you want to hide something without shifting the layout around it (like pre-reserving space for content that hasn't loaded yet).

Flex

display: flex turns an element into a flex container. Its direct children become flex items and can be laid out along a single axis — horizontal by default, vertical with flex-direction: column.

.navbar {
display: flex;
justify-content: space-between;
align-items: center;
}

Flexbox is ideal for one-dimensional layouts: navigation bars, card rows, centering content, distributing space between items. It handles alignment and spacing with very little code.

There's also display: inline-flex, which works the same way but the container itself behaves as an inline element (useful when you want a flex container that sits within a line of text).

Grid

display: grid creates a two-dimensional layout system. You define rows and columns, and children slot into the grid cells.

.dashboard {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
gap: 16px;
}

Grid shines for page-level layouts and anything with rows and columns — dashboards, image galleries, form layouts. Where flex handles one axis at a time, grid handles both simultaneously.

display: inline-grid is the inline variant, same as the flex/inline-flex relationship.

Contents

display: contents is one of the lesser-known values. It makes the element's box disappear — the element itself generates no box, but its children render as if they were direct children of the element's parent.

.wrapper {
display: contents;
}

This is useful when you need a wrapper element for React or accessibility purposes, but you don't want it to interfere with a parent flex or grid layout. The wrapper "unwraps" itself, and its children participate directly in the parent's formatting context.

Table

display: table, display: table-row, and display: table-cell make elements behave like HTML table elements. Before flexbox and grid existed, this was a common hack for vertical centering and equal-height columns.

.row {
display: table;
width: 100%;
}
.cell {
display: table-cell;
vertical-align: middle;
}

You'll still see this in legacy codebases, but in modern CSS there's almost no reason to use table display values for layout. Use actual <table> elements for tabular data, and flex or grid for everything else.

The outer and inner model

Here's something worth understanding at a deeper level. The display property actually controls two things:

  • Outer display — how the element participates in its parent's layout (block or inline)
  • Inner display — what formatting context the element creates for its children (flow, flex, grid, etc.)

When you write display: flex, you're really saying "block on the outside, flex on the inside." The modern multi-keyword syntax makes this explicit:

.container {
display: block flex; /* same as display: flex */
}

.tag {
display: inline flex; /* same as display: inline-flex */
}

Browser support for the two-value syntax is solid in modern browsers, and it makes the mental model clearer even if you don't use it in production yet.

Why interviewers ask this

The display property is one of the first things you reach for when building any layout, so interviewers use it to gauge whether you have a solid grasp of how CSS layout actually works. Knowing the difference between block and inline, understanding when to use flex vs grid, and being able to explain display: none vs visibility: hidden are all signals that you can write CSS intentionally rather than by guesswork.