Вопрос по html, css3, javascript, css – Как равномерно распределить плавающие элементы с помощью динамического числа столбцов и строк в CSS?

17

У меня есть несколько div с фиксированной шириной и высотой (подумайте о каком-то виде каталога с фотографиями статьи). Теперь я хочу показать им подобное поведение float: left. Это гарантирует, что чем больше окно вашего браузера, тем больше элементов div будет отображаться в одной строке.

Обратной стороной решения float: left является то, что с правой стороны есть большой белый зазор, пока не подойдет другой div. Теперь у меня есть задача распределять div равномерно на одной странице, и вместо большого белого пробела справа должны быть равномерно распределенные промежутки между отдельными div.

Решение в JavaScript легко:http://dl.dropbox.com/u/2719942/css/columns.html

Вы можете видеть, что при изменении размера окна браузера оно ведет себя подобно float: left, но пространство равномерно распределяется между полями. Количество столбцов и строк рассчитывается динамически с помощью JavaScript:

<code>  function updateLayout() {
    var boxes = document.getElementsByClassName('box');
    var boxWidth = boxes[0].clientWidth;
    var boxHeight = boxes[0].clientHeight;
    var parentWidth = boxes[0].parentElement.clientWidth;

    // Calculate how many boxes can fit into one row
    var columns = Math.floor(parentWidth / boxWidth);

    // Calculate the space to distribute the boxes evenly
    var space = (parentWidth - (boxWidth * columns)) / columns;

    // Now let's reorder the boxes to their new positions
    var col = 0;
    var row = 0;
    for (var i = 0; i < boxes.length; i++) {
      boxes[i].style.left = (col * (boxWidth + space)) + "px";
      boxes[i].style.top = (row * boxHeight) + "px";

      if (++col >= columns) {
        col = 0;
        row++;
      }
    }
  }
</code>

Теперь мне интересно, есть ли решение без JavaScript? Я бы предпочел решение только для CSS, потому что у меня может быть до сотен div на одной странице.

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

Итак, мой вопрос: могу ли я реализовать что-то подобное без JavaScript?

Ваш Ответ

4   ответа
13

closest чисто CSS решение основано наtext-align: justify.

Вот два из моих ответов, показывающих технику:

Вот демонстрация с использованием вашего HTML / CSS:http://jsfiddle.net/thirtydot/5CJ5e/ (или жеполноэкранный)

Существует различие в способе, которым ваш JavaScript и этот CSS обрабатывают последнюю строку, если количество блоков отличается от других строк.

Ваш JavaScript делает это:

Мой CSS делает это:

Если то, что CSS делает с другим количеством блоков в последнем ряду, неприемлемо, выcould добавьте несколько дополнительных невидимых полей для завершения строки:

http://jsfiddle.net/thirtydot/5CJ5e/1/ (или жеполноэкранный)

При этом возникает проблема, заключающаяся в том, что невидимые поля увеличивают высоту содержащего элемента. Если это проблема, я не могу придумать, как это исправить, не используя немного JavaScript:

http://jsfiddle.net/thirtydot/5CJ5e/2/ (или жеполноэкранный)

Конечно, поскольку сейчас используется JavaScript, вы также можете использовать его, чтобы добавить невидимые поля в первую очередь (вместо того, чтобы запутывать HTML):

http://jsfiddle.net/thirtydot/5CJ5e/5/ (или жеполноэкранный)

(Я также написал более сложное исправление JavaScript для этого в более раннем пересмотре, до того, как идея невидимых коробок была доведена до меня. Там не должно быть никаких причин, чтобы использовать мое старое исправление сейчас.)

Это немного странно, но вы могли бы добавить несколько дополнительных невидимых полей и вообще избегать JavaScript. Увидеть:jsfiddle.net/UxxJD/3 :)
Разве вы не можете просто добавить пару ящиков с нулевой (или 1 пиксельной) высотой, чтобы избежать дополнительной высоты, если хакерские ящики всплывают на следующую строку?
@trapper: Спасибо. Теперь, почему я не подумал об этом! Добавление невидимых ящиков является хакерским, но этоmuch лучше, чем мое старое исправление JavaScript. Я думаю, что некоторый JavaScript все еще необходим, чтобы препятствовать тому, чтобы невидимые коробки увеличили высоту контейнера. Я отредактировал свой ответ.
5

Вам нужно будет использовать Javascript для этого.

Но просто настройте класс ящика, чтобы настроить поля всех ящиков одновременно.

// Calculate how many boxes can fit into one row
var columns = Math.floor(parentWidth / boxWidth);

// Calculate the space to distribute the boxes evenly
var space = (parentWidth - (boxWidth * columns)) / columns;

$('.boxClass').css('margin', space / 2);

-

Пример:http://jsfiddle.net/VLr45/1/

2

возможноКИРПИЧНАЯ КЛАДКА может помочь с размещением?

1

So my question is: can I realize something like this without JavaScript?

Недавно я прошел через то же упражнение и, наконец, сдался и использовал JavaScript. Даже отказавшись от IE 7 и 8 (что не практично), я не смог найти чистого решения CSS. Я полагаю, вы могли бы составить длинный список медиа-запросов, чтобы выполнить это ограниченным образом.

Я закончил тем, что написал небольшую (около 1К) библиотеку, которая обрабатывает ширину, высоту, пропорциональное масштабирование, максимальную ширину, прокрутку, согласованные поля и отступы и т. Д.

Вот грубый пример, использующий мой собственный код:http://jsfiddle.net/CmZju/2/, Я поместил пару сотен элементов в этом примере.

I would prefer a CSS-only solution, because I will have possibly up to hundreds of divs on one page.

Механизм верстки браузера должен будет выполнить те же (или аналогичные) вычисления, что и вы. Конечно, он очень оптимизирован, но я бы протестировал ваше решение JS на нескольких старых ПК и нескольких мобильных устройствах, прежде чем сбрасывать его со счетов как слишком медленное.

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

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

Если вы в конечном итоге идете по маршруту сценария, вы можете взглянуть наJQuery Masonry для дополнительных идей. Я слышал хорошие вещи об этом, и это дало мне несколько хороших идей для моей собственной библиотеки.

Похожие вопросы