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

Обновление И Резюме

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

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

я работаю над фреймворком CSS для нескольких проектов, которые разделяют требования к дизайну, а именно fluid 12 расположение столбцов. Использование floated .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 отступы со всех сторон. я пытаюсь сделать край содержимого внешних столбцов заподлицо с краем view-port (или родительский контейнер, если на то пошло). Другой подход-устранить .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>

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

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

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


Исходный Вопрос

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

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

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

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) псевдо-селекторы.

10 ответов


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

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

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

word-spacing обеспечивает магический "третий способ" для добавления или удаления горизонтального расстояния между двумя элементами, при условии, что они являются встроенным блоком, так как они будут считаться одним "словом" в этом случае, и любые пробелы между будут collpapse до одного управляемого " 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%; }

вы можете увидеть мой magnum 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%) ширины cols и 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 делает заполнение и границу также не проблемой.

Edit: о, правильно, вы хотели быть вровень с бортами контейнера. Нет проблем с этим, я должен был специально добавить боковые желоба поэтому мы можем просто изменить некоторые значения на 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; }

тот же 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


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

база CSS (скрипка без косметики):

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.


обновление:

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

<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>

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

возможные ошибки:

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

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

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

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


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

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

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

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


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

ширина жидкости с равным расстоянием DIVs

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

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

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

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

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

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


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

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

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

в любом случае, если вы хотите имейте структуру таблицы (поскольку colums являются частью таблицы), я предлагаю использовать "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>

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

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

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

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


Я использую сетку OOCSS для этого

https://github.com/stubbornella/oocss

недавно я разместил демо онлайн на своем собственном сайте, так как нет подходящих примеров в интернете: (

http://www.leipeshit.com/awesome_stuff/oocss/core/grid/grids_all.html


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

например:

/* 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.


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


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

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

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

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

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


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

Е. Г.: Используя pureCSS pure-g-внешний контейнер, pure-u-* - узел столбца (дисплей: встроенный блок), содержащий вложенный div. интервал-это имя пользовательского расширения системы сетки pureCSS для разрешения столбца маржи.

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

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

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

С уважением, Макс!--2-->