Why does the inline-flex element with clearfix have weird blank space?

I have weird behavior of an inline-flex element when applying clearfix to it. When I set clearfix for an element that has an inline-flex display property, a strange white space appears in front of it:

inline-flex

But when inline-block , the behavior is different:

inline-block

I do not understand why inline-flex has a different behavior than inline-block .. and why it has this weird space.

 .a, .b { border: 1px solid red; } .a { text-align: center; } .b { display: inline-flex; height: 20px; width: 20px; } .cf:before, .cf:after { content: " "; display: table; } .cf:after { clear: both; } 
 <div class="a"> <div class="b cf"></div> </div> 

JSFiddle Demo

+6
source share
3 answers

display: inline-flex

When you use display: inline-flex , you install the flex container.

The initial setting for the flex container is flex-direction: row .

This means that all children in the stream in the container (including pseudo-elements in the stream) will line up in a row. The display value of these children ( table in this case) is overridden / ignored according to the rules of the flex formatting context .

Your flexible container has two flexible elements (pseudo-elements) in one line:

 .a, .b { border: 1px solid red; } .a { text-align: center; } .b { display: inline-flex; height: 20px; width: 20px; } .cf:before, .cf:after { content: "x"; display: table; } .cf:after { clear: both; } 
 <div class="a"> <div class="b cf"></div> </div> 

display: inline-block

When you use display: inline-block , you set the formatting block .

The display property of child elements is respected.

Your pseudo-elements with display: table are block elements that by default occupy the full available width. Therefore, pseudo-hosts create two lines:

 .a, .b { border: 1px solid red; } .a { text-align: center; } .b { display: inline-block; height: 20px; width: 20px; } .cf:before, .cf:after { content: "x"; display: table; } .cf:after { clear: both; } 
 <div class="a"> <div class="b cf"></div> </div> 

vertical-align: baseline

Since both versions of your code use display inline-level values, this causes the vertical-align property to be played, the initial value of which is baseline .

The empty space that you see below div.b when setting display: inline-flex is due to alignment of the baseline.

The empty space that you see below div.b when set to display: inline-block is due to the alignment of the baseline in combination with the effects of two children of the block.

Here is a more detailed explanation: fooobar.com/questions/385890 / ...


Clear property

 .cf:after { clear: both; } 

Your clearfix method is not the source of any white space. In fact, this does not affect your layout and can be safely removed.

You use the clear property only when working with float.

From the specification:

9.5.2 Flow control next to floats: clear Property

This property indicates which sides of the element block (s) cannot be adjacent to an earlier floating field.

There are no floating elements in your layout, but if they were, the float and clear properties are nevertheless ignored in the context of flex formatting.

3. Flex containers: displaying flex and inline-flex values

  • float and clear do not create or exit the flex element and do not exit it.
+3
source

Try setting verical-align: top; into your inline-flex | inline-block inline-flex | inline-block to fix this bias.

https://jsfiddle.net/jeca65my/2/

Thanks @NenadVracar on this solution

+3
source

You should submit your page as flow . Each element of your page is in a stream (DOM). You use the position property to change the position in the stream.

block

Block element Always starts a new line. (i.e.: div)

integrated unit

Elements of string blocks are div blocks, but with inline properties. (i.e.: span)

inline flex

This is used in the same way as inline-block in a stream. It creates an inline container, but with a flex layout.

For your example, an interesting task to focus on the difference between inline-block and inline-flex is to add text to a child div. You will see that your child div changes again as it has text in it. JSFiddle example

EDIT: I found a suggestion about SO that reflects the situation well. thanks @BoltClock for this post :

display: inline-flex does not display flex items in a row. This makes displaying a flexible container inline.

+1
source

All Articles