Creating a uniform layout with Flexbox: Equal-height columns with aligned tops

In the application, I have implemented a flexbox layout similar to the code snippet below, containing a group of li elements with three divs in each.

.container {
  width: 500px;
}
ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
}
li {
  border: solid 1px black;
  flex: 1;
}
.title {
  border: solid 1px red;
  margin-bottom: 1em;
}
.content {
  border: solid 1px yellow;
  margin-bottom: 1em;
}
.footer {
  border: solid 1px blue;
}
<div class="container">

  <ul>
    <li>
      <div class="title">
        Blah Blah Blah Blah Blah Blah
      </div>
      <div class="content">
        Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah
      </div>
      <div class="footer">
        Some other stuff here
      </div>
    </li>
    <li>
      <div class="title">
        Blah Blah Blah Blah Blah Blah
      </div>
      <div class="content">
        Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah
      </div>
      <div class="footer">
        Some other stuff here
      </div>
    </li>
    <li>
      <div class="title">
        Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah
      </div>
      <div class="content">
        Blah Blah Blah Blah Blah Blah Blah Blah
      </div>
      <div class="footer">
        Some other stuff here
      </div>
    </li>
  </ul>
</div>

I am in search of a way to ensure that the child divs align horizontally across all columns. For instance, the yellow div tops are aligned, as well as the blue div tops. My previous method involved absolute positioning of the child divs with fixed heights and tops. However, setting fixed heights results in a lot of empty space within the columns, especially on responsive pages where the layout changes.

Most solutions I have come across involve JavaScript or restructuring the HTML markup to prioritize rows over columns. I prefer to maintain the column structure, which supports 1, 2, or 3 columns, and also adapt to a carousel on smaller devices.

Is there a way to achieve this without resorting to JavaScript, or am I limited to that approach?

Answer №1

To achieve the layout you want, consider using display:flex-box. For detailed documentation, you can refer to: https://css-tricks.com/snippets/css/a-guide-to-flexbox/.

I've analyzed your current setup, and it seems that utilizing both flex directions (row & column) would be necessary.

If you're working with borders and aiming to align boxes in a single row, incorporating box-sizing:border-box (which includes borders and padding in the declared width) is essential. Moreover, I've adjusted the width calculation of your columns to maximize the available space in the row, minimizing any guesswork.

You can implement the following code snippet based on your requirements:

        .container * {
            box-sizing: border-box;
        }
            .container {
                width: 500px;
            }
                ul {
                    list-style: none;
                    margin: 0;
                    padding: 0;
                    display: -webkit-box;
                    display: -moz-box;
                    display: -ms-flexbox;
                    display: -webkit-flex;
                    display: flex;
                    -webkit-flex-wrap: wrap;
                    flex-wrap: wrap;
                    flex-direction: row;
                    align-items: stretch;
                    justify-content: center;
                }
                    li {
                        width: calc(100% / 3);
                        border: solid 1px black;
                        box-sizing: border-box;
                        display: -webkit-box;
                        display: -moz-box;
                        display: -ms-flexbox;
                        display: -webkit-flex;
                        display: flex;
                        -webkit-flex-wrap: wrap;
                        flex-wrap: wrap;
                        flex-direction: column;
                        align-items: center;
                        justify-content: space-between;
                    }
                        li > div {
                            width: 100%;
                            padding: 0;
                            margin: 0;
                        }
                        li > div + div {
                            margin-top: 20px;
                        }
                        .title {
                            border: solid 1px red;
                        }
                        .content {
                            border: solid 1px yellow;
                        }
                        .footer {
                            border: solid 1px blue;
                        }
    <div class="container">
        <ul>
            <li>
                <div class="title">
                    Blah Blah Blah Blah Blah Blah
                </div>
                <div class="content">
                    Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah
                </div>
                <div class="footer">
                    Some other stuff here
                </div>
            </li>
            <li>
                <div class="title">
                    Blah Blah Blah Blah Blah Blah
                </div>
                <div class="content">
                    Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah
                </div>
                <div class="footer">
                    Some other stuff here
                </div>
            </li>
            <li>
                <div class="title">
                    Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah
                </div>
                <div class="content">
                    Blah Blah Blah Blah Blah Blah Blah Blah
                </div>
                <div class="footer">
                    Some other stuff here
                </div>
            </li>
        </ul>
    </div>

Answer №2

By adjusting your HTML markup (removing ul li), you can utilize Flexbox to achieve the desired layout. Applying flex: 0 0 33% to each item and enabling flex-wrap: wrap ensures that the items maintain consistent height within each row. Utilize the nth-child() selector to reorder elements into columns.

* {
  box-sizing: border-box;
}
.container {
  width: 500px;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
}
div > div {
  flex: 0 0 33%;
}
div > div:nth-child(3n-2) {
  order: 1;
}
div > div:nth-child(3n-1) {
  order: 2;
}
div > div:nth-child(3n) {
  order: 3;
}
.title {
  border: solid 1px red;
  margin-bottom: 1em;
}
.content {
  border: solid 1px yellow;
  margin-bottom: 1em;
}
.footer {
  border: solid 1px blue;
}
<div class="container">
  <div class="title">
    Blah Blah Blah Blah Blah Blah
  </div>
  <div class="content">
    Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah
  </div>
  <div class="footer">
    Some other stuff here
  </div>

  <div class="title">
    Blah Blah Blah Blah Blah Blah
  </div>
  <div class="content">
    Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah
  </div>
  <div class="footer">
    Some other stuff here
  </div>
  <div class="title">
    Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah
  </div>
  <div class="content">
    Blah Blah Blah Blah Blah Blah Blah Blah
  </div>
  <div class="footer">
    Some other stuff here
  </div>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Add styling to a window popup and close it when focus is lost in Ext JS

