ChatGPT解决这个技术问题 Extra ChatGPT

How do I change Bootstrap 3 column order on mobile layout?

I'm making a responsive layout with a top fixed navbar. Underneath I have two columns, one for a sidebar (3), and one for content (9). Which on desktop looks like this

navbar [3][9]

When I resize to mobile the navbar is compressed and hidden, then the sidebar is stacked on top of the content, like this:

navbar [3] [9]

I would like the main content at the top, so I need to change the order on mobile to this:

navbar [9] [3]

I found this article which covers the same points, but the accepted answer has been edited to say that the solution no applies to the current version of Bootstrap.

How can I reorder these columns on mobile? Or alternatively, how can I get the sidbar list-group into my expanding navbar?

Here is my code:


e
emre nevayeshirazi

You cannot change the order of columns in smaller screens but you can do that in large screens.

So change the order of your columns.

<!--Main Content-->
<div class="col-lg-9 col-lg-push-3">
</div>

<!--Sidebar-->
<div class="col-lg-3 col-lg-pull-9">
</div>

By default this displays the main content first.

So in mobile main content is displayed first.

By using col-lg-push and col-lg-pull we can reorder the columns in large screens and display sidebar on the left and main content on the right.

Working fiddle here.


That's exactly what I wanted and your answer made perfect sense, thank you!
@emre, why you specify that just in large? in the official example seems to be working for middle as well. getbootstrap.com/css/#grid
I have been wondering what the push and pull classes are good for - now I know. Thanks.
Shortly after the official release of 3.0 push/pull can be used to change the order of columns at any screen size (xs,sm,md,lg) bootply.com/ft1tOI71cZ
Thanks for this. This beats positioning cols absolutely and such!
Z
Zim

Updated 2018

For the original question based on Bootstrap 3, the solution was to use push-pull.

In Bootstrap 4 it's now possible to change the order, even when the columns are full-width stacked vertically, thanks to Bootstrap 4 flexbox. OFC, the push pull method will still work, but now there are other ways to change column order in Bootstrap 4, making it possible to re-order full-width columns.

Method 1 - Use flex-column-reverse for xs screens:

<div class="row flex-column-reverse flex-md-row">
    <div class="col-md-3">
        sidebar
    </div>
    <div class="col-md-9">
        main
    </div>
</div>

Method 2 - Use order-first for xs screens:

<div class="row">
    <div class="col-md-3">
        sidebar
    </div>
    <div class="col-md-9 order-first order-md-last">
        main
    </div>
</div>

Bootstrap 4(alpha 6): http://www.codeply.com/go/bBMOsvtJhD
Bootstrap 4.1: https://www.codeply.com/go/e0v77yGtcr

Original 3.x Answer

For the original question based on Bootstrap 3, the solution was to use push-pull for the larger widths, and then the columns will show is their natural order on smaller (xs) widths. (A-B reverse to B-A).

<div class="container">
    <div class="row">
        <div class="col-md-9 col-md-push-3">
            main
        </div>
        <div class="col-md-3 col-md-pull-9">
            sidebar
        </div>
    </div>
</div>

Bootstrap 3: http://www.codeply.com/go/wgzJXs3gel

@emre stated, "You cannot change the order of columns in smaller screens but you can do that in large screens". However, this should be clarified to state: "You cannot change the order of full-width "stacked" columns.." in Bootstrap 3.


C
Chris Moschini

Bootstrap 3 Answer

The answers here work for just 2 cells, but as soon as those columns have more in them it can lead to a bit more complexity. I think I've found a generalized solution for any number of cells in multiple columns.

Goals

Get a vertical sequence of tags on mobile to arrange themselves in whatever order the design calls for on tablet/desktop. In this concrete example, one tag must enter flow earlier than it normally would, and another later than it normally would.

Mobile

[1 headline]
[2 image]
[3 qty]
[4 caption]
[5 desc]

Tablet+

[2 image  ][1 headline]
[         ][3 qty     ]
[         ][5 desc    ]
[4 caption][          ]
[         ][          ]

So headline needs to shuffle right on tablet+, and technically, so does desc - it sits above the caption tag that precedes it on mobile. You'll see in a moment 4 caption is in trouble too.

Let's assume every cell could vary in height, and needs to be flush top-to-bottom with its next cell (ruling out weak tricks like a table).

As with all Bootstrap Grid problems step 1 is to realize the HTML has to be in mobile-order, 1 2 3 4 5, on the page. Then, determine how to get tablet/desktop to reorder itself in this way - ideally without Javascript.

