Как я могу изменить порядок моих div с CSS?

201

Учитывая шаблон, в котором HTML нельзя изменить из-за других требований, как можно отображать (переупорядочивать) a 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 (и, вероятно, его придется встретить с другими решениями, если это не закончится).

После этого есть другие элементы. Хорошее предложение было упомянуто, учитывая ограниченный сценарий, который я продемонстрировал - учитывая, что это может быть лучший ответ, но я также хочу убедиться, что элементы, следующие за этим, не пострадали.

Теги:

23 ответа

226

Это решение использует только CSS и работает с переменным содержимым

#wrapper   { display: table; }
#firstDiv  { display: table-footer-group; }
#secondDiv { display: table-header-group; }
  • 3
    Ницца! Не работает для IE8 или ниже, но вы можете использовать условный скрипт для этих браузеров ...
  • 1
    Это правда, что не работает для IE7, но у меня нет проблем с IE8
Показать ещё 6 комментариев
132

Решение только для 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% ширина может быть использована для каждого ребенка с этим методом?
  • 8
    #flex { display: flex; flex-direction: column; } отобразит строки шириной 100%. jsfiddle.net/2fcj8s9e
Показать ещё 3 комментария
69

Как говорили другие, это не то, что вы хотели бы делать в CSS. Вы можете выманить его с абсолютным позиционированием и странными полями, но это просто не надежное решение. Лучшим вариантом в вашем случае было бы обращение к javascript. В jQuery это очень простая задача:

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

или более общий:

$('.swapMe').each(function(i, el) {
    $(el).insertBefore($(el).prev());
});
  • 2
    Иногда лучше всего уступить более сильным. В этом случае это выглядит более элегантно, и вы находитесь в реальном контроле. По этой причине я чувствую, что это аккуратнее и лучше.
  • 0
    Спустя почти 10 лет, и это просто спасло меня еще один час от попыток «исправить ошибку». Спасибо!
27

Это можно сделать, используя Flexbox.

Создайте контейнер, который применяет как display: flex, так и flex-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>

Источники:

  • 1
    Должно работать во всех последних версиях браузера: caniuse.com/#feat=flexbox
  • 0
    Это прекрасно работает для меня, большое спасибо!
Показать ещё 1 комментарий
23

Нет абсолютно никакого способа добиться того, чего вы хотите, только с помощью CSS - , если:

  • Вы знаете точную визуализированную высоту каждого элемента (если это так, вы можете абсолютно разместить содержимое). Если вы имеете дело с динамически созданным контентом, вам не повезло.
  • Вы знаете точное количество этих элементов. Опять же, если вам нужно сделать это для нескольких кусков контента, которые генерируются динамически, вам не повезло.

Если приведенные выше значения верны, вы можете делать то, что хотите, абсолютно позиционируя элементы -

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

Опять же, если вы не знаете, какую высоту хотите, по крайней мере, для #firstDiv, вы не сможете делать то, что хотите, только с помощью CSS. Если какое-либо из этого содержимого является динамическим, вам придется использовать javascript.

  • 8
    Да, ты можешь. stackoverflow.com/a/28159766/922522
  • 6
    Вы знаете, что flex не существовало в начале 2009 года, верно? Круто, просто проверяю.
Показать ещё 4 комментария
16

Здесь решение:

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

Но я подозреваю, что у вас есть контент, следующий за оболочкой div...

  • 0
    Да ... стараюсь не быть слишком многословным с ситуацией, но есть и другие элементы. Хорошее предложение, хотя и с учетом предоставленного ограниченного HTML - может работать для кого-то еще.
5

С модулем макета CSS3 flexbox вы можете заказать divs.

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

<div id="wrapper">
  <div id="firstDiv">
    Content1
  </div>
  <div id="secondDiv">
    Content2
  </div>
</div>
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, это может быть вариантом.

5

Если вы знаете или можете применить размер для верхнего элемента, вы можете использовать

position : absolute;

В вашем css и дайте divs свою позицию.

иначе javascript кажется единственным способом:

fd = document.getElementById( 'firstDiv' );
sd = document.getElementById( 'secondDiv' );
fd.parentNode.removeChild( fd );
sd.parentNode.insertAfter( fd, sd );

