Как установить поля автоматического поля в дизайне с гибкой шириной с помощью CSS?

У меня есть DIV с гибкой шириной, например. минимальная ширина: 800 пикселей и максимальная ширина: 1400 пикселей. В этом DIV есть много блоков с фиксированной шириной 200px и display:inline-block. Таким образом, в зависимости от ширины родительского DIV эти поля заполняют все пространство.

Моя проблема - это пустое пространство с правой стороны, вызванное переменной шириной родительского div. Иногда это пустое пространство маленькое и выглядит нормально, но с разной шириной родительского блока это пустое пространство составляет почти 200 пикселей.

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

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

И это то, что я хотел бы иметь:

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

Эта автоматическая маржа может быть легко достигнута с помощью TABLE. Однако я не знаю точного количества столбцов, так как оно зависит от разрешения экрана пользователя. Поэтому я не могу использовать таблицу и предпочитаю использовать CSS.

У кого-нибудь есть идея, как это решить? Заранее спасибо за ваши комментарии и ответы.

EDIT: мне не нужна поддержка IE6. Я хотел бы поддерживать IE7, но IE7 не является обязательным, поскольку я знаю, что существуют ограничения, поэтому я, вероятно, буду использовать фиксированную ширину «div.wrapper» в IE7.

EDIT2 Мне нужно обработать несколько строк этих блоков, чтобы они не превышали блок "div.wrapper" и правильно переносились в несколько строк блоков, а не только в одну длинную строку.

EDIT3 Я не знаю количество "столбцов", так как оно сильно зависит от разрешения экрана пользователя. Таким образом, на большом экране может быть 7 блоков в одном ряду, а на маленьких экранах может быть только 4 блока в одном ряду. Поэтому мне нужно решение, которое не устанавливает фиксированное количество ящиков в одной строке. Вместо этого, когда поля не помещаются в одну строку, их следует просто перенести на следующую строку.


person Frodik    schedule 12.08.2011    source источник
comment
Золотой вопрос: какие браузеры/версии вам нужно поддерживать?   -  person thirtydot    schedule 12.08.2011
comment
тридцатьдот: спасибо за вопрос, я обновил свой вопрос   -  person Frodik    schedule 12.08.2011
comment
Не уверен в простом решении CSS (без преобразования ширины поля в процент), вы можете просто использовать другую оболочку, чтобы поля всегда были по центру.   -  person joshnh    schedule 12.08.2011
comment
Боюсь, тег CSS3 не имеет отношения к этому вопросу.   -  person Spadar Shut    schedule 12.08.2011


Ответы (8)


Это максимально близко к CSS, совместимому с IE7: http://jsfiddle.net/thirtydot/79mFr/

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

HTML:

<div id="container">
    <div></div>
    <div></div>
    ..
    <span class="stretch"></span>
</div>

CSS:

#container {
    border: 2px dashed #444;

    text-align: justify;
    -ms-text-justify: distribute-all-lines;
    text-justify: distribute-all-lines;

    min-width: 800px;
    max-width: 1400px
}

#container > div {
    margin-top: 16px;
    border: 1px dashed #f0f;
    width: 200px;
    height: 200px;
    vertical-align: top;
    display: inline-block;
    *display: inline;
    zoom: 1
}
.stretch {
    width: 100%;
    display: inline-block;
    font-size: 0;
    line-height: 0
}

Лишние span (.stretch) можно заменить на :after.

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

См.: http://jsfiddle.net/thirtydot/79mFr/2/

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

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

<div id="container">
    <div></div>
    <div></div>
</div>

И это делает:

<div id="container">
    <div></div>
    <div></div></div>
person thirtydot    schedule 12.08.2011
comment
#container > div сломается. В устаревшем IE вам нужно использовать #container>div (без пробелов). - person AlienWebguy; 12.08.2011
comment
@AlienWebguy: Никому нет дела до IE 5. - person thirtydot; 12.08.2011
comment
+1 хорошее решение. Я попробовал решение CSS3 box-flex, но у меня были проблемы с полями :-/ - person andyb; 12.08.2011
comment
@andyb: Я думал попробовать это сам, когда впервые прочитал вопрос (особенно из-за тега css3). Но потом я спросил про поддержку браузера, и ответ был: I would like to support IE7, but IE7 is optional - значит нужна поддержка IE8. И на этом все закончилось :) - person thirtydot; 12.08.2011
comment
@thirtydot Я не говорю об IE5. IE6 и IE7 не всегда могут правильно интерпретировать пробел между parent > child, поэтому parent>child будет работать как альтернатива. Это известная ошибка. Видимо, не так широко известен, а? - person AlienWebguy; 12.08.2011
comment
@AlienWebguy: Можете ли вы процитировать то, что вы говорите? - person thirtydot; 12.08.2011
comment
Я смущен тем, почему 2-й ряд ящиков действует с задержкой. Если во 2-м ряду 2 ящика, а сверху 6, то первый ящик во 2-м ряду будет под ящиком 1, а 2-й ящик во 2-м ряду — под ящиком 6. - person Maverick; 12.08.2011
comment
@Matt Anderson: Именно так работает text-align: justify. Возможно, с текстом будет понятнее: jsfiddle.net/tXXsn. Нет ничего лучше, чем использование только CSS, который даже близко соответствует требованиям OP, который также работает в IE8. Так что я работаю с тем, что есть, а именно с text-align: justify. - person thirtydot; 12.08.2011

