如何只使用CSS重新排列我的div?

336

如果由于其他要求而无法修改 HTML,如何在两个 div 在 HTML 中的顺序不同的情况下将一个 div 显示(重新排列)在另一个 div 上方?这两个 div 都包含高度和宽度不同的数据。

<div id="wrapper">
    <div id="firstDiv">
        Content to be below in this situation
    </div>
    <div id="secondDiv">
        Content to be above in this situation
    </div>
</div>
Other elements

希望显而易见的是,期望的结果是:
Content to be above in this situation
Content to be below in this situation
Other elements

当元素的尺寸固定时,很容易将它们放在需要的位置,但当内容是可变的时,我需要一些想法。为了这种情况,请仅考虑宽度在两个方向上均为100%。

我特别寻找只使用CSS的解决方案(如果找不到,可能还需要其他解决方案)。

此后还有其他元素。针对我展示的局限场景提出了一个好建议——假设它可能是最好的答案,但我也希望确保不会影响此后的元素。

27个回答

336

1
这里的排序是有效的。但子元素没有获得100%的宽度。相反,它们在同一行中共享空间。有什么办法可以利用这种方法为每个子元素提供100%的宽度? - aniskhan001
13
#flex { display: flex; flex-direction: column; } 将显示100%宽度的行。http://jsfiddle.net/2fcj8s9e/ - Justin
1
不支持 iPhone 6s 及以下设备。 - AntonAL
6
这个解决方案允许您为任意数量的div选择任何所需的顺序。在我看来,这应该是被接受的解决方案。 - mareoraft
这是一个干净的解决方案。 - Sleek Geek
显示剩余2条评论

302

这个解决方案仅使用CSS并适用于可变内容。

#wrapper   { display: table; }
#firstDiv  { display: table-footer-group; }
#secondDiv { display: table-header-group; }

3
好的!不过这种方法在IE8及以下版本无效,但你可以使用条件脚本来兼容这些浏览器…… - Stuart Wakefield
3
这对于移动内容重新排序非常有用,而且IE浏览器的问题已经不存在了!比如定义的菜单首先出现在正常布局的左侧,但你希望它们在窄小的移动设备上显示在底部。这个功能非常好用。 - morphles
13
需要注意的是,这并不适用于浮点数。如果您已经设置了浮点值,则必须将其设置为float:none;。 - Thomas
1
很棒的技巧。我发现一个不起作用的问题是圆角或指定宽度的能力。一旦我给第一个div设置"display: table-footer-group",我就失去了做这些事情的能力。 - Matt James
5
注意:img { max-width: 100% } 不会在重新排列的元素内生效。 - Jonas Äppelgran
显示剩余4条评论

87

正如其他人所说,这不是您希望在CSS中进行的操作。您可以通过绝对定位和奇怪的边距来模拟它,但这并不是一个健壮的解决方案。在您的情况下,最好的选择是转向JavaScript。在jQuery中,这是一项非常简单的任务:

$('#secondDiv').insertBefore('#firstDiv');

更加普遍地说:

$('.swapMe').each(function(i, el) {
    $(el).insertBefore($(el).prev());
});

2
有时候,让位于更强大的人可能是最好的选择。在这种情况下,这会感觉更加优雅,而且你真正拥有控制权。因此,我认为这更加整洁和优秀。 - landed
2
这可能在2008年左右是正确的,但不幸的是,现在这个答案已经非常过时了。 - Simon East

40

可以使用Flexbox完成此操作。

创建一个容器,应用display:flexflex-flow:column-reverse两个属性。

/* -- Where the Magic Happens -- */

.container {
  
  /* Setup Flexbox */
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;

  /* Reverse Column Order */
  -webkit-flex-flow: column-reverse;
  flex-flow: column-reverse;

}


/* -- Styling Only -- */

.container > div {
  background: red;
  color: white;
  padding: 10px;
}

.container > div:last-of-type {
  background: blue;
}
<div class="container">
  
  <div class="first">

     first

  </div>
  
  <div class="second">

    second

  </div>
  
</div>

Sources:


26

如果要支持旧版 IE(主要是旧版 IE),纯 CSS 无法实现你想要的效果,除非:

  1. 你知道每个元素的确切渲染高度(如果是这样,你可以绝对定位内容)。如果你处理的是动态生成的内容,那就没戏了。
  2. 你知道将会有多少这些元素。同样,如果你需要对生成动态的几个内容块进行此操作,那就没戏了,特别是如果超过三个左右。

如果上述条件成立,则可以通过绝对定位元素来实现你想要的效果--

#wrapper { position: relative; }
#firstDiv { position: absolute; height: 100px; top: 110px; }
#secondDiv { position: absolute; height: 100px; top: 0; }

再次强调,如果您不知道至少要为 #firstDiv 设置多高,则无法仅通过 CSS 实现您想要的效果。如果其中任何内容是动态的,您将需要使用 JavaScript。


好的,我也先点了踩,但又撤回了。但是条件还需要进一步的改进:您不需要知道要重新排序的元素的确切数量,除非该数量> 3(请参见奖励获奖答案)。这对于原始帖子中特别想交换两个项目的情况尤其相关。 - Sz.

16

这里是一个解决方案:

<style>
#firstDiv {
    position:absolute; top:100%;
}
#wrapper {
    position:relative; 
}

但我怀疑你有一些跟在包装 div 后面的内容...


是的... 尝试用情况不太详细的措辞,但后面还有其他要素。 这是一个好建议,考虑到提供的HTML受限--可能适用于其他人。 - devmode

15

您可以使用 Flex

#wrapper {
  display: flex;
  flex-direction: column;
}

#firstDiv {
  order: 1;
}

#secondDiv {
  order: 0;
}
<div id="wrapper">
    <div id="firstDiv">
        Content to be below in this situation
    </div>
    <div id="secondDiv">
        Content to be above in this situation
    </div>
</div>


11

使用CSS3的flexbox布局模块,您可以对div进行排序。

#wrapper {
  display: flex;
  flex-direction: column;
}
#firstDiv {
  order: 2;
}

<div id="wrapper">
  <div id="firstDiv">
    Content1
  </div>
  <div id="secondDiv">
    Content2
  </div>
</div>

1
如果您想让多个元素中的一个“粘性”置顶,我建议使用 order: -1 :) - jave.web

7

如果只使用CSS,可以使用flex。

.price {
    display: flex;
    align-items: center;
    justify-content: center;

    flex-direction: row-reverse; //revert horizontally
    //flex-direction: column-reverse; revert vertically
}
<div class="price">
      <div>first block</div>
      <div>second block</div>
</div>


5
如果您知道或者能够设定待转换元素的大小,您可以使用以下代码:
position : absolute;

在你的 CSS 中指定 div 的位置。否则,JavaScript 似乎是唯一的选择:
fd = document.getElementById( 'firstDiv' );
sd = document.getElementById( 'secondDiv' );
fd.parentNode.removeChild( fd );
sd.parentNode.insertAfter( fd, sd );

或类似的东西。 编辑:我刚刚发现这个可能有用:w3文档css3 move-to

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