Подтвердить что ты не робот

CSS-флюидные столбцы, фиксированные поля; святой Грааль святых граалей

Обновление и сводка

Я чувствую себя обязанным сделать этот вопрос более ясным, теперь, когда есть щедрость.

(Кроме того, я уверен, что это будет детская игра, когда поддерживается значение единицы calc() CSS3, что-то вроде width: calc(25% - 5px), хотя мы, вероятно, будем смотреть в Интернете в наши умы к этому моменту)

Я работаю над структурой CSS для нескольких проектов, которые разделяют требования к дизайну; а именно жидкую раскладку 12 колонн. Используя плавающие элементы .column с процентной шириной (100% / 12) x col_size, это достаточно просто. Однако проблема связана с добавлением фиксированных полей (или любой формы интервала) между столбцами.

Моя первоначальная попытка использовала текущие столбцы, как описано, с ребенком .panel, вложенным в каждый. Ниже приведен фрагмент HTML/CSS (сокращенный для краткости):

.column{
    float: left;
    display: inline-block;
}

.width-01{ width:  8.3333%; }
.width-02{ width: 16.6666%; }
.width-03{ width:      25%; }
/* etc */

.panel{
    width: 100%;
    padding: 5px;
    box-sizing: border-box; /* so padding doesn't increase width */
}
<div class="column width-02">
    <div class="panel">Width-02</div>
</div>
<div class="column width-03">
    <div class="panel">Width-03</div>
</div>
<div class="column width-02">
    <div class="panel">Width-02</div>
</div>
<div class="column width-05">
    <div class="panel">Width-05</div>
</div>

Этот фрагмент создаст макет, аналогичный изображению ниже, однако все элементы .panel имеют отступы 5px со всех сторон. Я пытаюсь сделать краю содержимого внешних столбцов заподлицо с краем порта представления (или родительского контейнера, если на то пошло). Другим подходом было бы исключить класс .panel и просто пойти со столбцами:

.column{
    float: left;
    display: inline-block;
    padding-left: 10px;
    box-sizing: border-box;
}

.column:first-child{ padding-left: 0px; }

.width-01{ width:  8.3333%; }
.width-02{ width: 16.6666%; }
.width-03{ width:      25%; }
/* etc */
<div class="column width-02">Width-02</div>
<div class="column width-03">Width-03</div>
<div class="column width-02">Width-02</div>
<div class="column width-05">Width-05</div>

Опять же, это хорошо работает, принося результаты еще ближе к результатам изображения ниже, однако теперь (актуальная) проблема заключается в том, что прокладка ест по ширине колонн, завинчивающих распределение ширины. Столбец :first-child имеет 10 пикселей (или независимо от размера поля) большую ширину области содержимого, чем его братья и сестры.

Это может показаться безобидным, даже незаметным; однако есть несколько примеров, когда наличие точного (насколько это возможно) распределения ширины между элементами либо является необходимым, либо облегчит ситуацию.

Итак, используется ли заполнение, маржа или какая-либо их комбинация; есть ли какое-либо решение для флюидных столбцов, фиксированных полей, с равномерным распределением пространства желоба, которое не будет ограждать область содержимого "marginal" (*** haha ​​*) из соседних столбцов? **


Оригинальный вопрос

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

Есть ли способ, используя чистый CSS, для достижения ширины столбца с шириной столбца с фиксированными полями ширины?

Важное примечание. Эта цифра - всего лишь пример, а не конкретный макет, который я хочу достичь. Данное решение должно допускать любую комбинацию соседних столбцов, общее распределение ширины 12 или менее. Рассмотрите популярную 960 grid для справки.)

super_awesome_layout.css
Примечание. В макете с 12 столбцами распределение ширины столбцов на изображении равно 2, 3, 2 и 5 соответственно.

До сих пор я прибегал к сетке, которая, используя проценты, почти достигла этого. Проблема заключается в том, что для достижения полей каждый столбец требует дополнительного дочернего элемента (я называю их .panel):

width: 100%;
box-sizing: border-box;
padding: 10px;

Это снова почти нормально; проблема заключается в том, что первый и последний столбец имеют внешние "поля" (10px), а "поля" между каждым столбцом удваиваются (2 x 10px)

Конечно, с включением нового типа значений CSS3 calc() это можно было бы решить гораздо проще. Что-то в направлении:

.width-12 > .panel{ width: 100%; }
.width-09 > .panel{
    width: calc(75% - 10px);
    margin: ...;
}

У меня есть некоторые исправления Javascript, я взломал некоторые вещи, которые "работают", но я нахожусь в квесте. Надеюсь, самый священный из граалей существует.

