Thomas
Thomas

Reputation: 95

Layout with two equal height columns and one column has two rows

I am developing a forum theme at the moment, and am trying to figure out how to do the last bits, the posts. Example of what I'd like to make:

enter image description here

So the key things to keep in mind here is how User Info and Post Content have different colors, as well as the Post Description in the grid is in the same column as the Post Content.

Using a simple div setup doesn't work, as I need the User Info height to control the height of Post Content and vice versa. Having a wrapper element with the background color of User Info would work, but only if the Post Content is taller than User Info.

I am really just looking for brainstorming here. What would be the best way to go about doing this?


I created a draft of what the final result should look like here:

I created a draft of what the final result should look like here.

It should be fine with the code you have provided altered slightly, but I have some questions.

1) You commented the description has a set height? Does it need to? Worst case scenario I just adjust this height in media queries.

2) I probably need to have some columns within Post description too. As you see in my draft there's a left container with the timestamp (let's call that desc-meta) of the post, and to the right there's a permalink with ID (let's call that desc-ID). There's also a set of post options (Edit, report etc.) between the two (let's call that desc-edit), but aligned to the right side of the description. From my brief understanding of flex I can't figure out how to always keep the desc-meta and desc-ID on the same row, while desc-meta can be moved down if needed on smaller screens.

Upvotes: 5

Views: 3130

Answers (3)

Michael Benjamin
Michael Benjamin

Reputation: 371331

This layout can be achieved with CSS flexbox.

For both columns to have equal height we can use the align-items property, which controls space distribution among flex items on the cross-axis.

The default value is stretch, which enables items to extend the full length of the container.

.container-outer { align-items: stretch; }

We can also use the flex-grow property to control how free space is distributed among flex items in the main-axis.

.post-content { flex-grow: 1; }

The code below renders this (with borders only for demo purposes):

enter image description here

.container-outer {
    display: flex;
    align-items: stretch; /* tells boxes to stretch vertically (default value)  */
    width: 75%; 
    min-height: 250px;
    border: 5px solid mistyrose;   
}
.user-info {
    display: flex;          /* nested flexbox, to enable flex properties */
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width: 25%;
    border: 3px solid red;
    font-family: verdana;
    font-weight: bold;
    font-size: 2em;
    color: red;
    box-sizing: border-box;
    overflow: auto;
}
.container-inner {
    display: flex;         /* nested flexbox */
    flex-direction: column;
    width: 100%;
    border: 3px dashed black;
    overflow: auto;
}
.post-description {
    display: flex;         /* nested flexbox */
    justify-content: center;
    align-items: center;
    height: 50px;          /* fixed height */
    border: 3px solid green;
    font-family: verdana;
    font-weight: bold;
    font-size: 1.5em;
    color: green;
    box-sizing: border-box;
    overflow: auto;
}
.post-content {
    display: flex;          /* nested flexbox */
    justify-content: center;
    align-items: center;
    flex-grow: 1;          /* box takes all available space (stretch, basically) */
    border: 3px solid blue;
    font-family: verdana;
    font-weight: bold;
    font-size: 2em;
    color: blue;
    box-sizing: border-box;
    overflow: auto;
}
<article class="container-outer">
    <section class="user-info">USER<br>INFO</section>
    <div class="container-inner">
        <section class="post-description">POST DESCRIPTION</section>
        <section class="post-content">POST CONTENT</section>
    </div><!-- end .container-inner -->    
</article><!-- end .container-outer -->

jsFiddle

Regardless of how much or how little content is placed in USER INFO or POST CONTENT, both columns will remain equal height.

The container is given a minimum height (min-height: 250px;) to ensure it doesn't get too small if there is no content in either box.

flex-grow is only applied to POST CONTENT because USER INFO already expands full height by inheriting height from the container, and POST DESCRIPTION has a fixed height, so it won't expand.


Browser support: Flexbox is supported by all major browsers, except IE < 10. Some recent browser versions, such as Safari 8 and IE10, require vendor prefixes. For a quick way to add prefixes use Autoprefixer. More details in this answer.

Upvotes: 5

Abdul Ahmad
Abdul Ahmad

Reputation: 10021

I would use display: table with the corresponding rows/cells. See this http://jsfiddle.net/ycsmo9vg/ it should be easy extend this for your needs

notice how in the second cell, I have 2 divs, 1 has class row and the second div is plain (no class needed). This is up to you. Since a div is a block level element it will automatically take a row. Though I'd say keep it consistent and have a class of row wherever you have a row

Upvotes: 0

Andrew Carter
Andrew Carter

Reputation: 109

My initial thoughts would be to do something like this:

<div class="one">
</div>
<div class="container">
  <div class="two">
  </div>
  <div class="three">
  </div>
</div>

And then give the left div a display of inline-block and the right container of inline-block, and the inner divs remain block.

.one {
  display: inline-block;
}
.container {
  display: inline-block;
}

Upvotes: 0

Related Questions