Как должен работать CSS «display: table-column»?

87

Учитывая следующие HTML и CSS, я абсолютно ничего не вижу в своем браузере (Chrome и IE являются последними на момент написания). Все сворачивается до 0x0 пикселей. Зачем?

<!DOCTYPE html>
<html>
<head>
    <style type="text/css">
        section { display: table; height: 100%; background-color: grey; }

        #colLeft { display: table-column; height: 100%; background-color: green; }
        #colRight { display: table-column; height: 100%; background-color: red; }

        #row1 { display: table-row; height: 100%; }
        #row2 { display: table-row; height: 100%; }
        #row3 { display: table-row; height: 100%; }

        #cell1 { display: table-cell; height: 100%; }
        #cell2 { display: table-cell; height: 100%; }
        #cell3 { display: table-cell; height: 100%; }
    </style>
</head>
<body>
    <section>
        <div id="colLeft">
            <div id="row1">
                <div id="cell1">
                    AAA
                </div>
            </div>
            <div id="row2">
                <div id="cell2">
                    BBB
                </div>
            </div>
        </div>
        <div id="colRight">
            <div id="row3">
                <div id="cell3">
                    CCC
                </div>
            </div>
        </div>
    </section>
</body>
</html>
Элиот
источник

Ответы:

118

Модель таблицы CSS основана на модели таблицы HTML http://www.w3.org/TR/CSS21/tables.html.

Таблица разделена на СТРОКИ, и каждая строка содержит одну или несколько ячеек. Ячейки являются дочерними элементами ROWS, они НИКОГДА не являются дочерними элементами столбцов.

"display: table-column" НЕ предоставляет механизма для создания столбцов (например, страниц газет с несколькими столбцами, где контент может перетекать из одного столбца в другой).

Напротив, «таблица-столбец» ТОЛЬКО устанавливает атрибуты, которые применяются к соответствующим ячейкам в строках таблицы. Например, можно описать «Цвет фона первой ячейки в каждой строке зеленый».

Сама таблица всегда имеет такую ​​же структуру, как и в HTML.

В HTML (обратите внимание, что «td» находятся внутри «tr», а НЕ внутри «col»):

<table ..>
  <col .. />
  <col .. />
  <tr ..>
    <td ..></td>
    <td ..></td>
  </tr>
  <tr ..>
    <td ..></td>
    <td ..></td>
  </tr>
</table>

Соответствующий HTML с использованием свойств таблицы CSS (обратите внимание, что блоки div «столбец» не содержат никакого содержимого - стандарт не допускает размещение содержимого непосредственно в столбцах):

.mytable {
  display: table;
}
.myrow {
  display: table-row;
}
.mycell {
  display: table-cell;
}
.column1 {
  display: table-column;
  background-color: green;
}
.column2 {
  display: table-column;
}
<div class="mytable">
  <div class="column1"></div>
  <div class="column2"></div>
  <div class="myrow">
    <div class="mycell">contents of first cell in row 1</div>
    <div class="mycell">contents of second cell in row 1</div>
  </div>
  <div class="myrow">
    <div class="mycell">contents of first cell in row 2</div>
    <div class="mycell">contents of second cell in row 2</div>
  </div>
</div>



ДОПОЛНИТЕЛЬНО : стили и «строки», и «столбцы» могут быть стилизованы путем присвоения нескольких классов каждой строке и ячейке следующим образом. Этот подход дает максимальную гибкость при указании различных наборов ячеек или отдельных ячеек для стилизации:

//Useful css declarations, depending on what you want to affect, include:

/* all cells (that have "class=mycell") */
.mycell {
}

/* class row1, wherever it is used */
.row1 {
}

/* all the cells of row1 (if you've put "class=mycell" on each cell) */
.row1 .mycell {
}

/* cell1 of row1 */
.row1 .cell1 {
}

/* cell1 of all rows */
.cell1 {
}

/* row1 inside class mytable (so can have different tables with different styles) */
.mytable .row1 {
}

/* all the cells of row1 of a mytable */
.mytable .row1 .mycell {
}

/* cell1 of row1 of a mytable */
.mytable .row1 .cell1 {
}

/* cell1 of all rows of a mytable */
.mytable .cell1 {
}
<div class="mytable">
  <div class="column1"></div>
  <div class="column2"></div>
  <div class="myrow row1">
    <div class="mycell cell1">contents of first cell in row 1</div>
    <div class="mycell cell2">contents of second cell in row 1</div>
  </div>
  <div class="myrow row2">
    <div class="mycell cell1">contents of first cell in row 2</div>
    <div class="mycell cell2">contents of second cell in row 2</div>
  </div>