Следующее решение, и один @avall предоставил (хотя, безусловно, хороший выбор для упрощения), к сожалению, не то, что я ищу. Основная проблема заключается в том, что поля не равномерно распределяются между столбцами.

Единственный способ, с помощью которого я вижу эту работу, - уменьшить отступ .panel до 5px и что-то вроде:

.column:first-child > .panel {
    padding-left: 0px;
}

.column:last-child > .panel {
    padding-right: 0px;
}

/* not necessary? in any case, haven't tested */
.column:only-child > .panel {
    padding-right: 0px;
    padding-left: 0px;
}

Это решение неприемлемо, только потому, что IE8 не может распознать псевдоселектора :last-child (и в этом случае :only-child).

4b9b3361

Ответ 1

Я, наконец, понял. В течение сотен часов, потраченных впустую в течение последнего десятилетия (хотя я полагаюсь на некоторые css, которые не работали бы год назад в любом случае). Я решил это без каких-либо ошибок. и в IE8 +.

Пожалуйста, подготовьте 2001: A Space Odyssey Music, потому что я сажу эту лодку.

Гениальность и трюк этому методу заключаются в использовании элементов встроенного блока, а затем с использованием слово-интервала для уравновешивания с использованием отрицательного правого края. Отрицательное правое поле на нем будет вытягивать элементы вместе, позволяя вам установить 100% ширину и по-прежнему подходить друг к другу, но оставьте элементы перекрывающимися. Установка отрицательного поля для родителя просто отменяет дочернюю маржу в отношении эффекта взаимодействия с общей шириной (магия "100% -ная ширина", которую мы пытаемся ударить "). Заполнение служит только для увеличения размера элемента и он бесполезен по отношению к противодействующей маржи. Он часто используется с коробкой в ​​решениях жюри, подтасованных к этой проблеме, за счет потери способности использовать отступы на всех остальных (и маржи) и, вероятно, требует больше обертки.

word-spacing предоставляет магический "третий способ" для добавления или удаления горизонтального расстояния между двумя элементами, если они являются встроенным блоком, поскольку в этом случае они будут считаться одним "словом", и любые пробелы между ними будут сворачиваются до одного единственного контролируемого свойства "word-spacing". Помимо этого трюка, я не знаю другого способа получить этот 100% -ный результат.

Я смиренно представляю окончательный ответ на проблему с гибкими столбцами с фиксированными канавками. Я называю свое решение "маневра омеги". Он имеет возможность обрабатывать произвольные столбцы смешанной ширины (с точностью до 100% общей ширины или чуть меньше для округления), любой размер желоба, любое предопределенное количество столбцов по ширине, обрабатывает произвольное количество строк с автоматической упаковкой и использует элементы встроенного блока, поэтому предоставляет параметры вертикального выравнивания, которые поставляются с встроенным блоком, и он не требует дополнительной разметки и требует только одно объявление класса в контейнере (не считая определяющих ширины столбцов). Я думаю, что код говорит сам за себя. Здесь реализация кода для 2-6 столбцов с использованием 10px желобов и бонусных вспомогательных классов для процентов.

EDIT: интересная головоломка. Мне удалось получить две несколько разные версии; один для mozilla и ie8 +, другой для webkit. Кажется, трюк с интервалом слов не работает в webkit, и я не знаю, почему другая версия работает в webkit, но не ie8 +/mozilla. Сочетание обоих позволяет вам охватить все, и я готов сделать ставку на способ унификации этой тактики или что-то очень похожее на решение этой проблемы.

EDIT2: В основном получил его! Магический text-align: justify получает WebKit почти там со словом-интервалом. Интервал просто кажется немного крошечным, как пиксели справа и, возможно, один лишний в желобах. Но он полезен и кажется более надежным в сохранении столбцов, чем все, что я использовал раньше. Он никогда не отбрасывает до меньшего количества столбцов, он будет сжиматься до тех пор, пока браузер не получит горизонтальную полосу прокрутки.

Edit3: У него немного близка к совершенству. Установка размера шрифта в 0 нормализует большинство оставшихся проблем с отключением интервала. Просто нужно исправить IE9, который разрушает его, если шрифт равен 0.

EDIT4: Получил ответ на IE с некоторых других сообщений ширины жидкости: -ms-text-justify: distribute-all-lines. Протестировано в IE8-10.

/* The Omega Maneuver */
[class*=cols] { text-align: justify; padding-left: 10px; font-size: 0;
             -ms-text-justify: distribute-all-lines; } 

 [class*=cols]>* { display: inline-block; text-align: left; font-size: 13px;
                word-spacing: normal; vertical-align: top;
                -webkit-box-sizing: border-box;
                   -moz-box-sizing: border-box;
                        box-sizing: border-box; }

.cols2 { word-spacing: 20px; padding-right: 20px; }
.cols3 { word-spacing: 30px; padding-right: 30px; }
.cols4 { word-spacing: 40px; padding-right: 40px; }
.cols5 { word-spacing: 50px; padding-right: 50px; }
.cols6 { word-spacing: 60px; padding-right: 60px; }

  .cols2 > * { margin-right: -10px; }
  .cols3 > * { margin-right: -20px; }
  .cols4 > * { margin-right: -30px; }
  .cols5 > * { margin-right: -40px; }
  .cols6 > * { margin-right: -50px; }

Некоторые помощники:

.⅛, .⅛s >* { width: 12.50%; }
.⅙, .⅙s >* { width: 16.66%; }
.⅕, .⅕s >* { width: 20.00%; }
.¼, .¼s >* { width: 25.00%; }
.⅓, .⅓s >* { width: 33.00%; }
.⅜, .⅜s >* { width: 37.50%; }
.⅖, .⅖s >* { width: 40.00%; }
.½, .½s >* { width: 50.00%; }
.⅗, .⅗s >* { width: 60.00%; }
.⅝, .⅝s >* { width: 62.50%; }
.⅔, .⅔s >* { width: 66.00%; }
.¾, .¾s >* { width: 75.00%; }
.⅘, .⅘s >* { width: 80.00%; }
.⅚, .⅚s >* { width: 83.33%; }
.⅞, .⅞s >* { width: 87.50%; }
.blarg-five-twelfs { width: 41.66%; }

Вы можете увидеть мой магнум opus в действии среди поля славы здесь: http://jsfiddle.net/xg7nB/15/

<div class="cols4">
    <div class="⅙">This is my magnum opus</div>
    <div class="¼">I finally beat css</div>
    <div class="⅙">⚉ ☺ ☻ ♾ ☢</div>
    <div class="blarg-five-twelfs">I BEAT IT FOREVER</div>
</div>

Абсолютная минимальная реализация, использующая в качестве примера 4 равных ширины (25%) ширины столбцов и 10px желобов, такова:

.fourEqualCols { word-spacing: 40px; padding: 0 40px 0 10px;
                 text-align: justify; font-size: 0;
                 -ms-text-justify: distribute-all-lines; }

.fourEqualCols>* { margin-right: -30px; width: 25%;
                   display: inline-block; word-spacing: normal;
                   text-align: left; font-size: 13px; }


<div class="fourEqualCols ">
  <div>GLORIOUSLY CLEAN MARKUP</div>
  <div>I hate extra markup and excessive class props</div>
  <div>Naked code</div>
  <div>get intimate</div>
</div>

Soooo этот код существенно заменяет практически любую существующую структуру сетки? Если вы можете произвольно установить водосточные желоба, а затем просто создать наборы столбцов, которые достигают 100% ширины, что строго превосходит большинство/все сетки на самом деле, не так ли? Если вы не разрабатываете для IE7 больше, как многие из нас, то в сочетании с размером окна: border-box отображает отступы и границы также без проблем.

Изменить: о, вы хотели, чтобы вы были на одном уровне с боками контейнера. Нет проблем с этим, мне пришлось специально добавить боковые желоба, чтобы мы могли просто изменить некоторые значения на 10 и избавиться от прокладки и вуаля. http://jsfiddle.net/bTty3/

[class^=cols] { text-align: justify; font-size: 0;
             -ms-text-justify: distribute-all-lines; } 

 [class^=cols] >* { display: inline-block; text-align: left; font-size: 13px;
                word-spacing: normal; vertical-align: top;
                -webkit-box-sizing: border-box;
                   -moz-box-sizing: border-box;
                        box-sizing: border-box; }

.cols2 { word-spacing: 20px; padding-right: 10px; }
.cols3 { word-spacing: 30px; padding-right: 20px; }
.cols4 { word-spacing: 40px; padding-right: 30px; }
.cols5 { word-spacing: 50px; padding-right: 40px; }
.cols6 { word-spacing: 60px; padding-right: 50px; }
 .cols2 >* { margin-right: 0 }
 .cols2 >* { margin-right: -10px; }
 .cols3 >* { margin-right: -20px; }
 .cols4 >* { margin-right: -30px; }
 .cols5 >* { margin-right: -40px; }
 .cols6 >* { margin-right: -50px; }

Same html

<div class="cols4">
    <div class="⅙">This is my magnum opus</div>
    <div class="¼">I finally beat css</div>
    <div class="⅙">⚉ ☺ ☻ ♾ ☢</div>
    <div class="blarg-five-twelfs">I BEAT IT FOREVER</div>
</div>

I beat CSS here's your proof

Ответ 2

Попробуйте это чистое решение CSS2: демонстрационная скрипта

Основа CSS (fiddle без косметики):

html, body {
    padding: 0;
    margin: 0;
}
#wrap {
    padding-right: 30px;
    overflow: hidden;
}
.col {
    float: left;
    margin-left: 40px;
    margin-right: -30px;
}
.col:first-child {
    margin-left: 0;
}
.small {
    width: 16.66%;
}
.medium {
    width: 25%;
}
.large {
    width: 41.66%;
}