или что-то подобное.

edit: Я просто нашел это, что может быть полезно: w3 document css3 move-to

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. В зависимости от ваших точных требований это может быть возможно, но я надеюсь, что кто-то сможет построить это для твердого решения.

Комментарий Eric о javascript, вероятно, следует преследовать.

3

тебе просто нужно это! в css float сначала div слева или справа. float второй div слева или справа, как и первый. ясно левый или правый, как указано выше, два div для второго div. например:

#firstDiv {
    float: left;
}

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

Удачи моему другу.

  • 0
    Это решение не работает в моем случае.
  • 0
    пожалуйста, опишите ваш случай
Показать ещё 3 комментария
2

Решение с более крупной поддержкой браузера, затем 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 имеет любое количество детей.

  • 0
    Что если div содержит изображение>?
  • 0
    @RamjiSeetharaman Это тоже должно хорошо работать
2

Это можно сделать только с помощью CSS!

Пожалуйста, проверьте мой ответ на этот похожий вопрос:

https://stackoverflow.com/questions/14011125/changing-dom-element-order-with-css-crocodoc

Я не хочу дважды публиковать свой ответ, но, скорее всего, родительский элемент должен стать 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;
}
2

Я искал способ изменить порядок divs только для мобильной версии, чтобы потом я мог хорошо стилизовать его. Благодаря ответу на 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
});
0

Просто используйте flex для родительского div, указав display: flex и flex-direction : column. Затем используйте порядок, чтобы определить, какой из дочерних div приходит первым

  • 2
    Почему вы думаете, что этот ответ на 7-летний вопрос лучше, чем те, которые уже размещены? Если вы хотите принять участие в SO, пожалуйста, найдите вопросы без (хороших) ответов и постарайтесь ответить на них так, чтобы это помогло всем посетителям.
0

CSS действительно не следует использовать для реструктурирования HTML-сервера. Однако это возможно, если вы знаете высоту обоих элементов и чувствуете себя хаки. Кроме того, выбор текста будет перепутан при переходе между div, но это потому, что порядок HTML и CSS противоположный.

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

Где XXX и YYY - высоты первогоDiv и secondDiv соответственно. Это будет работать с конечными элементами, в отличие от верхнего ответа.

  • 0
    Тогда что следует «использовать для реструктуризации HTML», когда, скажем, содержимое перед навигацией для программы чтения с экрана?
-1

Или установите абсолютную позицию для элемента и отработайте поля, объявив их с края страницы, а не по краю объекта. Используйте%, поскольку он более подходит для других размеров экрана и т.д. Вот как я преодолел проблему... Спасибо, надеюсь, что ее ищут...

-2

Немного поздно вечеринке, но вы также можете это сделать:

<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

У меня есть намного лучший код, сделанный мной, он настолько большой, просто для того, чтобы показать обе вещи... создать таблицу 4x4 и вертикальное выравнивание больше, чем только одну ячейку.

В нем не используется IE-хак, нет вертикального выравнивания: средний; на всех...

Он не используется для вертикального центрирования таблицы отображения, отображения: 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>
-3

У меня есть простой способ сделать это.

<!--  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;}
}
  • 0
    Ваше решение вполне может решить проблему, но не могли бы вы объяснить, почему и как это происходит. На S / O есть куча новичков, и они могут узнать что-то из вашего опыта. То, что может быть очевидным решением для вас, может быть не так для них.
  • 0
    Сами по себе блоки кода, как правило, не являются полезными ответами и, скорее всего, привлекают отрицательные отзывы. Пожалуйста, объясните, что делает решение, которое вы показываете, и почему / как этот код отвечает на вопрос.
-4
.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;
}
-4

Только для решения CSS 1. Любая высота обертки должна быть фиксированной или 2. высота второго div должна быть исправлена.

  • 0
    Это не делает ничего, чтобы фактически ответить на задаваемый вопрос. Это всего лишь комментарий, намекающий на возможное решение.
-5

Легко с css, просто используйте display:block и z-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-color для div-s, чтобы правильно видеть вещи.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню