Как я могу изменить порядок моих div с CSS? - PullRequest
238 голосов
/ 21 октября 2008

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

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

Ответы [ 23 ]

263 голосов
/ 22 августа 2012

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

#wrapper   { display: table; }
#firstDiv  { display: table-footer-group; }
#secondDiv { display: table-header-group; }
178 голосов
/ 27 января 2015

Решение только для 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

77 голосов
/ 21 октября 2008

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

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

или более обобщенно:

$('.swapMe').each(function(i, el) {
    $(el).insertBefore($(el).prev());
});
33 голосов
/ 14 июня 2014

Это можно сделать с помощью Flexbox.

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

Источники:

26 голосов
/ 15 февраля 2009

Абсолютно невозможно достичь того, чего вы хотите, только с помощью CSS при поддержке пользовательских агентов pre-flexbox ( в основном старый IE ) - , если :

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

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

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

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

16 голосов
/ 21 октября 2008

Вот решение:

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

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

7 голосов
/ 21 октября 2015

С модулем макета 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 голосов
/ 22 октября 2008

Отрицательные верхние поля могут достичь этого эффекта, но их нужно будет настраивать для каждой страницы. Например, эта разметка ...

<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 голосов
/ 21 октября 2008

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

position : absolute;

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

В противном случае 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 голосов
/ 21 октября 2008

Ну, с немного абсолютного позиционирования и некоторой хитрой настройкой поля, я могу приблизиться, но это не идеально или красиво:

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

"margin-top: 4em" - это особенно неприятный бит: это поле необходимо корректировать в соответствии с количеством контента в firstDiv. В зависимости от ваших точных требований это может быть возможным, но я все равно надеюсь, что кто-то сможет использовать это для твердого решения.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...