HTML:

<div id="wrap">
    <div class="col small"></div>
    <div class="col medium"></div>
    <div class="col small"></div>
    <div class="col large"></div>
</div>

Протестировано на Win7 в IE7, IE8, IE9, Opera 11.50, Safari 5.0.5, FF 6.0, Chrome 13.0.


Обновление:

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

<div class="cols-12 count-04">
    <div class="col width-02"></div>
    <div class="col width-03"></div>
    <div class="col width-02"></div>
    <div class="col width-05"></div>
</div>

Смотрите эту обновленную скрипту, демонстрируя несколько различных столбцов.

Возможная ошибка:

Теоретически, это решение должно работать для любого количества столбцов для каждой возможной минимальной ширины столбца в любой ширине окна браузера. Но, похоже, все браузеры не могут обрабатывать: 1. большое количество столбцов ширины столбца или 2. небольшую ширину окна браузера.

Обратите внимание, что все браузеры с минимальной шириной 1440 пикселей, что составляет 12 раз 120 пикселей (пространство, занимаемое всеми полями 10 пикселей), отлично справляются с решением. И когда вы используете 2 или более столбца ширины столбцов, требование минимальной ширины браузера действительно падает до 720 пикселей (6 * 120 пикселей). Этот последний случай звучит более реалистично, но, тем не менее, я не могу объяснить это поведение браузера.

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

