DEV Community

Ekaterina Vujasinović
Ekaterina Vujasinović

Posted on

Lesser-known CSS display values

If you are just like me and have spent a last couple of years coding without being aware of how many CSS display values are out there, this could be a useful post for you. I will leave out the values that are most widely used (block, inline, inline-block, flex, grid, table with all the internal display values and none) since there are already so many great articles about them.

Table Of Contents

👉 What display is all about
👉 display: inline-flex and display: inline-grid
👉 display: flow-root
👉 display: list-item
👉 display: contents
👉 display: ruby

What display is all about

According to the CSS Display Module Level 3 spec 👇

The display property defines an element’s display type, which consists of the two basic qualities of how an element generates boxes:

👉 the inner display type, which defines the kind of formatting context it generates, dictating how its descendant boxes are laid out.

👉 the outer display type, which dictates how the principal box itself participates in flow layout.

In other words, the inner display type describes the behaviour of element's children, while the outer display type defines whether the element is block-level or inline-level, that is, how it interacts with other, outer elements.

Right now, display property single-value syntax feels kind of incomplete and doesn't always let you specify both inner and outer display type explicitly. Sometimes it's hard to figure out right away how the element behaves.

Luckily, the CSS Display Module Level 3 also defines new, two-value syntax for setting display values, with outer and inner display type values set separately (e.g. block flex instead of just flex). This feature has already been implemented in Firefox, but other browsers don't support it yet.

display: inline-flex and display: inline-grid

Both flex and grid containers are behaving like block items by default, as both flex and grid display values are setting the outer display type to block. This means that each container will occupy the full width available, even if its corresponding HTML element is an inline item (like <span>).

In case we need to modify the outer behaviour of the grid / flex containers, e.g. to position them side-by-side in the same row, 👉inline-flex and inline-grid display values will make them behave like inline elements, without affecting the layout of items inside the containers.

display: flow-root

flow-root is an inner display type value, which means that it sets the inner flow of the elements. In order to properly understand flow-root, we need to dig into something called Block Formatting Context (BFC). There is a definition in the spec, but it's easier to explain with an example.

There are two red <div> elements in CodePen below, with identical children elements and formatted in the same way, except for the display value. The first container has default, block display value, while the second one is an inline-block element. Do you see collapsed margins in the first container? 😱

Top margin of the blue square and bottom margin of the paragraph are somehow ending up outside of the parent element. In the second container, we avoided margins collapsing, since it occurs only between blocks belonging to the same Block Formatting Context and 👉 display value of inline-block creates a brand new BFC.

inline-block is not the only property creating a new BFC, though. What if we want to keep the margins from collapsing, but also keep our container block element, remaining in his own row in layout? Among other hacks, we could do it by setting overflow to hidden, but apparently, this method may have unwanted side effects.

👉 flow-root display value is a solution to our problem as it always generates a block container box and establishes a new BFC for its content. As an inner display type, it is actually short for block flow-root, whereas inline flow-root is identical to inline-block value.

Now we can use display values to create new BFC on both block and inline elements, which can be useful not only when handling margins, but for example, when we need to contain floats without using the clearfix hack.

Rememeber, the two-value syntax is not quite alive yet, so you can't use display: inline flow-root (except in Firefox). 👉 Use display: flow-root (but check the browser support first) and display:inline-block instead.

display: list-item

list-item is the default display value for <li> element. It generates a block box for the content and a separate inline box for the marker. In Firefox, the <summary> element also has list-item default display value, but only if it is the first child of the <details> element.

You can specify image, position and type for the list marker, but not distinct styles (like colors or fonts). However, in Firefox list-item creates a ::marker pseudoelement, which has a wider set of allowable properties.

Yes, I use this one quite a lot, but most of the time I wasn't aware that list items use this special display value. Why does it even matter? Well, in the two-value syntax list-item can be combined with both outer and inner display types, making really long display values (like inline flow-root list-item).😄

display: contents

Display values of contents and none define whether an element generates display boxes at all.

While element with display:none will be removed from the layout together with its descendants, 👉 display value of contents removes only the element from the document tree and its children are replacing it. Use it with care as it is marked as an experimental feature on MDN 🧪, although with fairly good browser support.

It makes it especially beneficial to use with Grid or Flexbox, since only the direct descendants of grid or flex containers are behaving as flex /grid items. In case we need to go down one level and make 'the grandchildren' behave as flex / grid items of the main container, 👉 display:content on the direct child of the main container will prevent it from generating a box, and its children will take its place.

In the example below, both purple rectangles are grid containers with orange rectangles as children and grid items. Yellow rectangles are children of the first orange rectangle. In the second container,👉 first orange rectangle is given display value of contents and is no longer visible. His children (yellow rectangles) are taking his place as grid-items, acting as if they were direct descendants of purple rectangle.😎

display: ruby

Ruby annotations are used for adding explanation or pronunciation to base text (usually to East Asian characters). There are two ways of adding a ruby annotation:

👉 with HTML <ruby> element (and corresponding <rt>, <rb>, <rtc> and <rbc> elements for the internal structure)
👉 with CSS display value of ruby (and corresponding ruby-text, ruby-base,ruby-text-container and ruby-base-container display values for the internal structure)

When to use CSS display: ruby?

For document languages (such as XML) that **do not have pre-defined ruby elements **like HTML does, corresponding elements can be translated to ruby elements with the CSS display: ruby property.

When to use HTML <ruby>?

In all other cases. If you have <ruby> element available, you should use it.

Authors using a language (such as HTML) that supports dedicated ruby markup 👉 should use that markup rather than styling arbitrary elements (like <span>) with ruby display values. Using the correct markup ensures that screen readers and non-CSS renderers can interpret the ruby structures.

—W3C, CSS Ruby Layout Module Level 1

That is, the two aren’t mutually exclusive, but I probably won't use CSS display: ruby very often. I tried them both in Firefox and found some subtle differences in default behaviour, which indicates there is still room to further investigate this matter.🤯

It seems like HTML <ruby> alone is good enough for a simple ruby structure, along with some optional ruby-related CSS properties to fine tune the positioning of the ruby text.

Top comments (4)

adam_cyclones profile image
Adam Crockett • Edited

As long is there is not accessibility implications I will be checking these out. My wierd one for you is

body {
    background: background;
ekaterina_vu profile image
Ekaterina Vujasinović

I have no clue what background: background; does 🤯
There are accessibility implications for display: contents,
Looks like there is a bug which should be solved soon in most browsers.

adam_cyclones profile image
Adam Crockett

background: background; gives you the background colour behind your desktop walpaper of your OS. It's so useless 🤪. I tried out display contents to fix a bug, seems to have done the trick in atleast proving there was a display issue. Thanks for the post.

Thread Thread
ekaterina_vu profile image
Ekaterina Vujasinović

I'm glad it was useful to you!