Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

<hr> inside container with display flex become corrupted

Tags:

css

flexbox

This behavior is a little odd and weird. If there is a container with its display property set to flex and flex-direction to column, the orientation of the <hr> elements inside it will change and become vertical and its height will decrease to fit the height of the line.

html, body {    height: 100%;  }  body {    font-family: sans-serif;  }  .container {    padding: 20px;    height: 100%;    display: flex;    flex-direction: column;    flex-grow: 1;  }
<div class="container">    <h3>Title</h3>    <hr/>    <div class="content">      <p>This is some content</p>    </div>  </div>

Check out this pen.

This behavior is confirmed on Firefox and Chrome. I didn't find any explanation for it. How can I fix it?

like image 242
Ahmad Alfy Avatar asked Dec 18 '15 23:12

Ahmad Alfy


People also ask

What happens when display is Flex?

A flex container expands items to fill available free space or shrinks them to prevent overflow. Most importantly, the flexbox layout is direction-agnostic as opposed to the regular layouts (block which is vertically-based and inline which is horizontally-based).

Can an element be both a flex item and a flex container?

Flex items within a flex container can be laid out either horizontally or vertically, but not both. If you want to lay out items in both dimensions, you'll need to nest a flex container inside another one. In this example we apply display: flex to both the outer container and to the red flex item.

Why do we use display flex?

Flexbox is a one-dimensional layout system that we can use to create a row or a column axis layout. It makes our life easier to design and build responsive web pages without having to use tricky hacks and a lot of float and position properties in our CSS code.


2 Answers

According to HTML5 Rendering - The hr element, it is expected to be rendered with this style:

hr { color: gray; border-style: inset; border-width: 1px; margin: 0.5em auto; } 

Specifically, note margin-left: auto, margin-right: auto.

Those styles are used to center a block element horizontally. According to Calculating widths and margins - Block

If both margin-left and margin-right are auto, their used values are equal. This horizontally centers the element with respect to the edges of the containing block.

In a block layout this effect is only noticeable if the block has an explicit width, otherwise the block will grow to cover all its containing block.

In Flexbox it's similar: the default align-self: auto and align-items: stretch make flex items grow to cover the flex line in the cross axis (horizontal one in column layout), and auto margins can also be used to center.

However, there is a big difference: according to Cross Size Determination, align-self: stretch does not affect flex items with auto margins:

If a flex item has align-self: stretch, its computed cross size property is auto, and neither of its cross-axis margins are auto, the used outer cross size is the used cross size of its flex line, clamped according to the item’s min and max cross size properties. Otherwise, the used cross size is the item’s hypothetical cross size.

Then, you can fix this problem by removing the auto margins:

hr {   margin-left: 0;   margin-right: 0; } 

.container {    padding: 20px;    display: flex;    flex-direction: column;  }  hr {    margin-left: 0;    margin-right: 0;  }
<div class="container">    <h3>Title</h3>    <hr />    <div class="content">      <p>This is some content</p>    </div>  </div>

Alternatively, forcing a certain width through width or min-width would counteract the shrinking (more technically, the lack of stretch) caused by the auto margins.

like image 78
Oriol Avatar answered Oct 09 '22 04:10

Oriol


I found that setting the width of the <hr> too 100% fix the problem. Still odd, I have no idea why this happen.

Here is a pen

like image 38
Ahmad Alfy Avatar answered Oct 09 '22 06:10

Ahmad Alfy