Я хотел бы услышать от других экспертов css по этому поводу, поэтому я добавил щедрость.

Ответ 3

Почему бы вам не использовать

.column > .panel {
    padding: 10px 0 10px 10px;
}

.column:first-child > .panel {
    padding-left: 0px;
}

Он будет делать 10px пробелов только между ящиками и без использования последнего-ребенка.

Ответ 4

Отметьте тридцать ответов в этом потоке для чистого CSS/HTML (макет Fluid с одинаково разнесенными "столбцами" без JavaScript)...

Ширина жидкости с равноотстоящими DIVs

http://jsfiddle.net/thirtydot/EDp8R/

Модификация JSFiddle демонстрирует, что "столбцы" могут быть разными фиксированными ширинами и по-прежнему иметь равные и текущие поля.

http://jsfiddle.net/EDp8R/43/

Затем, наконец, еще один пример, использующий проценты, сохраняя при этом равные и текущие поля.

http://jsfiddle.net/EDp8R/45/

Я понимаю, что это может быть не точное решение, но, похоже, оно становится довольно близким.

Ответ 5

В ссылках на исходный вопрос "Есть ли способ, используя чистый CSS, для достижения ширины столбца с шириной потока с фиксированными границами ширины?"

Замечательно, как чрезвычайно сложный CSS становится с такими вопросами. На прошлой неделе я работал над базовым шаблоном для создания моего собственного "святого грааля", в том числе границы, поля и прокладок... Кажется, CSS не подходит для таких вопросов. Хотя вопрос в виду довольно прост, он становится (почти?) Невозможным в CSS, особенно в кросс-браузере.

Самое смешное, что эти вопросы легко разрешаются с помощью таблиц. Я не понимаю, почему мы вынуждены веб-обществом использовать div вместо таких неопределенных аргументов, как "семантика" и "простой обзор", поскольку большинство аргументов слабы или даже ложны. Люди, говорящие на таблицах, приносят больше проблем, явно не понимая реальной трудности, которая лежит в CSS.

В любом случае, если вы хотите иметь табличную структуру (поскольку столбцы являются частью таблицы), я предлагаю использовать "display: table".

Чтобы достичь изображения под исходным вопросом с помощью чистого CSS, можно использовать следующее:

CSS

