Suggest an editImprove this articleRefine the answer for “CSS display property”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**CSS `display`** - controls how an element participates in layout: block box, inline box, flex/grid container, or nothing at all. `block` takes full width on a new line. `inline` flows inside text and ignores `width`/`height`. `none` removes the element entirely, no space reserved. **Key point:** `inline` ignores explicit dimensions. Use `inline-block` for sized inline elements.Shown above the full answer for quick recall.Answer (EN)Image**CSS `display`** - the property that controls how an element participates in document layout: block box, inline box, flex container, grid container, or nothing at all. ## Theory ### TL;DR - `block` owns the full row: new line, full parent width, dimensions work - `inline` sits inside text flow: no forced line break, ignores explicit `width` and `height` - `inline-block` places inline but respects sizing (the sweet spot for buttons and badges) - `flex` and `grid` turn the element into a layout container for its children - `none` removes the element from layout completely, no space reserved ### Quick example ```html <style> .block { display: block; background: #bcd; margin: 4px 0; } .inline { display: inline; background: #bdc; } .iblock { display: inline-block; background: #dbc; width: 120px; height: 40px; } </style> <div class="block">Block: stretches full width, new line</div> <div class="block">Block: second one stacks below</div> <span class="inline">Inline: flows</span> <span class="inline">next to each other</span> <span class="iblock">inline-block</span> <span class="iblock">respects size</span> ``` Blocks stack vertically and fill the container. Inlines sit side by side and ignore `width: 120px`. `inline-block` does both: flows inline, respects dimensions. ### Key difference: block vs inline Browsers compute `display` during layout to build the box tree. `block` creates a block-level box that starts on a new line and stretches to fill the parent's width. `inline` creates inline boxes that flow horizontally inside the line box and ignore explicit `width` or `height` settings. That gap matters: sizing a `<span>` with `width` does nothing until you switch it to `inline-block`. ### When to use - Full-width sections, cards, navbars -> `block` - Text emphasis, icons inside a sentence -> `inline` - Buttons, badges, image thumbnails with controlled sizing -> `inline-block` - Single-axis alignment: rows of buttons, columns of sidebar links -> `flex` - Two-dimensional layouts: dashboards, page templates, calendar grids -> `grid` - Hiding modals, collapsing error messages, toggling sidebars -> `none` ### Comparison table | Value | Box type | Width/Height | Line break | When to use | |---|---|---|---|---| | `block` | Block box | Full parent width | Yes | Sections, cards, navbars | | `inline` | Inline box | Shrinks to content | No | Text spans, icons in prose | | `inline-block` | Inline-block | Respected | No | Buttons, form inputs | | `flex` | Flex container | Flexible | Yes | Row/column layouts | | `grid` | Grid container | Grid-defined | Yes | 2D layouts, dashboards | | `none` | No box | None | N/A | Hiding elements | ### How the browser handles this CSS engines parse `display` during the cascade, then use it in the layout phase to build the box tree. `block` triggers a block-level containing block. `flex` activates the flex algorithm: it collects children as flex items and distributes free space via `justify-content` and `align-items`. Changing `display` in JavaScript queues a full style recalculation and reflow. `none` is cheapest: the browser skips the subtree entirely, no box is created, no paint happens. One thing I noticed in production: toggling `display` on a large component inside a scroll container causes visible jank because surrounding elements reflow. `visibility: hidden` or `opacity: 0` are cheaper when you only need to hide without removing from flow. ### Common mistakes **Mistake 1: expecting transitions with `display: none`.** ```css /* Wrong - transition has no effect */ .modal { display: none; transition: opacity 0.3s; } /* Fix */ .modal { opacity: 0; visibility: hidden; transition: opacity 0.3s, visibility 0.3s; } .modal.open { opacity: 1; visibility: visible; } ``` `display: none` removes the element instantly. No intermediate state exists, so no transition fires. Use `opacity` with `visibility` when you need a fade effect. **Mistake 2: `inline-block` baseline jumping.** ```css /* Wrong - items align to text baseline, rows look uneven */ .card { display: inline-block; } /* Fix */ .card { display: inline-block; vertical-align: top; } ``` `inline-block` aligns to the text baseline by default. Cards of different heights shift up and down in a way that looks broken. `vertical-align: top` fixes this. **Mistake 3: `display: flex` on `<ul>` without resetting list styles.** ```css /* Wrong - bullets appear outside the flex container */ ul { display: flex; } /* Fix */ ul { display: flex; list-style: none; padding: 0; margin: 0; } ``` **Mistake 4: `display: contents` on a flex item.** `display: contents` makes the element act as if it has no box. Its children become direct participants in the parent flex layout. Apply it to a flex item expecting it to still occupy space, and it disappears from the flex flow. Wrap in a `<div>` if you need the box to stay. ### Real-world usage - React: `display: isOpen ? 'flex' : 'none'` in sidebar and drawer components (Material-UI, Chakra UI) - Tailwind CSS: `hidden`, `block`, `inline-block`, `flex`, `grid` utility classes - Bootstrap: `d-none`, `d-flex`, `d-block` for responsive visibility - styled-components / CSS Modules: `display: grid` for dashboard layouts, `display: flex` for navigation bars ### Follow-up questions **Q:** What is the difference between `display: none` and `visibility: hidden`? **A:** `none` removes the element from layout entirely, no space is reserved, siblings close in. `hidden` hides the element visually but the space stays. Use `hidden` when layout shift would break the design. **Q:** Why does `vertical-align` have no effect on block elements? **A:** `vertical-align` only applies to inline and inline-block boxes. Block elements do not participate in inline formatting context, so the property is ignored. **Q:** When does `display: contents` actually help? **A:** When you have a semantic wrapper (like a `<li>` inside a flex nav) that you do not want to interrupt the flex flow. The wrapper's box disappears but its children are treated as direct flex items. Use with caution: it has known accessibility issues in some browsers. **Q:** `flex` vs `grid` - when to pick which? **A:** Flex handles one axis at a time: a row of buttons, a column of sidebar links. Grid handles both axes simultaneously: a full page layout, a photo gallery with defined rows and columns. They nest freely. **Q (senior):** In a flex container with `flex-direction: column`, why does `align-items: stretch` make children fill the full width, but `margin: auto` on a child centers it horizontally instead? **A:** `align-items: stretch` expands the cross-axis size before margins are resolved. `margin: auto` consumes all remaining free space after the flex algorithm distributes sizes. The spec resolves definite sizes first, then auto margins. So the child gets sized by stretch, but the auto margin overrides alignment by absorbing leftover space. ## Examples ### Block vs inline side by side ```html <!DOCTYPE html> <html> <head> <style> .container { border: 2px solid #333; padding: 10px; } .block { display: block; background: #adf; margin: 4px 0; padding: 4px; } .inline { display: inline; background: #afd; padding: 4px; } </style> </head> <body> <div class="container"> <div class="block">Block 1: takes full width</div> <div class="block">Block 2: stacks below</div> <span class="inline">Inline 1</span> <span class="inline">Inline 2 - same line</span> </div> </body> </html> ``` The two block divs stack vertically. The two inline spans sit next to each other on the same line. Setting `width: 200px` on the inline spans does nothing. ### Sidebar toggle in React ```jsx function Sidebar({ isOpen }) { return ( <nav style={{ display: isOpen ? 'flex' : 'none', flexDirection: 'column', width: 240, background: '#f5f5f5', }} > <a href="/dashboard">Dashboard</a> <a href="/settings">Settings</a> </nav> ); } // isOpen=true -> flex column nav is visible // isOpen=false -> removed from layout, no gap left behind ``` When `isOpen` is false, the nav takes zero space and the main content area expands to fill the gap. This is the standard pattern used in Material-UI drawers and Chakra UI sidebars. ### Auto margin in flex (senior edge case) ```css .toolbar { display: flex; height: 50px; align-items: center; padding: 0 16px; } .logo { flex: none; } .spacer { margin-left: auto; } /* pushes nav to the right edge */ .nav { display: flex; gap: 16px; } ``` ```html <div class="toolbar"> <img class="logo" src="logo.svg" alt="Logo"> <div class="spacer"></div> <nav class="nav"> <a href="/">Home</a> <a href="/docs">Docs</a> </nav> </div> ``` `margin-left: auto` on `.spacer` consumes all free horizontal space, pushing the nav to the right. This is the standard flex trick for a logo-left, nav-right toolbar without absolute positioning.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.