Как обернуть div вертикально, а затем горизонтально

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

То, что мне нужно, показано на рисунке ниже:

Desired OutPut

Приведенные данные являются динамическими. Я хочу нарисовать divs по вертикали сначала на основе родительской высоты div, а затем горизонтально. Что-то похожее на панель WPF wrap, но я еще не смог ее достичь.

Это то, что я пробовал, рисуя горизонтально, а затем вертикально:

Fiddle: http://jsfiddle.net/4wuJz/2/

HTML:

<div id="wrap">
   <div id="wrap1">
       <div class="result">
           <div class="title">1</div>
           <div class="postcontent">  
              <p>Test</p>
           </div>
       </div>

       <div class="result">
           <div class="title">2</div>
           <div class="postcontent">
              <p>Test</p>
           </div>
       </div>
   </div>
</div>

CSS

#wrap {
   width:100%;
   height: 500px;
   background-color: rgba(0,0,0,0.5);
   overflow:scroll;
   overflow-y:hidden;
}

#wrap1 {
   width:2500px;
   height:500px;
   text-align: center;
}


.result {
   width: 300px;
   vertical-align: middle;
   float:left;
   background: rgba(120,30,20,0.5);
   padding: 10px;
   margin: 30px 0px 30px 30px; 
}

Как я могу изменить свой код, чтобы я соответствовал желаемому результату? Любые плагины jQuery доступны для этого?

Ответ 1

Добавьте clear: left в класс .result, чтобы ваши поля располагались вертикально.

Затем оберните результаты блоками по 3 и плавайте эти блоки по горизонтали. Вы можете сделать эту логику с помощью любого внешнего языка, который вы можете использовать для вывода разметки результатов или с помощью jQuery:

$('.result:nth-child(3n+1)').each(function() {
    $(this).add( $(this).next().next().addBack() ).wrapAll('<div style="float:left"></div>');
});

Fiddle


Здесь более отзывчивое решение, которое пересчитывает при изменении размера окна: Демо.

Примечание: предполагается, что все ящики имеют одинаковую высоту. Вы можете жестко закодировать a max-height в переменной resultHeight, если это не так.

$(window).resize(function() {
    var resultHeight = $('.result:first').outerHeight(true),
        nRows = Math.floor( $('#wrap1').height() / resultHeight );

    $('.results-column').contents().unwrap();
    $('.result:nth-child('+nRows+'n+1)').each(function() {
        $(this).nextAll().slice(0, nRows-1).add(this).wrapAll('<div class="results-column"></div>');
    });
}).resize();

Добавлен CSS:

#wrap1 {
    white-space: nowrap;
}
.results-column {
    display: inline-block;
    vertical-align: top;
}

Также проверьте Isotope с его макетами cellsByColumn/fitColumns.


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

  • Firefox <= 27, IE10 и Safari <= 6 поддерживают старую версию спецификации
  • Новые Chrome, Safari и IE11 поддерживают новый синтаксис
  • Невозможно забыть все префиксы браузера!

Ссылка: http://caniuse.com/flexbox

Хотя, все еще не потеряно. Если вы хотите использовать Flexbox сегодня, есть очень полезный Flexbox generator.

Решение только с CSS с помощью Flexbox: Демо

#wrap1 {
    display: -webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;
    -webkit-box-direction: normal;
    -moz-box-direction: normal;
    -webkit-box-orient: vertical;
    -moz-box-orient: vertical;
    -webkit-flex-direction: column;
    -ms-flex-direction: column;
    flex-direction: column;
    -webkit-flex-wrap: wrap;
    -ms-flex-wrap: wrap;
    flex-wrap: wrap;
    -webkit-box-pack: start;
    -moz-box-pack: start;
    -webkit-justify-content: flex-start;
    -ms-flex-pack: start;
    justify-content: flex-start;
    -webkit-align-content: flex-start;
    -ms-flex-line-pack: start;
    align-content: flex-start;
    -webkit-box-align: start;
    -moz-box-align: start;
    -webkit-align-items: flex-start;
    -ms-flex-align: start;
    align-items: flex-start;
}

Я тестировал это решение, и он корректно работает в IE10, IE11, Chrome 31, Opera 18 и Firefox 29 Nightly.

Примечание. Firefox <= 27 не поддерживает Flexbox более чем с одной строкой/столбцом (он не поддерживает flex-wrap: wrap). Я тестировал это на Firefox 29 (ночное время), и он работает правильно, поэтому я считаю, что он должен скоро приземлиться на стабильном уровне.

Ответ 2

Flexbox будет работать без JavaScript:

#wrap1 {
    display: flex;
    flex-wrap: wrap;
    flex-direction: column;
}

Демо: http://jsfiddle.net/4wuJz/5/

Ответ 3

Вы можете просто использовать столбцы CSS, не изменяя большую часть вашего кода:

div.wrap {
    width: 100%;
    height: 300px;    
    -webkit-column-width: 100px; 
       -moz-column-width: 100px; 
            column-width: 100px;
    -webkit-column-gap: 16px;
       -moz-column-gap: 16px;
            column-gap: 16px;
}

Проверьте эту скрипту: http://jsfiddle.net/Be9B3/

Ответ 4

Вы можете сделать это с помощью display:flex

Проверьте демонстрационную версию codepen: http://codepen.io/surjithctly/pen/zolcF

Подробнее здесь

HTML

<ul class="flex-container">
  <li class="flex-item">1</li>
  <li class="flex-item">2</li>
  <li class="flex-item">3</li>
  <li class="flex-item">4</li>
  <li class="flex-item">5</li>
  <li class="flex-item">6</li>
</ul>

CSS

.flex-container {
  padding: 0;
  margin: 0;
  list-style: none;
  max-height:600px;
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;

  -webkit-flex-flow: column wrap;
  justify-content: space-around;
}

.flex-item {
  background: tomato;
  padding: 5px;
  width: 200px;
  height: 150px;
  margin-top: 10px;

  line-height: 150px;
  color: white;
  font-weight: bold;
  font-size: 3em;
  text-align: center;
}