The solution to get 1 headline and 3 qty to sit to the right not the left is to simply set them both pull-right. This applies CSS float: right, meaning they find the first open space they'll fit to the right. You can think of the browser's CSS processor working in the following order: 1 fits in to the right top corner. 2 is next and is regular (float: left), so it goes to top-left corner. Then 3, which is float: right so it leaps over underneath 1.

But this solution wasn't enough for 4 caption; because the right 2 cells are so short 2 image on the left tends to be longer than the both of them combined. Bootstrap Grid is a glorified float hack, meaning 4 caption is float: left. With 2 image occupying so much room on the left, 4 caption attempts to fit in the next available space - often the right column, not the left where we wanted it.

The solution here (and more generally for any issue like this) was to add a hack tag, hidden on mobile, that exists on tablet+ to push caption out, that then gets covered up by a negative margin - like this:

[2 image  ][1 headline]
[         ][3 qty     ]
[         ][4 hack    ]
[5 caption][6 desc ^^^]
[         ][          ]

http://jsfiddle.net/b9chris/52VtD/16633/

HTML:

<div id=headline class="col-xs-12 col-sm-6 pull-right">Product Headline</div>
<div id=image class="col-xs-12 col-sm-6">Product Image</div>
<div id=qty class="col-xs-12 col-sm-6 pull-right">Qty, Add to cart</div>
<div id=hack class="hidden-xs col-sm-6">Hack</div>
<div id=caption class="col-xs-12 col-sm-6">Product image caption</div>
<div id=desc class="col-xs-12 col-sm-6 pull-right">Product description</div>

CSS:

#hack { height: 50px; }

@media (min-width: @screen-sm) {
    #desc { margin-top: -50px; }
}

So, the generalized solution here is to add hack tags that can disappear on mobile. On tablet+ the hack tags allow displayed tags to appear earlier or later in the flow, then get pulled up or down to cover up those hack tags.

Note: I've used fixed heights for the sake of the simple example in the linked jsfiddle, but the actual site content I was working on varies in height in all 5 tags. It renders properly with relatively large variance in tag heights, especially image and desc.

Note 2: Depending on your layout, you may have a consistent enough column order on tablet+ (or larger resolutions), that you can avoid use of hack tags, using margin-bottom instead, like so:

Note 3: This uses Bootstrap 3. Bootstrap 4 uses a different grid set, and won't work with these examples.

http://jsfiddle.net/b9chris/52VtD/16632/


Thank you so much for this wonderful explanation. I've working on something similar at work for 3 days now and kept putting down, not knowing where to go. Thank you!
Best... Thank you ❤️
Maybe I'm not understanding, but how can this work if the divs "vary in height" as described in the answer? The listed code and the linked fiddles both explicitly set the height of the hack and the corresponding negative bottom margin to heights that will only be flush because the other divs also have explicitly set heights. If those divs heights are smaller than the hack, we'll have gaps in the next "row", and if they're larger, we'll have content on top of other content.
@PaulL Look at the code more carefully, the height of the problem div is randomized so each view you get a different height, to better demo the varies in height scenario.
@ChrisMoschini is it possible to bring "Product description" as first element in mobile device using bootstrap 3 ? help would be much appreciated !
b
bprdev

October 2017

I would like to add another Bootstrap 4 solution. One that worked for me.

The CSS "Order" property, combined with a media query, can be used to re-order columns when they get stacked in smaller screens.

Something like this:

@media only screen and (max-width: 768px) {
    #first {
        order: 2;
    }
    #second {
        order: 4;
    }
    #third {
        order: 1;
    }
    #fourth {
        order: 3;
    }
}

CodePen Link: https://codepen.io/preston206/pen/EwrXqm

Adjust the screen size and you'll see the columns get stacked in a different order.

I'll tie this in with the original poster's question. With CSS, the navbar, sidebar, and content can be targeted and then order properties applied within a media query.


This solution is very elegant and clear, and may be the best answer. Thanks.
a
ajax333221

In Bootstrap 4, if you want to do something like this:

    Mobile  |   Desktop
-----------------------------
    A       |       A
    C       |   B       C
    B       |       D
    D       |

You need to reverse the order of B then C then apply order-{breakpoint}-first to B. And apply two different settings, one that will make them share the same cols and other that will make them take the full width of the 12 cols:

Smaller screens: 12 cols to B and 12 cols to C

Larger screens: 12 cols between the sum of them (B + C = 12)

Like this

<div class='row no-gutters'>
    <div class='col-12'>
        A
    </div>
    <div class='col-12'>
        <div class='row no-gutters'>
            <div class='col-12 col-md-6'>
                C
            </div>
            <div class='col-12 col-md-6 order-md-first'>
                B
            </div>
        </div>
    </div>
    <div class='col-12'>
        D
    </div>
