Equal height columns with centered content in flexbox

橙三吉。 提交于 2019-11-27 21:33:41

The key to this layout is to apply equal heights to the primary flex container.

Then make the flex items nested flex containers, which can center the content of the flex items.

Hence, the top level creates the equal height. The second level does the centering.

(See the note at the bottom for more details.)

Here's an example based on your code structure:

body {
    height: 300px;             /* for demo purposes */
    color: white;
}

flex-container {
    display: flex;             /* primary flex container */
    flex-direction: row;       /* horizontal alignment of flex items
                                      (default value; can be omitted) */
    align-items: stretch;      /* will apply equal heights to flex items
                                      (default value; can be omitted) */
    height: 100%;
}

flex-item {
    display: flex;             /* nested flex container */
    flex-direction: column;    /* vertical alignment of flex items */
    justify-content: center;   /* center flex items vertically */
    align-items: center;       /* center flex items horizontally */
}

flex-item:first-child {
    flex: 3;                   /* consume 3x more free space than sibling */
    background-color: #a333c8;
}

flex-item:last-child {
    flex: 1;
    background-color: #db2828;
}
<flex-container>
    <flex-item><!-- also flex container -->
        <p>Text Text Text</p>
        <p>Text Text Text</p>
        <p>Text Text Text</p>
        <p>Text Text Text</p>
    </flex-item>
    <flex-item><!-- also flex container -->
        <div>Forward</div>
    </flex-item>
</flex-container>

jsFiddle demo


People sometimes consider a flex item and its content to be one element. This is not correct.

The HTML structure of a flex container has three levels:

  • the container
  • the item
  • the content

Therefore, the content inside an item does not represent the item; it represents a separate element.

If the content inside an item is text, it becomes an anonymous element.

From the flexbox spec:

4. Flex Items

Each in-flow child of a flex container becomes a flex item, and each contiguous run of text that is directly contained inside a flex container is wrapped in an anonymous flex item.

That's why, in the solution above, the flex item becomes a flex container. It enables the use of flex properties on the children of the flex item (the content).

You need to give height to your elements

.height {
  height: 300px;
}
.row {
  height: 100%;
}
.row > div {
  height: 100%;
}

Updated fiddle 1

If you want them to center vertical, update above .row > div rule to this

.row > div {
  height: 100%;
  display: flex !important;
  flex-direction: column;
  justify-content: center;
}

Updated fiddle 2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!