DEV Community

Stas Melnikov
Stas Melnikov

Posted on • Updated on

All nuances about the display property

In my experience, the display property raises a lot of questions for novice developers. Yes, to be honest, I often met confusion from experienced developers too.

I created a live cheat sheet for fixing this situation. Also I talk about most of the nuances of the property in this article.

display: block

Default behavior

1. The width property of elements with display: block fills up all available space by the text direction. The height property of elements with display: block is calculated automatically depending on the content.

If the content of elements with display: block doesn't fit on one line then browsers will move it to a new line.

2. The elements with dispay: block always start on a new line.

Box model features

3. The width and height properties can be set to elements with dispay: block.

4. The padding and border properties can be applied too.

But surprises wait for us when using margins because they might end up outside the parent.

And if we set the border or padding property for the parent, margins stop to end up outside it.

That will work in the case when using vertical paddings or borders but doesn't with horizontal.


When adding padding or borders with only one side margins will stop ending up outside the parent with this side but will still with the opposite.


Margins stop to end up outside the parent after adding the overflow property with a value that's different from visible.

In the case of the parent with a few items margins before the first and after the last element end up outside the parent.

In this case, adding the border, padding and overflow property for the parent ceases this margin behavior.



The margins of adjacent elements with display: block collapse too. The browsers choose the biggest between the two.

The padding, border and overflow properties can't change it.



display: inline

Default behavior

1. The width and height properties of elements with display: inline are calculated automatically depending on the content.

If the content of elements with display: inline doesn't fit on one line then browsers will move it to a new line. The width will be calculated depending on the maximum line length.

2. If there is space elements with display: inline will be on the same line. If no, browsers will move the part of them to a new line.

Box model features

3. The width and height properties can't be set to elements with display: inline.

4. You can set paddings, borders and margins. Vertical values will end up outside the parent.

Also, paddings, borders and margins can overlap paddings and borders of the parent.

Paddings, borders and margins overlap each other if elements with display: inline are in multiple rows.

In the case with multiline elements margins can end up outside by horizontal.

The overflow property crops margins if a value is different from the visible value.

There's no point using margin: auto for elements with display: inline because it won't work.

display: flex

Default behavior

1. The the width property of elements with display: flex fills up all available space by the text direction. The height property is calculated automatically depending on the content height.

If the element has display: block by default we won't see any changes after changing the block value on flex.

And they happen for elements with display: inline. The width property stops depending on the content after the inline value on flex.

If the content of elements with display: flex doesn't fit on one line then browsers will move it to a new line. The width property will equal the width property of the parent.

If we change the block value on flex then we won't see changes as with the width property.

And if we change the inline value to flex the width property stops depending on the maximum line length.

2. By default elements with display: flex are positioned in a column. So if we change the block value to flex elements will save its position.

And if we change the inline value to flex we will get that they are positioned in a column.

Box model features

3. The width and height properties can be set to elements with display: flex. Therefore we don't notice changes when changing the block value to flex.

The width and height properties start to apply after changing the inline value to flex.

4. The padding and border properties can be set for elements with display: flex. If the element has display: block by default we won't see any changes after changing the block value on flex.

And we'll see them after changing the inline value to flex because vertical paddings and borders stop ending up outside the parent.

The margin property works with a few specificities. Since vertical margins of elements with display: block might end up outside the parent, this behavior saves after changing the block value to flex.

However, as with elements with display: block adding the border or padding properties to the parent stops this margins behavior.

If the parent has a few elements with display: block top margins will end up outside it from the first element and the bottom from the last. Changing the block value to flex doesn't cancel that.

As with a single item case, adding the padding or border properties to the parent stops this behavior for elements with display: flex too.

Also, margins between adjacent elements continue collapsing when changing the block value to flex Also. The gap between elements will equal the largest.

And collapsing is saved after adding the padding or border properties.

Since vertical margins of elements with display: inline might end up outside the parent, this behavior saves after changing the inline value to flex.

When changing the inline value to flex, margins don't overlap paddings or margins that are set to the parent.

When we change the inline to flex and the parent has multiline elements top margins will end up outside it for only the first element and bottom margins for the last.

Margins from other elements stop overlapping siblings by vertical. They will be collapsed.

Default behavior of flex items

Note! Flex items are childs of the element with display: flex or display: inline-flex

5. Flex items always are blockified. It means all block values are saved.

All inline values will be changed on block values. So the inline and inline-block values will be changed to block, inline-flex -> flex, inline-grid -> grid and inline-table -> table.

6. The width property of flex items depending on the flex-direction property. If flex-direction: row (default value) the width property is calculated automatically depending on the content and the height property of flex items is equal to the height property of the parent.