</div>

В сегодняшних гибких проектах, которые используются <div>для нескольких целей, разумно поместить некоторый класс в каждый div, чтобы облегчить обращение к нему. Здесь то, что раньше было <tr>в HTML, стало class myrowи <td>стало class mycell. Это соглашение и делает полезными указанные выше селекторы CSS.

ЗАМЕЧАНИЕ ПО ЭКСПЛУАТАЦИИ : размещение имен классов в каждой ячейке и использование вышеуказанных мультиклассовых селекторов дает лучшую производительность, чем использование селекторов, заканчивающихся на *, например, .row1 *или даже .row1 > *. Причина в том, что селекторы сопоставляются в первую очередь последними , поэтому при поиске совпадающих элементов .row1 *сначала выполняется поиск, *который соответствует всем элементам, а затем проверяет всех предков каждого элемента , чтобы определить, есть ли у какого-либо предка class row1. Это может быть медленным в сложном документе на медленном устройстве. .row1 > *лучше, потому что проверяется только непосредственный родитель. Но еще лучше сразу удалить большинство элементов с помощью .row1 .cell1. (.row1 > .cell1- еще более жесткая спецификация, но это первый шаг поиска, который имеет самое большое значение, поэтому обычно не стоит беспорядок и дополнительный мыслительный процесс относительно того, всегда ли он будет прямым потомком, добавлением дочерний селектор >.)

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

ИнструментальщикСтив
источник
Я сам этого не пробовал, но видел рекомендации для tanalin.com/en/projects/display-table-htc, который является решением javascript для IE6 и IE7. При запуске javascript преобразует страницу в старые теги таблицы HTML.
ToolmakerSteve
Решение работает на IE8 +, Firefox, Chrome, iPad, Android. Это хороший способ избежать компоновки таблиц, если вам нужна гибкая структура таблицы и вы поддерживаете более современные браузеры, перечисленные выше.
mbokil
<col style="color: red;" >не работает, но <col style="background-color: red;" >это нормально! что с этим не так?
xgqfrms
@xgqfrms: какое-то другое правило CSS должно переопределять цвет. Вероятно, правило применяется к элементу внутри ваших ячеек. Например, если ваш текст находится внутри <p>, то где-то у вас есть более конкретное правило, устанавливающее цвет <p>. Попробуй <col style="color: red !important;">. Если это сработает, то проблема в этом. Однако не приобретайте привычки злоупотреблять !important. Увидев эту работу, лучше всего удалить ее и определить более конкретный селектор, который будет иметь приоритет. Google "C более конкретный селектор", или смотрите smashingmagazine.com/2007/07/...
ToolmakerSteve
23

Тип отображения «таблица-столбец» означает, что он действует как <col>тег в HTML - т.е. невидимый элемент, ширина * которого определяет ширину соответствующего физического столбца включающей таблицы.

См. Стандарт W3C для получения дополнительной информации о модели таблиц CSS.

* И несколько других свойств, таких как границы, фон.

Случайный832
источник
2
Если colэлемент имеет логическую структуру, а она имеет, то как можно оправдать использование правила CSS display: table-column;, которое имеет только презентационную структуру? Согласно спецификации display( w3.org/wiki/CSS/Properties/display ), он должен «вести себя» как colэлемент. Но я не понимаю, насколько это полезно ...
Чхарви
1
@ TestSubject528491 Потому что тогда вы можете установить фон столбца, ширину столбца и т. Д. [Презентационной] таблицы. Но на самом деле это наиболее полезно с точки зрения определения правила стиля по умолчанию для самого <col>тега или эквивалентного тега на другом языке разметки на основе XML.
Random832 08
@chharvey: HTML col- это логический элемент, который содержит только презентационный стиль. В него нельзя поместить столбец с информацией - это распространенное заблуждение. Данные таблицы всегда располагаются в строках. display: table-column;преобразует логический элемент (обычно a div) в col. Это заставляет другие поля стиля, назначенные этому элементу, применяться к концепции представления «столбец». Результатом является логический элемент, который не отображается и содержимое которого, если оно есть, игнорируется; его единственный эффект - применить стиль к «столбцам» связанной презентации. См. Мой ответ для шаблона.
ToolmakerSteve