Ширина жидкости с одинаково расположенными DIV

329

У меня есть контейнер с жидкостью шириной DIV.

В рамках этого у меня есть 4 DIVs все 300px x 250px ...

<div id="container">
   <div class="box1"> </div>
   <div class="box2"> </div>
   <div class="box3"> </div>
   <div class="box4"> </div>
</div>

Я хочу, чтобы поле 1 было смещено влево, поле 4 смещено вправо, а поля 2 и 3 - между ними равномерно. Я хочу, чтобы интервал также был плавным, так как браузер становится меньше, пространство также становится меньше.

введите описание изображения здесь

Ли Прайс
источник
2
Почему бы не сделать display:inline-block;вместо плавания?
айып
1
потому что IE6 / IE7 поддерживает только inline-blockна inlineэлементы
Ли Цена
Хорошо, я не был уверен, для каких браузеров вы собираетесь.
айып
1
Самое близкое решение, которое я мог придумать, - это обернуть каждый дочерний элемент .box в другой div с шириной 25%. Затем отцентрируйте дочерний .box div к оболочке. .Box div будут равномерно распределены, но левый и правый div не будут располагаться справа от края.
Пол Шам
5
Я превратил идею @Paul Sham в JSFiddle .
Sparky

Ответы:

440

Смотрите: http://jsfiddle.net/thirtydot/EDp8R/

  • Это работает в IE6 + и во всех современных браузерах!
  • Я сократил ваши размеры вдвое, чтобы вам было проще работать.
  • text-align: justifyв сочетании с .stretchтем, что обрабатывает позиционирование.
  • display:inline-block; *display:inline; zoom:1исправления inline-blockдля IE6 / 7, смотрите здесь .
  • font-size: 0; line-height: 0 исправляет небольшую проблему в IE6.

#container {
  border: 2px dashed #444;
  height: 125px;
  text-align: justify;
  -ms-text-justify: distribute-all-lines;
  text-justify: distribute-all-lines;
  /* just for demo */
  min-width: 612px;
}

.box1,
.box2,
.box3,
.box4 {
  width: 150px;
  height: 125px;
  vertical-align: top;
  display: inline-block;
  *display: inline;
  zoom: 1
}

.stretch {
  width: 100%;
  display: inline-block;
  font-size: 0;
  line-height: 0
}

.box1,
.box3 {
  background: #ccc
}

.box2,
.box4 {
  background: #0ff
}
<div id="container">
  <div class="box1"></div>
  <div class="box2"></div>
  <div class="box3"></div>
  <div class="box4"></div>
  <span class="stretch"></span>
</div>

Экстра span( .stretch) можно заменить на :after.

Это все еще работает во всех тех же браузерах, что и вышеуказанное решение. :afterне работает в IE6 / 7, но они все distribute-all-linesравно используют , так что это не имеет значения.

Смотрите: http://jsfiddle.net/thirtydot/EDp8R/3/

Есть небольшой недостаток :after: чтобы последняя строка отлично работала в Safari, вы должны быть осторожны с пробелами в HTML.

В частности, это не работает:

<div id="container">
    ..
    <div class="box3"></div>
    <div class="box4"></div>
</div>

И это делает:

<div id="container">
    ..
    <div class="box3"></div>
    <div class="box4"></div></div>

Вы можете использовать это для любого произвольного числа дочерних элементов, divне добавляя boxNкласс к каждому, изменяя

.box1, .box2, .box3, .box4 { ...

в

#container > div { ...

Это выбирает любой div, который является первым дочерним элементом #containerdiv, и никаких других ниже него. Чтобы обобщить цвета фона, вы можете использовать CSS3-селектор n-го порядка , хотя он поддерживается только в IE9 + и других современных браузерах:

.box1, .box3 { ...

будет выглядеть так:

#container > div:nth-child(odd) { ...

Смотрите здесь для примера jsfiddle.

thirtydot
источник
123
Я взял 3 часа, чтобы найти, что вы должны иметь пробелы между каждым полями в HTML. «Justify» расширяет пробелы между элементами, и если ваш контент <div/><div/><div/>это не работает. Вы должны иметь <div/> <div/> <div/>.
Venimus
5
просто хотел это заметить :) потому что трудно заметить, если вы работаете с сгенерированным контентом (что является распространенным случаем). Я думал использовать justifyдля такого случая, но спасибо, чтобы предоставить рабочее решение. спасло меня много экспериментов (несмотря на 3-часовую отладку: D). Кроме того, я мог бы добавить примечание, что если вы хотите, чтобы ваш последний ряд был выровнен по левому краю, вы должны добавить несколько дополнительных невидимых полей (чтобы завершить ряд)
venimus
4
@venimus: я написал другой ответ, используя эту технику: stackoverflow.com/questions/10548417/… . Что вы сделали, чтобы избавиться от лишней высоты, вызванной добавлением невидимых ящиков?
Тридцатое
11
Может кто-нибудь объяснить, зачем нужен .stretch?
АТП
6
@HartleySan: .stretch/ :afterнеобходим, потому что (обычно) с выровненным текстом последняя строка не выровнена . Здесь мы хотим, чтобы последняя строка была обоснована, отсюда и необходимость :after. Что касается вашего второго вопроса, я изучил это некоторое время назад в предыдущем ответе . В этом ответе был необходим JavaScript. Если вам нужна поддержка старых браузеров (IE8), то, я думаю, вам нужен JavaScript.
Тридцатое
140

Самый простой способ сделать это сейчас - использовать flexbox:

http://css-tricks.com/snippets/css/a-guide-to-flexbox/

CSS это просто:

#container {
    display: flex;
    justify-content: space-between;
}

демо: http://jsfiddle.net/QPrk3/