html,body{
    margin: 0px; 
    padding: 0px; 
    height: 100%; 
    width: 100%;
    overflow: auto;
}
.table{
    background: pink;
    display: table;
    width: 100%;
    height: 100%;
}
.tableRow{
    display: table-row;         
}
.tableCell{
    display: table-cell;
    vertical-align: top;
    height: 100%;  
}
/*
    Ensures the full size of the table-cell has the behaviour of a block-element. 
    This is needed, because 'table-cell' will behave differently in different browsers.
*/
.tableCell>div{
    height: 100%;
}
/*
    Padding has to be used instead of margin in 'border-box' modus.
*/
.tableCell>div>div{
    height: 100%;
    box-sizing:border-box;
    -moz-box-sizing:border-box;
}
/*
    The final content.
*/
.tableCell>div>div>div{
    background: lightblue;
    padding: 5px;
    height: 100%;
    box-sizing:border-box;
    -moz-box-sizing:border-box;
}


#col1{
    width: 16.66%;          
}
#col1>div>div{
    padding-right: 10px;
}
#col2{
    width: 25%;         
}
#col2>div>div{
    padding-right: 10px;
}
#col3{      
    width: 16.66%;
}
#col3>div>div{
    padding-right: 10px;
}
#col4{
    width: 41.66%;
}

HTML

<div class="table">
    <div class="tableRow">
        <div id='col1' class="tableCell">   
            <div><div><div>16.66%</div></div></div>
        </div>
        <div id='col2' class="tableCell">
            <div><div><div>25%</div></div></div>
        </div>
        <div id='col3' class="tableCell">
            <div><div><div>16.66%</div></div></div>
        </div>
        <div id='col4' class="tableCell">
            <div><div><div>41.66%</div></div></div>
        </div>  
    </div>
</div>

Я бы сказал, что он довольно переусердствовал с использованием дополнительных div для просто маржи, но, к сожалению, CSS не имеет модели "margin-box", которая фактически решила бы миллиард проблем.

Этот объем вложенного кода может заставить вас подумать "почему бы не использовать другие методы?" так как это может привести к уменьшению количества кода. Для очень конкретного желания, которое было бы так. Однако другие методы часто включают плавное или абсолютное позиционирование. Эти методы не могут достичь одного и того же: поплавки, например, могут достигать одинаковых по объему колоний, но когда вы хотите получить границу или маржу, вы окажетесь в беде. Для абсолютного позиционирования это больше похоже на противоположное: вы можете решить проблему margin, но высота может быть основана только на одном столбце.

По-моему, CSS не соответствовал требованиям. Несмотря на то, что заменить таблицы для позиции g, после всех этих лет все еще невозможно получить одинаковые результаты. Чтобы достичь "святого Грааля святых Граалей", структуры таблиц - это не просто самый простой способ, есть также единственный способ... по крайней мере, насколько я знаю, когда попытался сотня возможностей.

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

Ответ 7

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

Например:

/* Gutters */
h1, h2, h3, h4, h5, h6,
p, ul, ol, blockquote,
hr, address, pre, object, fieldset
{
    margin-right: .75rem;
    margin-left: .75rem;
    padding-right: .75rem;
    padding-left: .75rem;
}

Это также упрощает калибровку ваших столбцов, вложенность и применение фонов к вашим частям lego.

Ответ 8

Почему бы не использовать прописку, как в первом примере, а затем установить размер окна: border-box для всех элементов?

Ответ 9

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

Это не использует JavaScript и работает в IE8 +.

В этом решении маржа определяется на двух классах - поэтому ее легко изменить для гибких конструкций. Ширины столбцов также представляют собой пространство, которое они используют, например, строка из 2 столбцов имеет ширину 50%, а строка из 4 столбцов имеет ширину 25%.

Вы можете увидеть пример http://www.andrewjamestait.co.uk/conflexgrids/

Или он доступен на GitHub в https://github.com/andrewjtait/conflexgrids

Ответ 10

Если вы можете жить с другим вложенным div за столбец, вы можете определить желаемый запас для каждого. Чтобы избавиться от поля на левом и правом внешних краях, вы можете определить отрицательный запас на внешнем контейнере.

Например: pureCSS pure-g - это внешний контейнер, pure-u- * - это столбец node (display: inline-block), содержащий вложенный div. интервал - это имя этого пользовательского расширения сетки pureCSS, чтобы разрешить поля столбца.

.pure-g.spacing {
    margin: 0 -10px;
}

.pure-g.spacing [class *= "pure-u"] > div {
    margin: 10px;
}

Должно работать в большинстве браузеров. Скажите, если это не так - я уже использую его.

С уважением, Макс