如何仅使用CSS重新排序div?


266

给定一个模板,其中HTML不能因为其他要求进行修改,怎么可能到显示器(重排)一个div在另一个上div时,他们没有在HTML的顺序?两者都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的解决方案(如果不成功,可能必须与其他解决方案配合使用)。

此后还有其他元素。考虑到我展示的场景有限,提到了一个很好的建议-考虑到这可能是最好的答案,但是我还希望确保遵循此条件的元素不会受到影响。

Answers:


279

此解决方案仅使用CSS并处理可变内容

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

3
真好!不适用于IE8或更低版本,但您可以为这些浏览器使用条件脚本...
Stuart Wakefield 2012年

1
这是真的,是不是IE7工作,但我有IE8没有问题
霍尔迪

3
是的,这对于移动内容重新排序非常好,并且IE的关注不在了!可以考虑首先定义的菜单,这些菜单显示在常规布局的左侧,但您希望它们显示在狭窄的移动显示器的底部。这很好地完成了窍门。
morphles 2014年

13
应该注意的是,这不适用于浮子。您必须设置float:none; 如果您已经有一个浮动集。
托马斯

5
注意:img { max-width: 100% }在重新排序的元素内将无法使用。
乔纳斯·阿佩格兰(JonasÄppelgran)'16

239

仅限CSS的解决方案(适用于IE10 +)–使用Flexbox的order属性:

演示:http//jsfiddle.net/hqya7q6o/596/

#flex { display: flex; flex-direction: column; }
#a { order: 2; }
#b { order: 1; }
#c { order: 3; }
<div id="flex">
   <div id="a">A</div>
   <div id="b">B</div>
   <div id="c">C</div>
</div>

更多信息:https : //developer.mozilla.org/en-US/docs/Web/CSS/order


1
订购在这里。但是孩子们没有得到100%的宽度。相反,他们在同一行中共享空间。知道使用这种方法如何将100%的宽度用于每个孩子吗?
aniskhan001

8
#flex { display: flex; flex-direction: column; }将显示宽度为100%的行。jsfiddle.net/2fcj8s9e
贾斯汀

可以使用transform更广泛的浏览器支持来完成它-Finesse
2016年

iPhone 6s及以下版本不支持
AntonAL

4
该解决方案允许您为任意数量的div选择任何所需的顺序。这应该是IMO公认的解决方案。
mareoraft

83

正如其他人所说,这不是您要在CSS中执行的操作。您可以用绝对的定位和奇怪的边距来捏造它,但这并不是一个可靠的解决方案。在您的情况下,最好的选择是转向javascript。在jQuery中,这是一个非常简单的任务:

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

或更一般地:

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

2
有时最好让那些更强大的人屈服。在这种情况下,这种感觉会更优雅,您可以真正掌控一切。因此,我觉得这更整洁和更好。
降落

35

这可以使用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>

资料来源:


25

在支持flexbox之前的用户代理(主要是旧版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(见赏金殊荣的答案)。这尤其与仅交换2个项目的OP有关。
Sz。

16

这是一个解决方案:

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

但是我怀疑您有一些内容紧随包装器部门...


是的...尽量不要对这种情况过于冗长,但是接下来还有其他要点。鉴于提供的HTML数量有限,因此建议还是不错的-可能对其他人也有用。
devmode

7

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

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


5

负的上边距可以实现此效果,但是需要为每页自定义它们。例如,此标记...

<div class="product">
<h2>Greatest Product Ever</h2>
<p class="desc">This paragraph appears in the source code directly after the heading and will appear in the search results.</p>
<p class="sidenote">Note: This information appears in HTML after the product description appearing below.</p>
</div>

...还有这个CSS ...

.product { width: 400px; }
.desc { margin-top: 5em; }
.sidenote { margin-top: -7em; }

...将使您可以将第二段拉到第一段之上。

当然,您必须手动调整CSS以适应不同的描述长度,以使介绍段跳到适当的数量,但是如果您对其他部分的控制有限,但对标记和CSS的控制完全有限,那么这可能是一个选择。


4

好吧,有了一些绝对的定位和一些模糊的边距设置,我可以接近,但这并不是完美的或漂亮的:

#wrapper { position: relative; margin-top: 4em; }
#firstDiv { position: absolute; top: 0; width: 100%; }
#secondDiv { position: absolute; bottom: 0; width: 100%; }

“ margin-top:4em”是一个特别讨厌的位:需要根据firstDiv中的内容量来调整此margin。根据您的确切要求,这可能是可行的,但无论如何,我希望有人能够以此为基础提供可靠的解决方案。

埃里克(Eric)关于JavaScript的评论应该被采纳。


3

这只能通过CSS来完成!

请检查我对类似问题的回答:

https://stackoverflow.com/a/25462829/1077230

我不想重复发布我的答案,但是它的不足之处是父级需要成为flexbox元素。例如:

(此处仅使用webkit供应商前缀。)

#main {
    display: -webkit-box;
    display: -webkit-flex;
    display: flex;
    -webkit-box-orient: vertical;
    -webkit-flex-direction: column;
    flex-direction: column;
    -webkit-box-align: start;
    -webkit-align-items: flex-start;
    align-items: flex-start;
}

