bogdan
bogdan

Reputation: 667

How can I properly set the order of divs at different breakpoints?

I am using Bootstrap and I want to achieve the following arrangement:

Numbers indicate how they should be ordered in a column on mobile.

The numbers indicate how I want these divs to be ordered IN A SINGLE COLUMN on mobile. The HTML I tried is here:

<div class="col-xs-12">
<div class="flex-row">
    <div class="col-md-6">
        <div class="order-1">
            <!-- TITLE SUBTITLE -->
        </div>
        <div class="order-md-3">
            <!-- FILM META AND CONTENT -->
        </div>
    </div>

    <div class="col-md-6">
        <div class="order-md-2">
            <!-- FILM POSTER -->
        </div>
        <div class="order-md-4">
            <!-- UNDER POSTER. -->
        </div>
    </div>
</div>

Can anyone tell me what I'm doing wrong here?

Upvotes: 1

Views: 65

Answers (3)

Carol Skelly
Carol Skelly

Reputation: 362360

The simplest solution (no extra CSS or duplicate markup) is to use "floats" in Bootstrap 4. Use the d-md-block class to "disable" the flexbox on larger screens, and then float-* to position the columns. On mobile, the columns will follow their natural order...

      <div class="row d-md-block d-flex">
            <div class="col-md-6 float-left py-2">
                <div class="border">
                    1
                </div>
            </div>
            <div class="col-md-6 float-right py-2">
                <div class="border taller">
                    2 FILM POSTER
                </div>
            </div>
            <div class="col-md-6 float-left py-2">
                <div class="border taller">
                    3 FILM META AND CONTENT
                </div>
            </div>
            <div class="col-md-6 float-left py-2">
                <div class="border">
                    4
                </div>
            </div>
      </div>

https://codeply.com/go/WnnCXNckAy

Upvotes: 1

David Liang
David Liang

Reputation: 21476

There are 3 approaches you can go:

  1. Duplicate your HTML elements and show/hide them accordingly
  2. Display items as flex columns and set fixed height to make it wrapped
  3. Use column-count

Option 1: duplicate elements

The easiest solution would be to duplicate your #2 and #4 onto your left column. On a single column mode on mobile, you show copy of #2 and #4 and hide the right column with d-none. On larger screens, you hide the copy of #2 and #4 with d-md-none but show the right column with d-md-block.

HTML

<div class="container">
    <div class="row">
        <div class="col-md-6">
            <div class="card section-1">
                <div class="card-body">
                    <h6 class="card-title">
                        TITLE SUBTITLE
                    </h6>
                    <p>1</p>
                </div>
            </div>
            <div class="card section-2 d-md-none">
                <div class="card-body">
                    <h6 class="card-title">
                        COPY OF FILM POSTER
                    </h6>
                    <p>COPY OF 2</p>
                </div>
            </div>
            <div class="card section-3">
                <div class="card-body">
                    <h6 class="card-title">
                        FILM META AND CONTENT
                    </h6>
                    <p>3</p>
                </div>
            </div>
            <div class="card section-4 d-md-none">
                <div class="card-body">
                    <h6 class="card-title">
                        COPY OF UNDER POSTER
                    </h6>
                    <p>COPY OF 4</p>
                </div>
            </div>
        </div>
        <div class="col-md-6 d-none d-md-block">
            <div class="card section-2">
                <div class="card-body">
                    <h6 class="card-title">
                        FILM POSTER
                    </h6>
                    <p>2</p>
                </div>
            </div>
            <div class="card section-4">
                <div class="card-body">
                    <h6 class="card-title">
                        UNDER POSTER
                    </h6>
                    <p>4</p>
                </div>
            </div>
        </div>
    </div>
</div>

Demo

https://jsfiddle.net/davidliang2008/L2cwf4z3/11/

enter image description here

enter image description here

Option 2: make sure items are displayed as flex-column and utilize the wrapping

You can't use order if the items are not in the same row / column. That's why your approach didn't work. But that's what leads to this option #2.

Here I set the container to display as d-md-flex and flex-md-column on larger screen, and make sure it wraps with flex-md-wrap! Since it's displayed as flex column, in order to make it wrapped, we need to set a fixed height on the container.

HTML

<div class="container d-md-flex flex-md-column flex-md-wrap">
    <div class="card section-1">
        <div class="card-body">
            <h6 class="card-title">
                TITLE SUBTITLE
            </h6>
            <p>1</p>
        </div>
    </div>
    <div class="card section-2">
        <div class="card-body">
            <h6 class="card-title">
                FILM POSTER
            </h6>
            <p>2</p>
        </div>
    </div>
    <div class="card section-3">
        <div class="card-body">
            <h6 class="card-title">
                FILM META AND CONTENT
            </h6>
            <p>3</p>
        </div>
    </div>
    <div class="card section-4">
        <div class="card-body">
            <h6 class="card-title">
                UNDER POSTER
            </h6>
            <p>4</p>
        </div>
    </div>
</div>

CSS

@media (min-width: 768px) {
    .container {
        height: 40rem;
    }

    .card {
        width: 45%;
    }

    .section-3 {
        order: 2;
    }

    .section-2 {
        order: 3;
    }

    .section-4 {
        order: 4;
    }
}

DEMO

https://jsfiddle.net/davidliang2008/ypvngd7w/32/

enter image description here

This option feels like a hack to me though LOL

Option 3: column-count

You can utilize CSS3 column-count feature! I think this is the cleanest approach!

Because with column-count you can't change the orders of the items, so you have to pre-arrange the items first. Hence #3 has to come before #2.

On smaller screen, you will have to display them as flex-column because you want to use Order to arrange the items as 1,2,3,4.

HTML

<div class="container">
    <div class="card section-1">
        <div class="card-body">
            <h6 class="card-title">
                TITLE SUBTITLE
            </h6>
            <p>1</p>
        </div>
    </div>
    <div class="card section-3">
        <div class="card-body">
            <h6 class="card-title">
                FILM META AND CONTENT
            </h6>
            <p>3</p>
        </div>
    </div>
    <div class="card section-2">
        <div class="card-body">
            <h6 class="card-title">
                FILM POSTER
            </h6>
            <p>2</p>
        </div>
    </div>
    <div class="card section-4">
        <div class="card-body">
            <h6 class="card-title">
                UNDER POSTER
            </h6>
            <p>4</p>
        </div>
    </div>
</div>

CSS

.card {
    text-align: center;
    margin-bottom: 1rem;
}

.container {
    display: flex;
    flex-direction: column;
}

.section-2 {
    height: 20rem;
    order: 2;
}

.section-3 {
    height: 18rem;
    order: 3;
}

.section-4 {
    order:4;
}

@media (min-width: 768px) {
    .container {
        display: block;
        column-count: 2;
    }

    .card {
        display: inline-block;
        width: 100%;
    }
}

DEMO

https://jsfiddle.net/davidliang2008/ve96jx42/9/

enter image description here

Upvotes: 2

Ahmed Maruf
Ahmed Maruf

Reputation: 511

If you keep the same html then you can you flex as display to parent and then set the order of the children. Setting the order in specific breakpoint using media queries should do the work.

Upvotes: 0

Related Questions