Вам нужно сделать .box встроенных блоков и выровнять текст в .wrapper. .wraper:after необходимо для выравнивания последней строки. Старые IE не понимают after, но в IE text-align-last:center позаботится о последней строке.

.wrapper{
    text-align:justify;
    max-width:1400px;
    min-width:800px;
    text-align-last:center;
}
.wrapper:after{
    content:'';
    display:inline-block;
    width:100%;
    height:0;
    font-size:0;
    line-height:0;
}
.box{
    display:inline-block;
    *display:inline;
    vertical-align:top;
    width:200px;
    height:50px;
    background:red;
}

Вот jsfiddle.

person Spadar Shut    schedule 12.08.2011
comment
+1. Кто бы дал исчерпывающий и обоснованный ответ без объяснений? Насколько я могу судить, это работает так, как задумано. - person ANeves thinks SE is evil; 12.08.2011
comment
-1 Вы двое хоть смотрели на скрипку? Он полностью сломан как в хроме, так и в firefox. - person Maverick; 12.08.2011
comment
+1. Я не заметил вашего ответа раньше, он похож на мой (более поздний) ответ, что с нашим взаимным использованием text-align:justify. Я собираюсь позаимствовать использование :after для своего собственного ответа. - person thirtydot; 12.08.2011
comment
@Matt Anderson Возможно, вам следует обновиться с FF2, он выглядит одинаково в Opera, Chrome и Firefox. - person Spadar Shut; 12.08.2011

Вы можете плавать и просто применять оболочку к .box, что позволит вам margin:auto; .box относительно плавающей оболочки.

CSS:

div.wrapper {
    width:100%;
    border:3px solid red;
}
div.clear {
    clear:both;
}
div.box-wrapper {
    float:left;
    margin:10px 0;
    height:100px;
    width:20%;
}
div.box {
    border:1px solid black;
    width:80px;
    height:100px;
    margin:auto;
}

HTML:

<div class="wrapper">
    <div class="box-wrapper"><div class="box"></div></div>
    <div class="box-wrapper"><div class="box"></div></div>
    <div class="box-wrapper"><div class="box"></div></div>
    <div class="box-wrapper"><div class="box"></div></div>
    <div class="box-wrapper"><div class="box"></div></div>
    <div class="box-wrapper"><div class="box"></div></div>
    <div class="box-wrapper"><div class="box"></div></div>
    <div class="box-wrapper"><div class="box"></div></div>
    <div class="box-wrapper"><div class="box"></div></div>
    <div class="box-wrapper"><div class="box"></div></div>
    <div class="clear"></div>
</div>

Демонстрация: http://jsfiddle.net/2avwf/

Я не делал их шириной 200 пикселей ради окна скрипки. Просто замените это width:80px на желаемую ширину.

Если вы хотите сделать это динамическим решением, в котором количество блоков в строке будет варьироваться от пользователя к пользователю в зависимости от размера их экрана и т. д., просто создайте 3 или 4 класса-обертки, определяющие ширину:

.box-wrapper-25 {
    width:25%;
}
.box-wrapper-33 {
    width:33%;
}

Затем с помощью JQuery вы можете легко определить ширину .wrapper и назначить класс переопределения оберткам блоков:

$('.box-wrapper').each(function(){
    $(this).removeClass().addClass('box-wrapper box-wrapper-25'); // only need 4 per row
});

Примерно так: http://jsfiddle.net/RcDky/

person AlienWebguy    schedule 12.08.2011
comment
Ваши решения выглядят хорошо, но у них есть недостаток, заключающийся в том, что они устанавливают фиксированное количество ящиков в строке. А когда у меня большой экран, поля коробок больше, чем сами коробки. Не могли бы вы обновить свой ответ, чтобы он не устанавливал фиксированное количество ящиков в одной строке? - person Frodik; 12.08.2011

Попробуйте этот jsFiddle: http://jsfiddle.net/MKuxm/

Просто увеличьте и уменьшите окно, чтобы изменить размер div, и вы увидите, что поля между красными прямоугольниками будут соответственно изменяться. Я знаю, что красные поля больше не имеют ширины 200 пикселей, но я боюсь, что это невозможно с чистым css, потому что вы не должны смешивать ширину в процентах и ​​фиксированную ширину в пикселях.