Thus the width property stops to be equal to the width property of the parent for elements with display: block. It's calculated depending on the content. The height property doesn't depend on the content and becomes to equal the height property of the parent.

In the case of elements with display: inline we will get the height property is equal to the height property of the parent.

When flex-direction: column the width property of flex items fills up all available space by the text direction and the height property is calculated automatically depending on the content.

As a result, this behavior is the same as the behavior of elements with display: block.

There are changes for elements with display: inline. The width property becomes to be equal to the width parent.

If the content of a flex item doesn't fit on one line then browsers will move it to a new line. The width property will equal the width property of the parent. It doesn't matter that a value is set to the flex-direction property.

As a result, the content of elements with display: block will be displayed the same after adding display: flex to its parent.

The width property of the element with display: inline stops to be calculated depending on the maximum line length.

7. By default flex items position on the same line. If there isn't space, browsers will squeeze them depending on its content.

For this reason elements with display: block stop positioning in a column.

The single change for elements with display: inline is they are squeezed.

Also, a position might be changed using the flex-direction property. If we set the column value flex items will be stacked and stop squeeze.

This behavior repeats for elements with display: block.

In the case of elements with display: inline they stop to be on the same line and will display in a column.

Box model features of flex items

8. The width and height properties can be set to flex items. It doesn't matter which the value is used for the flex-direction.

It's why we won't see some changes after becoming the element with display: block to a flex item.

When it comes to elements with display: inline we already can set the width and height properties after adding display: flex to the parent.

9. The padding and border properties can be set too. They will work without changes for elements with display: block.

When it comes to elements with display: inline vertical paddings and borders stop ending up outside the parent.

The padding and border properties for elements with display: block save their behavior when adding flex-direction: column to the parent.

Adding flex-direction: column doesn't affect the behavior of properties for elements with display: inline in comparison with flex-direction: row.

Pay attention vertical margins don't end up outside the parent. That behavior doesn't depend on the flex-direction property. If we set the row or column value we will get an equal result.

That leads to we'll see changes if we use elements with display: block.

Also, that applies to elements with display: inline.

If the parent has two elements with display: block margins stop ending up outside it from the first element and the bottom from the last.

In the case, we set margins for adjacent elements with display: block they stop collapsing.

display: grid

Default behavior

1. The the width property of elements with display: grid fills up all available space by the text direction. The height property is calculated automatically depending on the content.

If the element has display: block by default we won't see any changes after changing the block value on grid.

And they happen for elements with display: inline. The width property stops depending on the content after the inline value on grid.

If the content of elements with display: grid doesn't fit on one line then browsers will move it to a new line. The width property will equal the width property of the parent.

If we change the block value on grid then we won't see changes as with the width property.

And if we change the inline value to grid the width property stops depending on the maximum line length.

2. By default elements with display: grid are positioned in a column. So if we change the block value to grid elements will save its position.

And if we change the inline value to grid we will get they are positioned in a column.

3. The width and height properties can be set to elements with display: grid. Therefore we don't notice changes when changing the block value to grid.

The width and height properties start to apply after changing the inline value to grid.

4. The padding and border properties can be set for elements with display: grid. If the element has display: block by default we won't see any changes after changing the block value on grid.


And we'll see them after changing the inline value to grid because vertical paddings and borders stop ending up outside the parent.


Since vertical margins of elements with display: block might end up outside the parent, this behavior stops after changing the block value to grid.

However, as with elements with display: block adding the border or padding properties to the parent stops this margins behavior.


As with elements with display: block adding to the parent the overflow property with a value that's different from visible cancels margins behavior.

If the parent has a few elements with display: block top margins will end up outside it from the first element and the bottom from the last. Changing the block value to grid doesn't cancel that.


As with a single item case, adding the padding, border or overflow properties to the parent stops this behavior for elements with display: grid too.






Also, margins between adjacent elements continue collapsing when changing the block value to grid Also. The gap between elements will equal the largest.

And collapsing is saved after adding the padding, border and overflow properties.



Since vertical margins of elements with display: inline might end up outside the parent, this behavior saves after changing the inline value to grid.

When changing the inline value to grid, margins don't overlap paddings or margins that are set to the parent.


When we change the inline to grid and the parent has multiline elements top margins will end up outside it for only the first element and bottom margins for the last.

Margins from other elements stop overlapping siblings by vertical. They will be collapsed.


Also, changing the inline value to grid leads margins again displays when the overflow is applied. The value should be different from the visible.

If we define margin: auto to elements with display: block or display: inline that continues doesn't work after adding display: grid.


Defining the width property to elements with display: block allows work of margins horizontal. That saves after changing the block value on grid.