</div>

Demo: https://codepen.io/anon/pen/wXLGKa


u
user2866893

Starting with the mobile version first, you can achieve what you want, most of the time.

Examples here:

http://jsbin.com/wulexiq/edit?html,css,output

<div class="container">
      <h1>PUSH - PULL Bootstrap demo</h1>
    <h2>Version 1:</h2>

    <div class="row">

      <div class="col-xs-12 col-sm-5 col-sm-push-3 green">
        IN MIDDLE ON SMALL/MEDIUM/LARGE SCREEN
        <hr> TOP ROW XS-SMALL SCREEN
      </div>

      <div class="col-xs-12 col-sm-4 col-sm-push-3 gold">
        TO THE RIGHT ON SMALL/MEDIUM/LARGE SCREEN
        <hr> MIDDLE ROW ON XS-SMALL
      </div>

      <div class="col-xs-12 col-sm-3 col-sm-pull-9 red">
        TO THE LEFT ON SMALL/MEDIUM/LARGE SCREEN
        <hr> BOTTOM ROW ON XS-SMALL
      </div>

    </div>

    <h2>Version 2:</h2>

    <div class="row">

      <div class="col-xs-12 col-sm-4 col-sm-push-8 yellow">
        TO THE RIGHT ON SMALL/MEDIUM/LARGE SCREEN
        <hr> TOP ROW ON XS-SMALL
      </div>

      <div class="col-xs-12 col-sm-4 col-sm-pull-4 blue">
        TO THE LEFT ON SMALL/MEDIUM/LARGE SCREEN
        <hr> MIDDLE ROW XS-SMALL SCREEN
      </div>

      <div class="col-xs-12 col-sm-4 col-sm-pull-4 pink">
        IN MIDDLE ON SMALL/MEDIUM/LARGE SCREEN
        <hr> BOTTOM ROW ON XS-SMALL
      </div>

    </div>

    <h2>Version 3:</h2>

    <div class="row">

      <div class="col-xs-12 col-sm-5 cyan">
        TO THE LEFT ON SMALL/MEDIUM/LARGE SCREEN TOP ROW ON XS-SMALL
      </div>

      <div class="col-xs-12 col-sm-3 col-sm-push-4 orange">
        TO THE RIGHT ON SMALL/MEDIUM/LARGE SCREEN
        <hr> MIDDLE ROW ON XS-SMALL
      </div>

      <div class="col-xs-12 col-sm-4 col-sm-pull-3 brown">
        IN THE MIDDLE ON SMALL/MEDIUM/LARGE SCREEN
        <hr> BOTTOM ROW XS-SMALL SCREEN
      </div>

    </div>

    <h2>Version 4:</h2>
    <div class="row">

      <div class="col-xs-12 col-sm-4 col-sm-push-8 darkblue">
        TO THE RIGHT ON SMALL/MEDIUM/LARGE SCREEN
        <hr> TOP ROW XS-SMALL SCREEN
      </div>

      <div class="col-xs-12 col-sm-4 beige">
        MIDDLE ON SMALL/MEDIUM/LARGE SCREEN
        <hr> MIDDLE ROW ON XS-SMALL
      </div>

      <div class="col-xs-12 col-sm-4 col-sm-pull-8 silver">
        TO THE LEFT ON SMALL/MEDIUM/LARGE SCREEN
        <hr> BOTTOM ROW ON XS-SMALL
      </div>

    </div>

  </div>

how to do the same for multiple columns? I have 7 columns and their order should change for tablet and phone. For mobile last column(7) should appear first.
L
Leandro Bardelli

This is quite easy with jQuery using insertAfter() or insertBefore():

<div class="left">content</div>
<div class="right">sidebar</div>

If you want to to set o condition for mobile devices you can make it like this:

example https://jsfiddle.net/w9n27k23/


It is really a bad feeling when you see someone using JS to correct the problem with HTML/CSS architecture. You are not correcting the problem, you are just hiding it.
@ZarkoJovic so what? Sometimes JS solutions might be much more viable. Bootstrap is not made of pure CSS, it also uses JS.
Z
Zayne komichi

Its very simple, write your html the way you would want it to be viewed in mobile. Then using the bootstrap order class you can arrange how you want it to viewed on desktop.

<html>
<head>
 <title>Order View</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
</head>
<body>
<div class="row">
  <div class="col order-md-2">
    <h1>IMAGE</h1>
  </div>
  <div class="col order-md-1">
    <h1>TEXT</h1>
  </div>
</body>
</html>