HTML

<div>
     <span>TEXT</span>
     <span>TEXT</span> 
     <span>TEXT</span> 
     <span>TEXT</span> 
</div>

CSS

div {
    width: 95%;
}

span {
    float: left;
    background: red;
    width: 20%;
    margin-left: 2.5%;
    margin-right: 2.5%;
}
person Bazzz    schedule 12.08.2011
comment
Спасибо за ответ, однако мне действительно нужно, чтобы эти поля имели фиксированную ширину 200 пикселей, а также мне нужно обрабатывать перенос в несколько строк, если все поля не помещаются в одну строку. - person Frodik; 12.08.2011

Я ответил на аналогичный вопрос здесь

Это возможно в чистом css3 с использованием media queries и процедуры css calc().

Конечно, это будет работать только в современных браузерах. IE9+, Chrome, Firefox,

См. этот РАБОЧИЙ ДЕМО

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

person Danield    schedule 30.04.2013

В моем проекте я столкнулся с той же проблемой и пришел к следующему решению - лучший способ для меня - использовать js, в моем случае вы можете иметь xxx количество блоков внутри контейнера, если в 1-й строке достаточно места блок из 2-й строки переходит в 1-ю строку и так далее. вот пример http://jsfiddle.net/gVAjN/11/

 $(function() {
  // Call function when DOM is ready
  settingsAlignment();

$(window).resize(function() {
      // Call function on window resize
        settingsAlignment();
    })

$('#new_div').click(function() {
    box_number = $('.element').size();
    box_add = box_number + 1;
    $('.container').append($('<div class="element">Box'+ box_add + '</div>'))
    settingsAlignment();
})

function settingsAlignment() {
// calculation of ul's padding-left and li's margin-right
var settingsUl = $('.container');
    settingsLi = $('.element');
    ul_width = settingsUl.outerWidth(true);
    item_width = settingsLi.width();
    min_gap = 7;
    effective_item_width = item_width + min_gap;
    items_in_row = Math.floor((ul_width - min_gap) / effective_item_width);
    gaps_sum = ul_width - items_in_row * item_width;
    new_gaps = gaps_sum / (items_in_row + 1);
    item_margin = Math.floor(new_gaps);
    row_width = (item_width + item_margin) * items_in_row - item_margin;
    console.log(row_width + '= row_width');
    console.log(ul_width + '= ul_width');
    ul_left_padding = Math.ceil((ul_width - row_width) / 2);
    console.log(ul_left_padding + '=ul_left_padding');
    settingsUl.css('padding-left', ul_left_padding + 'px');
    settingsLi.css('margin-right', item_margin + 'px');
  console.log(settingsLi);
 }
});
person John Connor    schedule 18.05.2013

довольно старый, но стоит попробовать, так как несколько строк и text-align: justify; в #container создает пробелы, когда в последней строке меньше элементов div. Я хотел, чтобы все плавало слева. Итак, моя идея состояла в том, чтобы использовать 2 обертки.

<div class="wrapper">
    <div class="wrapper2">    
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="clear"></div>
    </div>
</div>

а также переполнение: скрытое; в css

.wrapper {
    width:620px;
    border:3px solid red;
    margin:0 auto; overflow:hidden;
}
.wrapper2 {
    width:630px;
}
div.clear {
    clear:both;
}
.box {
    width:200px; background:#000; height:100px; margin-bottom:10px; float:left; overflow:hidden; margin-right:10px;
}

недостаток: поля не устанавливаются автоматически...

ДЕМО: http://jsfiddle.net/hexagon13/2avwf/52/

person Nick Zulu    schedule 09.12.2014

Попробуй это:

div.wrapper {
    display: flex;
    align-items: stretch;
    width: 100%;
    height: 100%;
    justify-content: space-between;
    /* justify-content will give the auto margin you looking for
       it will place the auto margin only between each div.box
       make sure the div.wrapper has "display: flex;"
     */
}

div.box {
    display: inline-flex; /* inline-flex will make the boxes all in the same line */
    width: 200px; /* notice you don't need width to be a % for this to work */
    height: 100%;
    margin: auto; /* gives you the auto margin for the first and last box from the border of your wrapper */
}
person Muhammad    schedule 02.03.2017
comment
извините, я впервые использую этот сайт, и мне было трудно публиковать сообщения, и я не понял, как отформатировать его, чтобы избежать ошибки, которую он выдал мне, когда я пытался опубликовать, поэтому здесь много кода ввода, он выглядит беспорядок, но если вы все еще ищете ответ, просто напишите мне или пришлите мне свой адрес электронной почты, я отправлю вам код. Я боролся с той же проблемой, и это сработало для меня. мой адрес электронной почты [email protected] - person Muhammad; 02.03.2017