Usage of Display Property of Flex Box Items

Usage of display property of flex box items

From the specifciation:

The display value of a flex item is blockified: if the specified display of an in-flow child of an element generating a flex container is an inline-level value, it computes to its block-level equivalent. (See CSS2.1§9.7 [CSS21] and CSS Display [CSS3-DISPLAY] for details on this type of display value conversion.)

So basically, setting inline-block or block will do nothing as both will get computed to block but you can set table or inline-table and your flex item will behave as a table. Same thing if you set inline-grid or grid

.box {  display: flex;  margin:5px;}
.box>div { height: 50px; width: 100%; background: red; display: grid; grid-template-columns: 200px 1fr; grid-template-rows: 1fr; grid-gap: 20px;}
span { border: 2px solid green;}
<div class="box">  <div>    <span></span>
<span></span> </div></div>
<div class="box"> <div style="display:inline-grid;"> <span></span>
<span></span> </div></div>

What are allowed values of the `display` property for a flex-item? (layout of flex-item’s children is irrelevant)

The only condition for being a flex item is being an in-flow child of a flex container.

Note this means a contiguous run of text can be wrapped inside an anonymous flex item which do not correspond to any element, and an element child of a flex container might not be a flex item if any of the following

  • It is absolutely positioned

    an absolutely-positioned child of a flex container does not participate in flex layout.

  • It has display: contents

    The element itself does not generate any boxes, but its children and
    pseudo-elements still generate boxes as normal. For the purposes of
    box generation and layout, the element must be treated as if it had
    been replaced with its children and pseudo-elements in the document
    tree.

    Its children will become the flex items instead (unless something from this list applies to them).

  • It has display: none

    The element and its descendants generates no boxes.

  • It has box-suppress: discard

    The element generates no boxes at all.

  • It has box-suppress: hide

    The element generates boxes as normal, but those boxes do not
    participate in layout in any way, and must not be displayed.

  • Previously, if a child of a flex container had a display value that generated an anonymous parent, that parent became the flex item instead of the child. This changed and now the child becomes the flex item, and no parent is generated.

Apart from that, yes, the display value should not prevent an element from being a flex item.

Be aware that flex items are blockified, so for example inline-block becomes block, inline-table becomes table, inline-flex becomes flex, etc.

This means that, whatever the specified outer display role, the flex item will always be block-level.

Basically, the display property, when used on a flex item, is only useful to set its inner display layout model, e.g. that you want the flex item to be a flex container for its contents.

A flex item establishes a new formatting context for its
contents. The type of this formatting context is determined by its
display value, as usual. However, flex items themselves are
flex-level boxes, not block-level boxes: they participate in their container’s flex formatting context, not in a block formatting
context.

(The terminology differs a bit, the Display spec says a flex item is block-level in the sense of its outer display role, the Flexbox spec says it's not block-level in the sense that the formatting context in which it participates is not a block one)

What's the difference between display:inline-flex and display:flex?

display: inline-flex does not make flex items display inline. It makes the flex container display inline. That is the only difference between display: inline-flex and display: flex. A similar comparison can be made between display: inline-block and display: block, and pretty much any other display type that has an inline counterpart.1

There is absolutely no difference in the effect on flex items; flex layout is identical whether the flex container is block-level or inline-level. In particular, the flex items themselves always behave like block-level boxes (although they do have some properties of inline-blocks). You cannot display flex items inline; otherwise you don't actually have a flex layout.

It is not clear what exactly you mean by "vertically align" or why exactly you want to display the contents inline, but I suspect that flexbox is not the right tool for whatever you are trying to accomplish. Chances are what you're looking for is just plain old inline layout (display: inline and/or display: inline-block), for which flexbox is not a replacement; flexbox is not the universal layout solution that everyone claims it is (I'm stating this because the misconception is probably why you're considering flexbox in the first place).


1 The differences between block layout and inline layout are outside the scope of this question, but the one that stands out the most is auto width: block-level boxes stretch horizontally to fill their containing block, whereas inline-level boxes shrink to fit their contents. In fact, it is for this reason alone you will almost never use display: inline-flex unless you have a very good reason to display your flex container inline.

What are the most important advantages of using flexbox instead of just using display: inline

...arguments why flexbox is a good alternative to the old inline/float-approach...

Why Flexbox?

For a long time, the only reliable cross-browser compatible tools
available for creating CSS layouts were features like floats and
positioning. These work, but in some ways they're also limiting and
frustrating.

The following simple layout designs are either difficult or impossible
to achieve with such tools in any kind of convenient, flexible way:

  • Vertically centering a block of content inside its parent.

  • Making all the children of a container take up an equal amount of the available width/height, regardless of how much width/height is
    available.

  • Making all columns in a multiple-column layout adopt the same height even if they contain a different amount of content.

MDN flexbox

Proper use of flex properties when nesting flex containers

The scope of a flex formatting context is limited to a parent/child relationship.

This means that a flex container is always the parent and a flex item is always the child. Flex properties work only within this relationship.

Descendants of a flex container beyond the children are not part of flex layout and will not accept flex properties.

You will always need to apply display: flex or display: inline-flex to a parent in order to apply flex properties to the child.

There are certain flex properties that apply only to flex containers (e.g., justify-content, flex-wrap and flex-direction), and there are certain flex properties that apply only to flex items (e.g., align-self, flex-grow and flex).

However, flex items can also be flex containers. In such cases the element can accept all flex properties. Being that each property performs a different function, there is no internal conflict and nothing needs to be overridden.

How to reset 'display' property for flex-item

As Danield has mentioned, all children of a flex container (designated by display: flex or display: inline-flex) are automatically made flex items. There is no display property for a flex item; instead, you set it to some other value depending on how you want the children of the flex item to be laid out. If browsers are recognizing display: flex-item, then they probably have some weird non-standard implementation of "flexbox", because that value has never existed in any incarnation of the Flexbox spec (and I have no idea what exactly it would correspond to if it did).

The initial value of display is inline, so display: initial is equivalent to display: inline. See this answer. What you're trying to do is reset the elements to whatever their default display is as given by browsers. You will need to know this value in advance; for div elements it's display: block.

Unfortunately, this will override the existing table-cell declaration in all browsers, for obvious reasons. In that case, you might as well just stick with the table layout if it already works for you, if you need to support browsers that don't support flexbox.



Related Topics



Leave a reply



Submit