1
votes

I have a bootstrap 4.1 app. I'm trying to layout a set of 6 cards.

On a wide (landscape) display I want to display 2 rows of 3 columns.

[1] [2] [3]
[4] [5] [6]

But on a narrow (portrait) display, I want to display 3 rows of 2 columns and I want the cards to maintain order going down the column, like this:

[1] [4]
[2] [5]
[3] [6]

The problem I'm having is that it doesn't seem to honor the col-* when the grid is in column direction and I get this:

[1]
[2]
[3]
[4]
[5]
[6]

Here's my markup:

<div class="container">
    <div class="row flex-column flex-md-row">
        <div class="card col-6 col-md-4">
            <h5 class="card-header">Card 1</h5>
            <div class="card-body"></div>
        </div>
        <div class="card col-6 col-md-4">
            <h5 class="card-header">Card 2</h5>
            <div class="card-body"></div>
        </div>
        <div class="card col-6 col-md-4">
            <h5 class="card-header">Card 3</h5>
            <div class="card-body"></div>
        </div>
        <div class="card col-6 col-md-4">
            <h5 class="card-header">Card 4</h5>
            <div class="card-body"></div>
        </div>
        <div class="card col-6 col-md-4">
            <h5 class="card-header">Card 5</h5>
            <div class="card-body"></div>
        </div>
        <div class="card col-6 col-md-4">
            <h5 class="card-header">Card 6</h5>
            <div class="card-body"></div>
        </div>
    </div>
</div>

On the div with the row class I'm defaulting to flex-column to get the columnar direction at narrow widths. I switch to row direction at medium size. That seems to work. On each card div I default to col-6 to get only two columns at small widths and switch to col-4 at medium size to get 3 columns with wider displays.

With wider displays, the grid honors the number of columns. At narrow widths, nothing forces the cards to a second column. What's the best way to handle that?

1
remove the flex-column class for smaller widths, that should display everything as intended, and then to reorder your cards in the way you need, you can define a order-* class on your columns - IvanS95
Either that or set a explicit height on your row, as setting flex-column will keep expanding the row indefinitely since the viewport can grow with it: codepen.io/IvanS95/pen/aQjBdz - IvanS95
also reasonably sure that row is by default set to row for display purposes. - Jhecht

1 Answers

2
votes

You have two approaches to solve this:

First One: Ordering Columns

You could remove the flex-column class from the row to keep the default behavior of the columns, then you can just reorder each column with the order-* classes to set them up in any position you want on the row.

Bootstrap Docs for Ordering Classes

Second Option: Setting a max-height on the row

Since rows are flex containers, they span the entire width of the page if available or otherwise defined, when you set flex-column you basically rotate the row, and since the viewport will keep growing with the page, you should set a max-height on the row so it knows when to wrap its flex-items (columns in this case) to a new column.

.no-order {
   max-height: 300px
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
   <h1>Without Ordering</h1>
    <div class="row no-order flex-column flex-md-row">
        <div class="card col-6 col-md-4">
            <h5 class="card-header">Card 1</h5>
            <div class="card-body"></div>
        </div>
        <div class="card col-6 col-md-4">
            <h5 class="card-header">Card 2</h5>
            <div class="card-body"></div>
        </div>
        <div class="card col-6 col-md-4">
            <h5 class="card-header">Card 3</h5>
            <div class="card-body"></div>
        </div>
        <div class="card col-6 col-md-4">
            <h5 class="card-header">Card 4</h5>
            <div class="card-body"></div>
        </div>
        <div class="card col-6 col-md-4">
            <h5 class="card-header">Card 5</h5>
            <div class="card-body"></div>
        </div>
        <div class="card col-6 col-md-4">
            <h5 class="card-header">Card 6</h5>
            <div class="card-body"></div>
        </div>
    </div>
</div>

<!-- With Ordering -->
<div class="container mt-5">
   <h1>With Column Ordering</h1>
    <div class="row">
        <div class="card col-6 col-md-4 order-1 order-md-1">
            <h5 class="card-header">Card 1</h5>
            <div class="card-body"></div>
        </div>
        <div class="card col-6 col-md-4 order-3 order-md-2">
            <h5 class="card-header">Card 2</h5>
            <div class="card-body"></div>
        </div>
        <div class="card col-6 col-md-4 order-5 order-md-3">
            <h5 class="card-header">Card 3</h5>
            <div class="card-body"></div>
        </div>
        <div class="card col-6 col-md-4 order-2 order-md-4">
            <h5 class="card-header">Card 4</h5>
            <div class="card-body"></div>
        </div>
        <div class="card col-6 col-md-4 order-4 order-md-5">
            <h5 class="card-header">Card 5</h5>
            <div class="card-body"></div>
        </div>
        <div class="card col-6 col-md-4 order-6 order-md-6">
            <h5 class="card-header">Card 6</h5>
            <div class="card-body"></div>
        </div>
    </div>
</div>

Working example: https://codepen.io/IvanS95/pen/aQjBdz