Однако в настоящее время это поддерживается только относительно недавними браузерами ( http://caniuse.com/flexbox ). Кроме того, спецификация макета flexbox несколько раз менялась, поэтому можно охватить больше браузеров, дополнительно включив старый синтаксис:

http://css-tricks.com/old-flexbox-and-new-flexbox/

http://css-tricks.com/using-flexbox/

Бен Джексон
источник
1
Спасибо за это, так просто, я применил его к четырем равномерно расположенным спискам в нижнем колонтитуле, закрепленном внизу страницы. Работал лакомством в FF28.0, Chrome 34.0.1847.116 м и IE11.
user1063287
1
Flexbox - не самый поддерживаемый инструмент в Интернете, и он не превосходит классический подход к марже и отступам.
TheBlackBenzKid
Для всех, кто ищет обоснование нескольких элементов div с неопределенным значением: используйте flex-wrap с параметром display: flex. Это обернет div с динамической шириной.
Камил Будзевски
20

Если опция css3 является опцией, это можно сделать с помощью calc()функции css .

Случай 1: Оправдывающие блоки на одной строке ( FIDDLE )

Разметка проста - куча элементов с некоторым элементом контейнера.

CSS выглядит так:

div
{
    height: 100px;
    float: left;
    background:pink;
    width: 50px;
    margin-right: calc((100% - 300px) / 5 - 1px); 
}
div:last-child
{
    margin-right:0;
}

где -1px для исправления ошибки IE9 + calc / округления - смотрите здесь

Случай 2: Оправдывающие блоки на нескольких строках ( FIDDLE )

Здесь, помимо calc()функции, media queriesнеобходимы.

Основная идея состоит в том, чтобы настроить медиазапрос для каждого состояния #columns, где я затем использую calc () для определения поля справа для каждого из элементов (кроме элементов в последнем столбце).

Это звучит как большая работа, но если вы используете LESS или SASS, это можно сделать довольно легко

(Это все еще можно сделать с помощью обычного CSS, но тогда вам придется делать все расчеты вручную, а затем, если вы измените ширину вашего бокса - вам придется все заново обрабатывать)

Ниже приведен пример использования LESS: (Вы можете скопировать / вставить этот код здесь, чтобы поиграть с ним, [это также код, который я использовал для генерации вышеупомянутой скрипки])

@min-margin: 15px;
@div-width: 150px;

@3divs: (@div-width * 3);
@4divs: (@div-width * 4);
@5divs: (@div-width * 5);
@6divs: (@div-width * 6);
@7divs: (@div-width * 7);

@3divs-width: (@3divs + @min-margin * 2);
@4divs-width: (@4divs + @min-margin * 3);
@5divs-width: (@5divs + @min-margin * 4);
@6divs-width: (@6divs + @min-margin * 5);
@7divs-width: (@7divs + @min-margin * 6);


*{margin:0;padding:0;}

.container
{
    overflow: auto;
    display: block;
    min-width: @3divs-width;
}
.container > div
{
    margin-bottom: 20px;
    width: @div-width;
    height: 100px;
    background: blue;
    float:left;
    color: #fff;
    text-align: center;
}

@media (max-width: @3divs-width) {
    .container > div {  
        margin-right: @min-margin;
    }
    .container > div:nth-child(3n) {  
        margin-right: 0;
    }
}

@media (min-width: @3divs-width) and (max-width: @4divs-width) {
    .container > div {  
        margin-right: ~"calc((100% - @{3divs})/2 - 1px)";
    }
    .container > div:nth-child(3n) {  
        margin-right: 0;
    }
}

@media (min-width: @4divs-width) and (max-width: @5divs-width) {
    .container > div {  
        margin-right: ~"calc((100% - @{4divs})/3 - 1px)";
    }
    .container > div:nth-child(4n) {  
        margin-right: 0;
    }
}

@media (min-width: @5divs-width) and (max-width: @6divs-width) {
    .container > div {  
        margin-right: ~"calc((100% - @{5divs})/4 - 1px)";
    }
    .container > div:nth-child(5n) {  
        margin-right: 0;
    }
}

@media (min-width: @6divs-width){
    .container > div {  
        margin-right: ~"calc((100% - @{6divs})/5 - 1px)";
    }
    .container > div:nth-child(6n) {  
        margin-right: 0;
    }
}

Таким образом, вначале вам нужно определить ширину блока и минимальный размер поля между блоками.

С этим вы можете определить, сколько места вам нужно для каждого штата.

Затем используйте calc () для вычисления правого поля и nth-child, чтобы удалить правое поле из полей в последнем столбце.

Преимущество этого ответа над общепринятом ответ , который использует в text-align:justifyтом , что когда у вас есть более чем один ряд коробки - ящики на заключительном подряд не получают «оправданным» , например: если есть 2 коробки , оставшиеся на заключительном ряду - я не нужно, чтобы первый прямоугольник находился слева, а следующий - справа, - скорее, чтобы прямоугольники следовали друг за другом по порядку.

Что касается поддержки браузера : это будет работать в IE9 +, Firefox, Chrome, Safari6.0 + - (см. Здесь для получения более подробной информации). Однако я заметил, что в IE9 + есть некоторая ошибка между состояниями медиа-запросов. [если кто-то знает, как это исправить, мне бы очень хотелось знать :)] <- ИСПРАВЛЕНО ЗДЕСЬ

Danield
источник
13

В других публикациях упоминается flexbox , но если необходимо более одной строки элементов , space-betweenсвойство flexbox не выполняется (см. Конец публикации).

На сегодняшний день единственное чистое решение для этого с

Модуль CSS Grid Layout ( Codepen demo )

В основном соответствующий код сводится к следующему:

ul {
  display: grid; /* (1) */
  grid-template-columns: repeat(auto-fit, 120px); /* (2) */
  grid-gap: 1rem; /* (3) */
  justify-content: space-between; /* (4) */
  align-content: flex-start; /* (5) */
}

1) Сделать элемент контейнера контейнером сетки

2) Установите сетку с «автоматическим» количеством столбцов - при необходимости. Это сделано для адаптивных макетов. Ширина каждого столбца будет 120px. (Обратите внимание на использование auto-fit( применительно к auto-fill), которое (для однострочного макета) сворачивает пустые дорожки в 0 - позволяя элементам расширяться, чтобы занять оставшееся пространство. ( Посмотрите эту демонстрацию, чтобы увидеть, о чем я говорю )).

3) Установите промежутки / желоба для строк и столбцов сетки - здесь, так как нужно расположение «промежуток» - разрыв будет фактически минимальным, потому что он будет расти по мере необходимости.

4) и 5) - похоже на flexbox.

