如何在移动布局中更改Bootstrap 3列的顺序?

335

我正在制作一个响应式布局,其中包含一个顶部固定的导航栏。下面有两列,一列是边栏(3),另一列是内容(9)。在桌面上看起来像这样:

导航栏
[3][9]

当我将其 调整大小 到移动端时,导航栏 会被压缩隐藏,然后侧边栏叠放在内容上方,如下所示:

导航栏
[3]
[9]

我希望主要内容置于顶部,因此需要在移动设备上更改顺序,如下所示:

导航栏
[9]
[3]

我发现了这篇文章,涵盖了同样的问题,但已编辑的答案表明该解决方案不适用于当前版本的Bootstrap。

如何在移动设备上重新排列这些列?或者,如何将我的展开式导航栏中的侧边栏列表组件放入其中?

以下是我的代码:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

<div class="navbar navbar-inverse navbar-static-top">
  <div class="container">
    <a href="#" class="navbar-brand">Brand Title</a>
    <button class="navbar-toggle" data-toggle="collapse" data-target=".navHeaderCollapse">
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
    </button>
    <div class="collapse navbar-collapse navHeaderCollapse">

    <ul class="nav navbar-nav navbar-right"><!--original navbar-->
      <li class="active"><a href="#">Home</a></li>
      <li><a href="#">FAQ</a></li>
    </ul>

    </div>
  </div>
</div><!--End Navbar Div-->
    <div class="container">
  <div class="row">

    <div class="col-lg-3">
  <div class="list-group">
    <a href="#" class="list-group-item">
    <h4 class="list-group-item-heading">Lorem ipsum</h4>
    <p class="list-group-item-text">Lorem Ipsum is simply dummy text.</p></a>
  </div>
</div><!--end sidebar-->


<div class="col-lg-9">
  <div class="panel panel-default">
    <div class="panel-body">
      <div class="page-header">
     Main Content
    </div>
  </div>
</div><!--end main content area-->


1
现在使用Bootstrap 5非常容易 https://getbootstrap.com/docs/4.0/layout/grid/#order-classes - Alex Winkler
8个回答

521

在小屏幕下您不能更改列的顺序,但在大屏幕下可以。

因此,请更改您的列的顺序。

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

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

默认情况下,主要内容首先显示。

因此,在移动设备上,主要内容会首先显示。

通过使用col-lg-pushcol-lg-pull,我们可以在大屏幕上重新排序列,并将侧边栏显示在左侧,将主要内容显示在右侧。

这里有一个演示示例


8
非常感谢,你的回答正是我想要的,而且非常清晰易懂! - user3000310
2
@emre,为什么你只指定了大尺寸?在官方示例中,似乎也适用于中等尺寸。http://getbootstrap.com/css/#grid - Luchux
3
我一直在想推和拉类有什么用 - 现在我知道了。谢谢。 - cdonner
33
3.0正式发布后不久,推/拉功能可用于在任何屏幕尺寸(xs、sm、md、lg)上更改列的顺序。http://bootply.com/ft1tOI71cZ - Carol Skelly
谢谢您。这比“绝对定位列”之类的方法要好! - Radmation

150

2018年更新

对于基于Bootstrap 3的原始问题,解决方案是使用push-pull

Bootstrap 4中,即使列使用全宽度堆叠,也可以通过Bootstrap 4 flexbox来更改顺序。当然,push pull方法仍然有效,但现在还有其他方法可以在Bootstrap 4中更改列顺序,从而可以重新排列全宽度列。

方法1- 对于小屏幕(xs屏幕)使用 flex-column-reverse

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

方法二 - 在xs屏幕上使用order-first
<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


Bootstrap 3 原始问题的答案

对于基于 Bootstrap 3 原始 问题,解决方案是在较大的宽度上使用 push-pull ,然后在较小的(xs)宽度上,列将以其自然顺序显示。(A-B 反转为 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说过:“你不能更改小屏幕中列的顺序,但在大屏幕中可以做到。” 但是,这应该澄清为:“在Bootstrap 3中,您无法更改全宽 '堆叠' 列的顺序。


30

Bootstrap 3答案

这里的答案适用于只有2个单元格,但是一旦这些列中有更多内容,它可能会变得更加复杂。我认为我已经找到了一个通用的解决方案,适用于多列中任意数量的单元格。

目标

在移动设备上,使标签的垂直序列按照设计要求在平板电脑/桌面设备上以任何顺序排列。在这个具体的例子中,一个标签必须比通常情况下更早地进入流,另一个标签必须比通常情况下更晚地进入流。

移动设备

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

平板电脑+
[2 image  ][1 headline]
[         ][3 qty     ]
[         ][5 desc    ]
[4 caption][          ]
[         ][          ]

所以在平板电脑及以上设备上,标题需要向右移动,而技术上,描述也需要向右移动 - 它位于移动设备上先于它的字幕标签之上。你很快就会发现,第4个字幕也有问题。

假设每个单元格的高度都可能不同,并且需要与下一个单元格顶部对齐(排除类似表格的弱技巧)。

与所有Bootstrap Grid问题一样,第1步是意识到HTML必须按照移动顺序,在页面上是1 2 3 4 5。然后,确定如何使平板电脑/桌面电脑以这种方式重新排序 - 最好不使用Javascript。

1 headline3 qty设置为pull-right的解决方法是,它们都应用了CSS float: right,这意味着它们会找到第一个适合它们的空间并向右移动。您可以认为浏览器的CSS处理器按以下顺序工作:1适合右上角。接下来是2,它是常规的(float: left),因此它进入左上角。然后是3,它是float: right,因此它跳过1并到达下方。

但这个解决方案对于4 caption不够好,因为右侧的两个单元格太短了,使得左侧的2 image往往比它们两个加起来还长。Bootstrap Grid是一个被吹嘘的浮动hack,意味着4 captionfloat: left。由于2 image在左侧占用了很多空间,4 caption试图适应下一个可用的空间 - 通常是右列,而不是我们想要的左侧。
解决方法(以及更一般地说,针对任何类似问题的解决方法)是添加一个hack标签,在平板电脑及以上设备上存在,用于推动标题,然后通过负边距覆盖它 - 就像这样:
[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; }
}