然后,通过用以下命令指示其顺序来交换div:

#main > div#one{
    -webkit-box-ordinal-group: 2;
    -moz-box-ordinal-group: 2;
    -ms-flex-order: 2;
    -webkit-order: 2;
    order: 2;
    overflow:visible;
}

#main > div#two{
    -webkit-box-ordinal-group: 1;
    -moz-box-ordinal-group: 1;
    -ms-flex-order: 1;
    -webkit-order: 1;
    order: 1;
}

3

在CSS中,将第一个div左右浮动。与第一个div一样,向左或向右浮动第二个div。申请clear: leftright与上述两个div相同的第二个div。

例如:

#firstDiv {
    float: left;
}

#secondDiv {
    float: left;
    clear: left;
}

<div class =“ container”> <div id =“ secondDiv”> <p> ... </ p> </ div> <div id =“ firstDiv”> <p> ... </ p> </ div> </ div>
Vestel 2012年

就我的情况而言,浮动:对;清除:左;工作完美
user956584 2014年

使用clear是一种很好的方法,但是请注意,您应该以正确的方向浮动元素,并且还应该浮动所有其他元素才能正确执行。在Vestel,您应该使用以下样式:<style> #secondDiv,#firstDiv {float:left; } #firstDiv {clear:left; } </ style> <div class =“ container”>容器<div id =“ secondDiv”> <p> secondDiv </ p> </ div> <div id =“ firstDiv”> <p> firstDiv </ p> </ div> </ div>
Reza Amya 2014年

3

如果仅使用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>


2

我一直在寻找一种仅针对移动版本更改div顺序的方法,这样我就可以对其进行漂亮的样式设置。多亏了nickf的回复,我才能使这段代码对我想要的东西工作得很好,所以我还是与大家分享了一下:

//  changing the order of the sidebar so it goes after the content for mobile versions
jQuery(window).resize(function(){
    if ( jQuery(window).width() < 480 )
    {
        jQuery('#main-content').insertBefore('#sidebar');
    }
    if ( jQuery(window).width() > 480 )
    {
        jQuery('#sidebar').insertBefore('#main-content');
    }
    jQuery(window).height(); // New height
    jQuery(window).width(); // New width
});

1

一个具有比flexbox更大的浏览器支持的解决方案(在IE≥9中有效):

#wrapper {
  -webkit-transform: scaleY(-1);
  -ms-transform: scaleY(-1);
  transform: scaleY(-1);
}
#wrapper > * {
  -webkit-transform: scaleY(-1);
  -ms-transform: scaleY(-1);
  transform: scaleY(-1);
}
<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

display: table;解决方案相反,此解决方案在.wrapper有任意数量的子代时有效。


如果div包含图片>怎么办?
Ramji Seetharaman

0

只需通过指定display: flex和将flex用于父级div flex-direction : column。然后使用order确定哪个子div首先出现


2
为什么您认为这个7岁以上的问题的答案比已经发布的答案更好?如果您想参加SO,请查找没有(好的)答案的问题,并尝试以对所有访客都有用的方式来解答。
Marki555

-1

确实不应该使用CSS来重组HTML后端。但是,如果您知道所涉及的两个元素的高度并感到有些呆滞,则有可能。另外,在div之间切换时,文本选择会变得混乱,但这是因为HTML和CSS的顺序相反。

#firstDiv { position: relative; top: YYYpx; height: XXXpx; }
#secondDiv { position: relative; top: -XXXpx; height: YYYpx; }

其中XXX和YYY分别是firstDiv和secondDiv的高度。与顶部答案不同,这将适用于尾随元素。


那么,例如,在将内容放置在屏幕阅读器的导航之前,应该使用什么“重新构造HTML”呢?
Damian Yerrick '18

-1

我有一个更好的代码,由我自己编写,它是如此之大,只是为了展示这两件事...创建一个4x4的表,并且垂直对齐多个单元。

它不使用任何IE hack,不使用vertical-align:middle; 完全...