I am trying to implement a specific functionality where the popup arrow should be at the edge of the textbox as shown in the image below. How can I achieve this? Additionally, how can I make sure that clicking outside the control destroys the popup instead ...

Insert a triangle shape at the bottom of the material design tab with the class mat-ink-bar

I'm trying to update the appearance of the mat-ink-bar in the Angular material tab. My goal is to achieve a design similar to this: Jsfiddle example The issue I'm facing is that the mat-ink-bar is already positioned as absolute, making it diffi ...

"Refine Your Grid with a Pinterest-Inspired

I've set up a grid of images in columns similar to Pinterest that I would like to filter. The images vary in height but all have the same width. The issue arises when a taller image is followed by a shorter one, causing the short image to float right ...

Troubleshooting problem with text overlaying images upon hovering in CSS

Several months ago, I successfully implemented a cool effect on a Shopify website that I had designed. However, recently the client decided to switch to a new theme without my knowledge, and now one of my CSS tricks is no longer working. If you look at t ...

Creating linear overlays in Tailwind CSS can be achieved by utilizing the `bg-gradient

Is there a way to add a linear background like this using Tailwind CSS without configuring it in tailwind.config.js? The image will be fetched from the backend, so I need the linear effect on the image from bottom to top with a soft background. Here are ...

ngSwitchCase provider not found

While following a tutorial and trying to implement what I learned, I encountered an error that I'm having trouble understanding. The browser console shows an error message stating [ERROR ->]<span *ngSwitchCase="true">, but I can't figure ...

Changing the CSS property from "display: none" to "display: block" using JavaScript causes all the div elements to overlap

My issue involves several radio inputs where clicking one should reveal a hidden div containing information. However, when this div appears, it overlaps with the footer instead of staying positioned between the footer and radio input as intended. I am str ...

Overflow scrollbars do not appear on flex divs

I am struggling with implementing a simple flex container that contains standard divs. The issue I am facing is that the overflow does not display a vertical scroller as desired. In order to achieve this, I have included the following CSS code snippet: #c ...

Page items do not expand to fill the page when zooming out

When I try to zoom out in my browser, the elements within #workspaceMain such as #pagename, #toolbar, #content, and #tabs do not expand to fill the remaining space within #workspaceMain, even though I have set all widths to 100%. The width of #workspaceMai ...

Creating styles for different screen sizes including mobile devices, low-resolution desktops, and high-resolution desktops

One of the techniques I'm using involves analyzing both the horizontal and vertical screen dimensions to differentiate between mobile devices and desktops, as well as distinguish high-resolution from low-resolution desktop displays. In order to achie ...

Utilizing Bootstrap in Laravel to align the heights of rows in adjacent columns

I am in the process of developing a calendar application that includes a header row and a header column. The layout displays six days in columns with a fixed number of time periods per day. <div class="row"> <div class="col-md c ...

Utilize the id in AngularJS to bring attention to a specific row within a table

I am brand new to using angularjs. I currently have a table structured like this: HTML <table class="table table-striped" id="manageResumeTable"> <thead class="text-center text-info text-capitalize"> <th class="text-center col- ...

Ways to stop click propagation in the case of a parent anchor link containing a button among its children

Every time I click on the Link parent, it triggers a click event on the button as well. I want these events to be independent. <Link className="product-item__link" to={`/products/${product.category}/${product.id}`} > <div className ...

Page elements subtly move when reloading in Chrome

I am experiencing an issue with a div that has left and top offsets randomly selected from an array of values upon page load. Most of the time, it works fine. However, occasionally, upon refreshing the page, the window scrolls down slightly, revealing the ...

The CSS in Django seems to be malfunctioning on various pages, particularly on header elements

My CSS file is linked in 'main/static/css/style.css' and my pages are located in 'main/templates/main/pages.html'. However, the CSS does not seem to be working properly for some pages; for example, the h2 tag is not taking on the specif ...

Adjusting the opacity of images in a Bootstrap 4 Jumbotron without affecting the text

Is there a way to apply an opacity of 0.5 to only the background image in my jumbotron, without affecting the text? Currently, when I set the opacity for the background, it also affects the text. How can this be resolved? Below is the custom CSS file: .j ...

Optimizing the appearance of an unordered horizontal list in the most effective manner

When attempting to make lists horizontal and hide default bullets, is it necessary to apply {display:inline} and {float:left} to both the <li> tags or would just one of these properties suffice? <ul> <li><a href="#">First item< ...

Exploring the concept of clip-path

Recently, I have been delving into the world of HTML and CSS, exploring clip-paths after stumbling upon them on this captivating website. My interpretation is that utilizing clip-paths, particularly with the polygon attribute, enables one to control which ...

GWT Designer style issue plaguing development efforts

Currently, I am working on designing a login view using GWT Designer while incorporating styles from Twitter Bootstrap. The structure I have set up is as follows: However, the displayed result does not meet my expectations: Despite setting all CSS paddi ...

The printing function for the window system can cause disruptions to the layout of the table

After creating a page with a simple table that can be filled in and printed, I noticed some issues with the table formatting after printing. The intended table design was supposed to look like this: https://i.stack.imgur.com/aAk89.png However, upon print ...