因此,这里的通用解决方案是添加可以在移动设备上消失的hack标签。在平板电脑及以上设备上,hack标签允许显示标签早些或晚些出现在流中,然后被拉上或拉下来覆盖这些hack标签。
注意:我为了简化jsfiddle示例而使用了固定高度,但我实际工作的网站内容在所有5个标签的高度上都有所不同。它可以正确地呈现出相对较大的标签高度差异,特别是图像和描述。
注意2:根据您的布局,在平板电脑及以上分辨率上可能会有足够一致的列顺序,您可以避免使用hack标签,改用margin-bottom,如下所示:
注意3:这使用的是Bootstrap 3。Bootstrap 4使用不同的网格设置,不能与这些示例一起使用。

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


1
非常感谢您的精彩解释。我在工作中一直在做类似的事情,但已经放下了三天,不知道该怎么办。谢谢! - kdweber89
最好的...谢谢 ❤️ - Milad Ghiravani
也许我没有理解,但是如果答案中所描述的div“高度不同”,这个方法怎么能行呢?列出的代码和链接的fiddles都明确设置了hack的高度和相应的负底边距,以使它们与其他div的高度相等。如果那些div的高度比hack小,我们将在下一“行”中留下空白,如果它们更大,我们将有内容重叠。 - Paul L
@PaulL 请仔细查看代码,问题div的高度是随机的,所以每次查看页面时都会得到不同的高度,以更好地演示高度变化的情况。 - Chris Moschini
@ChrisMoschini,使用Bootstrap 3是否可以将“产品描述”作为移动设备中的第一个元素呈现?非常感谢您的帮助! - James_RajKumar

11

2017年10月

我想添加另一种Bootstrap 4的解决方案。这是对我有效的解决方案。

CSS的"Order"属性,结合媒体查询,可用于在较小屏幕上重新排列列当它们被堆叠起来。

类似于这样:

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

CodePen链接:https://codepen.io/preston206/pen/EwrXqm

调整屏幕大小,您会看到列以不同的顺序堆叠。

我将与原帖的问题联系起来。使用CSS,可以在媒体查询中针对导航栏、侧边栏和内容进行定位,然后应用排序属性。


1
这个解决方案非常优雅明了,可能是最佳答案。谢谢。 - Milo Persic

6
在Bootstrap 4中,如果您想要做类似于以下的事情:
    Mobile  |   Desktop
-----------------------------
    A       |       A
    C       |   B       C
    B       |       D
    D       |

您需要将BC的顺序颠倒,然后对B应用order-{breakpoint}-first。并且应用两个不同的设置,一个使它们共享相同的列,另一个使它们占据整个12列的宽度:
  • 较小屏幕:12列分配给B和12列分配给C

  • 较大屏幕:它们之和为12列(B + C = 12)

像这样:
<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


4

首先从移动版本开始,大多数情况下你可以实现你想要的效果。

这里有一些例子:

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>

如何对多列执行相同的操作?我有7列,它们的顺序应该根据平板电脑和手机进行更改。在移动设备上,最后一列(第7列)应该首先出现。 - James_RajKumar

0
使用jQuery的insertAfter()insertBefore()非常容易实现:
<div class="left">content</div>
<div class="right">sidebar</div>

<script>
$('.right').insertBefore('left');
</script>

如果你想为移动设备设置条件,可以这样做:

<script>
  var $iW = $(window).innerWidth();
  if ($iW < 992){
     $('.right').insertBefore('.left');
  }else{
     $('.right').insertAfter('.left');
  }
</script>

example https://jsfiddle.net/w9n27k23/


15
当你看到有人使用JS来修正HTML/CSS架构问题时,这实在是一种不好的感觉。你并没有真正修正问题,而只是掩盖了它。 - Zarko Jovic
@ZarkoJovic 那又怎样?有时候JS的解决方案可能更加可行。Bootstrap不仅由纯CSS构成,它还使用JS。 - Nanoturka

0

很简单,按照你想在移动设备上查看的方式编写HTML。然后使用Bootstrap的order类,您可以安排在桌面上的查看方式。

<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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接