它不用于垂直居中显示表display:table-rom; 显示:表格单元格;

它使用了一个有两个div的容器,其中一个隐藏(位置不正确,但使父级具有正确的变量大小),一个隐藏之后可见,但顶部为-50%;因此它是可移动的正确位置。

请参阅可完成此操作的div类:BloqueTipoContenedor BloqueTipoContenedor_VerticalmenteCentrado BloqueTipoContenido_VerticalmenteCentrado_Oculto BloqueTipoContenido_VerticalmenteCentrado_Visible

请为在班级名称上使用西班牙语而感到抱歉(这是因为我会说西班牙语,这非常棘手,如果我使用英语,我会迷路)。

完整代码:

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Language" content="en" />
<meta name="language" content="en" />
<title>Vertical Centering in CSS2 - Example (IE, FF & Chrome tested) - This is so tricky!!!</title>
<style type="text/css">
 html,body{
  margin:0px;
  padding:0px;
  width:100%;
  height:100%;
 }
 div.BloqueTipoTabla{
  display:table;margin:0px;border:0px;padding:0px;width:100%;height:100%;
 }
 div.BloqueTipoFila_AltoAjustadoAlContenido{
  display:table-row;margin:0px;border:0px;padding:0px;width:100%;height:auto;
 }
 div.BloqueTipoFila_AltoRestante{
  display:table-row;margin:0px;border:0px;padding:0px;width:100%;height:100%;
 }
 div.BloqueTipoCelda_AjustadoAlContenido{
  display:table-cell;margin:0px;border:0px;padding:0px;width:auto;height:auto;
 }
 div.BloqueTipoCelda_RestanteAncho{
  display:table-cell;margin:0px;border:0px;padding:0px;width:100%;height:auto;
 }
 div.BloqueTipoCelda_RestanteAlto{
  display:table-cell;margin:0px;border:0px;padding:0px;width:auto;height:100%;
 }
 div.BloqueTipoCelda_RestanteAnchoAlto{
  display:table-cell;margin:0px;border:0px;padding:0px;width:100%;height:100%;
 }
 div.BloqueTipoContenedor{
  display:block;margin:0px;border:0px;padding:0px;width:100%;height:100%;position:relative;
 }
 div.BloqueTipoContenedor_VerticalmenteCentrado{
  display:block;margin:0px;border:0px;padding:0px;width:100%;height:auto;position:relative;top:50%;
 }
 div.BloqueTipoContenido_VerticalmenteCentrado_Oculto{
  display:block;margin:0px;border:0px;padding:0px;width:100%;height:auto;visibility:hidden;position:relative;top:50%;
 }
 div.BloqueTipoContenido_VerticalmenteCentrado_Visible{
  display:block;margin:0px;border:0px;padding:0px;width:100%;height:auto;visibility:visible;position:absolute;top:-50%;
 }
</style>
</head>
<body>
<h1>Vertical Centering in CSS2 - Example<br />(IE, FF & Chrome tested)<br />This is so tricky!!!</h1>
<div class="BloqueTipoTabla" style="margin:0px 0px 0px 25px;width:75%;height:66%;border:1px solid blue;">
 <div class="BloqueTipoFila_AltoAjustadoAlContenido">
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [1,1]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [1,2]
  </div>
  <div class="BloqueTipoCelda_RestanteAncho">
   [1,3]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [1,4]
  </div>
 </div>
 <div class="BloqueTipoFila_AltoAjustadoAlContenido">
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [2,1]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [2,2]
  </div>
  <div class="BloqueTipoCelda_RestanteAncho">
   [2,3]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [2,4]
  </div>