In addition, changing the inline value on grid allows using margin: auto if the width property is defined to them.

Default behavior of grid items

Note! grid items are childs of the element with display: grid or display: inline-grid

5. Grid items always are blockified. It means all block values are saved.

All inline values will be changed on block values. So the inline and inline-block values will be changed to block, inline-grid -> grid, inline-grid -> grid and inline-table -> table.

6. The width property of grid items is equal to the width property of the parent. The height property tries to fill all space.

Thus the width property keeps being equal to the width property of the parent for childs with display: block. The height property stops depending on the content but looks the same when the height property isn't defined to the parent.


In this case, if it's defined filling all space of the height property is more noticeable.


In the case of childs with display: inline we will get the width property stops depending on the content. The height property looks the same like before if the height property isn't defined to the parent.

If the height property is defined to the parent we will better see how the property stretches.


If the content of a grid item doesn't fit on one line then browsers will move it to a new line. The width property will equal the width property of the parent.

As a result, the content of childs with display: block will be displayed the same after adding display: grid to its parent.

The width property of the childs with display: inline stops to be calculated depending on the maximum line length.

By default, grid items start on a new line. For this reason childs with display: block still saves position.

In contrast to the case with childs with display: block, childs with display: inline changes default position.

Box model features of grid items

8. The width and height properties can be set to grid items. It's why we won't see some changes after changing the display property of the parent with the block value to grid.

When considering childs with display: inline we already can set the width and height properties after adding display: grid to the parent.

9. The padding and border properties can be set too. They will work without changes for childs with display: block.


When it comes to childs with display: inline vertical paddings and borders stop ending up outside the parent.


Pay attention, vertical margins don't end up outside the parent. That leads to we'll see changes if display: block is set to childs.

If the parent has two childs with display: block margins stop ending up outside it from the first child and the bottom from the last.


In the case, we set margins for adjacent childs with display: block they stop collapsing.

Vertical margins of childs with display: inline cease to end up outside the parent when adding display: grid to it.

Also, margins cease to overlap paddings and borders.


When applying margin: auto the width and height properties of the childs are calculated depending on the content after adding display: grid to the parent. All space between the childs and the parent's borders will be shared evenly.

We'll see the width property stops to be equal to the width property of the parent after changing the block value on grid.

The width and height properties keep behavior after changing the inline value on grid.

Adding margin: auto to grid items stops filling all space of the width and height properties.

P.S.
💪 Get more free tips about CSS directly to your inbox

❤ Thank you so much, my sponsors: Ben Rinehart, Jesse Willard, Tanya Ten, Konstantinos Kapenekakis.

Top comments (12)

Collapse
 
avmantzaris profile image
Alex V. Mantzaris

Great article! Can you explain the 'logic' of the browser (rendering engine) for why the parent needs to have a margin or padding in order to prevent overflow of the child components? I would expect that they should be contained in the parent by default. Why would it be allowed to 'step outside' of the parent? Is there a use-case for that?

Collapse
 
z2lai profile image
z2lai • Edited

Fortunately, this behaviour, related to collapsing margins, isn't random and it falls under the concept of Block Formatting Context. Always try to find the proper terminology so you can research the concepts better. Here's a good article about BFC: smashingmagazine.com/2017/12/under...

Collapse
 
avmantzaris profile image
Alex V. Mantzaris

An amazing link, would never have found it otherwise.

Collapse
 
melnik909 profile image
Stas Melnikov

I'm not sure but I remember that was done because people used HTML and CSS for text. So these styles were created for correct displaying of text

Collapse
 
avmantzaris profile image
Alex V. Mantzaris

So, would you recommend to make a habit of placing some margin/padding in the parent to prevent overflow etc?

Thread Thread
 
melnik909 profile image
Stas Melnikov

Please, a demo for demonstration what you want to make and email on melnik909@ya.ru. I'll check it

Collapse
 
joset98 profile image
joset98

thank you. This information is so valuable

Collapse
 
bhupendersinghbisht profile image
Bhupender singh

Awesome

Collapse
 
alohci profile image
Nicholas Stimpson • Edited

What about list-item, table, inline-table, all the inner table display values, flow-root, contents, none, and out-of-flow block-level elements?

Collapse
 
melnik909 profile image
Stas Melnikov

That will be in the future. I described values that are often used

Collapse
 
kurdoharki1 profile image
Kurdo Harki

Many thanks, i started learning programming 2 months ago and i’m really excited. This information is really useful, thanks

Collapse
 
brvhprince profile image
Prince Takyi Akomea

This is great, because I'm about starting to write code for a UI design and had no idea what I'll be facing with displays.