body {
  margin: 0;
}
ul {
  display: grid;
  grid-template-columns: repeat(auto-fit, 120px);
  grid-gap: 1rem;
  justify-content: space-between;
  align-content: flex-start;
  
  /* boring properties: */
  list-style: none;
  width: 90vw;
  height: 90vh;
  margin: 2vh auto;
  border: 5px solid green;
  padding: 0;
  overflow: auto;
}
li {
  background: tomato;
  height: 120px;
}
<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

Codepen demo ( измените размер, чтобы увидеть эффект)


Поддержка браузера - Caniuse

В настоящее время поддерживается Chrome (Blink), Firefox, Safari и Edge! ... с частичной поддержкой от IE (см. это сообщение Рэйчел Эндрю)


NB:

space-betweenСвойство Flexbox прекрасно работает для одного ряда элементов, но при применении к флекс-контейнеру, который упаковывает его элементы - (с flex-wrap: wrap) - не выполняется, поскольку вы не можете контролировать выравнивание последнего ряда элементов; последний ряд всегда будет оправдан (обычно не то, что вы хотите)

Демонстрировать:

Codepen ( измените размер, чтобы увидеть, о чем я говорю)


Дальнейшее чтение по сеткам CSS:

Danield
источник
1
Очень недооцененный ответ. Это был самый простой и эффективный способ достичь того, что я хотел сделать. Спасибо.
Барнаби Мерсер
1
Это было наименьшее количество CSS (и не JS!), Которое произвело именно то поведение, которое я искал, с некоторыми настройками размера и пространства.
EKW
1
Я искал это некоторое время и наконец нашел это! Спасибо @Danield
nareeboy
2

Это сработало для меня с 5 изображениями разных размеров.

  1. Создать контейнерный div
  2. Ненумерованный список изображений
  3. На css неупорядоченный должен отображаться вертикально и без маркеров
  4. Обоснуйте содержимое контейнера div

Это работает из-за justify-content: space -ween, и он находится в списке, отображаемом горизонтально.

По CSS

 #container {
            display: flex;
            justify-content: space-between;
 }
    #container ul li{ display:inline; list-style-type:none;
}

На HTML

<div id="container"> 
  <ul>  
        <li><img src="box1.png"><li>
        <li><img src="box2.png"><li>
        <li><img src="box3.png"><li>
        <li><img src="box4.png"><li>
        <li><img src="box5.png"><li>
    </ul>
</div>
Себастьян Брун Вальенте
источник
Хотя этот код может хорошо работать, хороший ответ будет включать в себя объяснение того, как он работает и почему это хорошее решение.
Блэквуд
Стоит отметить, что flexbox не поддерживается (или только частично) IE caniuse.com/#feat=flexbox
Дэвид Саламон
это отзывчиво?
стек
1

в jQueryвас может быть нацелен на Родителя напрямую.

ЭТО ПОЛЕЗНО, ЕСЛИ ВЫ НЕ ЗНАЕТЕ ТОЧНО, КАК МНОГИЕ ДЕТИ БУДУТ ДОБАВЛЕНЫ ДИНАМИЧЕСКИ, ИЛИ ЕСЛИ ВЫ НЕ МОЖЕТЕ УВИДЕТЬ ИХ НОМЕР.

var tWidth=0;

$('.children').each(function(i,e){
tWidth += $(e).width();

///Example: If the Children have a padding-left of 10px;..
//You could do instead:
tWidth += ($(e).width()+10);

})
$('#parent').css('width',tWidth);

Это позволит parentрасти горизонтально при childrenдобавлении бенга.

ПРИМЕЧАНИЕ: это предполагает, что '.children'есть widthи HeightSet

Надеюсь, это поможет.

ErickBest
источник
1

Если вы знаете количество элементов на «строку» и ширину контейнера, вы можете использовать селектор, чтобы добавить поле к элементам, которое вам нужно, чтобы получить оправданный вид.

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

.tile:nth-child(3n+2) { margin: 0 10px }

это позволяет центру div в каждом ряду иметь поле, которое вынуждает 1-й и 3-й div к внешним краям контейнера

Также отлично подходит для других вещей, таких как границы фона и т. Д.

Дейв Робертсон
источник