</div>
 <div class="BloqueTipoFila_AltoRestante">
  <div class="BloqueTipoCelda_RestanteAlto">
   <div class="BloqueTipoContenedor" style="border:1px solid lime;">
    <div class="BloqueTipoContenedor_VerticalmenteCentrado" style="border:1px dotted red;">
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Oculto">
     The cell [3,1]
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     Now&nbsp;is&nbsp;the&nbsp;highest&nbsp;one
     </div>
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Visible" style="border:1px dotted blue;">
     The cell [3,1]
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     *&nbsp;*&nbsp;*&nbsp;*
     <br />
     Now&nbsp;is&nbsp;the&nbsp;highest&nbsp;one
     </div>
    </div>
   </div>
  </div>
  <div class="BloqueTipoCelda_RestanteAlto">
   <div class="BloqueTipoContenedor" style="border:1px solid lime;">
    <div class="BloqueTipoContenedor_VerticalmenteCentrado" style="border:1px dotted red;">
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Oculto">
      This&nbsp;is<br />cell&nbsp;[3,2]
     </div>
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Visible" style="border:1px dotted blue;">
      This&nbsp;is<br />cell&nbsp;[3,2]
     </div>
    </div>
   </div>
  </div>
  <div class="BloqueTipoCelda_RestanteAnchoAlto">
   <div class="BloqueTipoContenedor" style="border:1px solid lime;">
    <div class="BloqueTipoContenedor_VerticalmenteCentrado" style="border:1px dotted red;">
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Oculto">
      This is cell [3,3]
      <br/>
      It is duplicated on source to make the trick to know its variable height
      <br />
      First copy is hidden and second copy is visible
      <br/>
      Other cells of this row are not correctly aligned only on IE!!!
     </div>
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Visible" style="border:1px dotted blue;">
      This is cell [3,3]
      <br/>
      It is duplicated on source to make the trick to know its variable height
      <br />
      First copy is hidden and second copy is visible
      <br/>
      Other cells of this row are not correctly aligned only on IE!!!
     </div>
    </div>
   </div>
  </div>
  <div class="BloqueTipoCelda_RestanteAlto">
   <div class="BloqueTipoContenedor" style="border:1px solid lime;">
    <div class="BloqueTipoContenedor_VerticalmenteCentrado" style="border:1px dotted red;">
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Oculto">
      This&nbsp;other is<br />the cell&nbsp;[3,4]
     </div>
     <div class="BloqueTipoContenido_VerticalmenteCentrado_Visible" style="border:1px dotted blue;">
      This&nbsp;other is<br />the cell&nbsp;[3,4]
     </div>
    </div>
   </div>
  </div>
 </div>
 <div class="BloqueTipoFila_AltoAjustadoAlContenido">
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [4,1]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [4,2]
  </div>
  <div class="BloqueTipoCelda_RestanteAncho">
   [4,3]
  </div>
  <div class="BloqueTipoCelda_AjustadoAlContenido">
   [4,4]
  </div>
 </div>
</div>
</body>
</html>

-1

聚会晚了一点,但是您也可以这样做:

<div style="height: 500px; width: 500px;">

<div class="bottom" style="height: 250px; width: 500px; background: red; margin-top: 250px;"></div>

<div class="top" style="height: 250px; width: 500px; background: blue; margin-top: -500px;"></div>


-2

或为元素设置绝对位置,并通过从页面边缘而非对象边缘声明边缘来消除边缘。使用%作为其更适合其他屏幕尺寸等。这就是我克服问题的方式...谢谢,希望它能为您提供帮助...


-3

对于仅CSS的解决方案1.应该固定包装纸的高度,或者2.应该固定第二个div的高度


这实际上无法回答所提出的问题。这无非是一条暗示可能解决方案的评论。
cimmanon

-3
.move-wrap {
    display: table;
    table-layout: fixed; // prevent some responsive bugs
    width: 100%; // set a width if u like
    /* TODO: js-fallback IE7 if u like ms */
}

.move-down {
    display: table-footer-group;
}

.move-up {
    display: table-header-group;
}

2
此解决方案早于您的发布时间发布了3年:stackoverflow.com/a/12069537/1652962
cimmanon

-4

使用CSS很容易,只需使用display:blockz-index属性

这是一个例子:

HTML:

<body>
    <div class="wrapper">

        <div class="header">
            header
        </div>

        <div class="content">
            content
        </div>
    </div>
</body>

CSS:

.wrapper
{
    [...]
}

.header
{
    [...]
    z-index:9001;
    display:block;
    [...]
}

.content
{
    [...]
    z-index:9000;
    [...]
}

编辑:最好将设置background-colordiv-s以便正确查看内容。


-4

我有一个简单的方法来做到这一点。

<!--  HTML  -->

<div class="wrapper">

    <div class="sm-hide">This content hides when at your layouts chosen breaking point.</div>

    <div>Content that stays in place</div>

    <div class="sm-show">This content is set to show at your layouts chosen breaking point.</div>

</div>

<!--  CSS  -->

    .sm-hide {display:block;}
    .sm-show {display:none;}

@media (max-width:598px) {
    .sm-hide {display:none;}
    .sm-show {display:block;}
}

您的解决方案可能很好地解决了问题-但能否请您解释为什么/如何解决。S / O上有很多品牌新手,他们可以从您的专业知识中学到东西。对您而言,显而易见的解决方案可能对他们而言并非如此。
Taryn East

单独的代码块通常不是有用的答案,并且更有可能吸引低票。请解释您所显示的解决方案的功能,以及该代码为何/如何回答问题。
j_s_stack
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.