Все, что вы знали о CSS —  неправда

VitaliyRodnenko, 16.11.2008

После релиза, IE8 будет поддерживать множество новых параметров для аттрибута дисплея CSS, включая параметры, относящиеся к таблицам: table, table-row и table-cell — и это последний крупный браузер с их поддержкой. Это событие обозначит конец сложных методов CSS разметки и забьет последний гвоздь в гроб использования HTML таблиц для верстки. В итоге, создание сеток разметки табличного вида будет быстрее и проще.

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

CSS таблицы решают все проблемы, появляющиеся при использовании абсолютной системы коодинат или флоатов, для создания многострочной разметки в современных браузерах. Задание параметра table для аттрибута display позволит вам отобразить элементы так, как будто они являются элементами таблицы. Главное преимущество табличной разметки CSS — это возможность легкого определения границ клетки, позволяющее нам добавить к ней фон и прочее без семантических проблем выделения нетабличных элементов, как в HTML таблице документа.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"> 
  <head> 
    ⋮ HTML head content… 
  </head> 
  <body> 
    <div id="wrapper"> 
      <div id="header"></div> 
      <div id="main"> 
        <div id="nav"> 
          ⋮ navigation column content… 
        </div>
        <div id="extras">
          ⋮ news headlines column content… 
        </div>
        <div id="content">
          ⋮ main article content… 
        </div>
      </div>
    </div>
  </body>
</html>

HTML код определяет нужный порядок вывода данных. Первой идет столбец nav, затем extras, последним идет content.

Также нам необходимо написать требуемый CSS код:

#main { 
  display: table; 
  border-collapse: collapse; 
} 

#nav { 
  display: table-cell; 
  width: 180px; 
  background-color: #e7dbcd; 
} 

#extras { 
  display: table-cell; 
  width: 180px; 
  padding-left: 10px; 
  border-right: 1px dotted #d7ad7b; 
} 

#content { 
  display: table-cell; 
  width: 380px; 
  padding-left: 10px; 
}

Только что созданная нами табличная разметка будет корректно отображаться как в IE8, так и в Firefox, Safari и Opera.

Табличная CSS разметка

Мы получили разметку из трех столбцов равной высоты без применения особых приемов, таких как ложных столбцов с помощью фоновых рисунков, проблем с размещением или необходимости очищать floats!

Как это работает?

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

  • table заставляет элемент вести себя, как элемент таблицы;
  • table-row заставляет элемент вести себя, как элемент строки таблицы;
  • table-cell заставляет элемент вести себя, как элемент ячейки таблицы;
  • table-row-group заставляет элемент вести себя, как элемент группы строк таблицы;
  • table-header-group заставляет элемент вести себя, как элемент группы заголовков таблицы;
  • table-footer-group заставляет элемент вести себя, как элемент группы нижнего колонтитула;
  • table-caption заставляет элемент вести себя, как элемент заголовка таблицы;
  • table-column заставляет элемент вести себя, как элемент столбца таблицы;
  • table-column-group заставляет элемент вести себя, как элемент группы столбцов таблицы.

Подождите, разве разметка таблицами — это правильно?

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

HTML элемент table — это семантическая структура: он описывает, что из себя представляют данные. Поэтому, вам нужно использовать table, только если данные, которые вы размещаете — табличные, например, финансовая информация. Она обычно размещается на компьютере электронной таблицей, поэтому наверное следует определять её как таблицу в HTML.

С другой стороны, параметр table аттрибута display, просто показывает как что-то должно выглядеть в браузере и не имеет семантического значения!

Использование элемента table для вашей разметки говорит агенту пользователя: «Это табличные данные». А применение связки div-ов просит его отборазить их визуально определенным образом, если это возможно.

Конечно же, нам не следует использовать display: table; в связке элементов div, когда мы имеем действительно табличные данные. Наш простой пример, описанный выше, заставляет нашу разметку выглядеть так, как будто у нас есть однострочная таблица с тремя ячейками, не требуется большое воображение, чтобы осознать потенциал этой техники для легкого создания комплексных видов разметок.

Анонимные элементы таблиц

Таблицы CSS придерживаются обычных правил табличной разметки, которые открывают очень мощное свойство табличных разметок CSS: пропущенные элементы таблиц создаются анонимно самим браузером. Спецификация CSS 2.1 утверждает:

Отличные от HTML документальные языки могут не содержать всех элементов модели таблицы CSS 2.1. В этих случаях «пропущенные» элементы дожны быть созданы, чтобы табличная модель заработала. Любой элемент таблицы автоматически сгенерирует вокруг себя необходимые анонимные объекты таблицы, состоящие по крайней мере из трех вложенных объектов, соответсвующих элментам «table»/«inline-table», «table-row», и «table-cell».

Это значит, что если мы используем display: table-cell; без предварительного размещения ячейки в месте, относящемся к display: table-row;, то строка будет подразумеваться — браузер будет вести себя так, как будто объявленная строка на самом деле есть.

Давайте используем простой пример, чтобы объяснить этот прием: разметку из трех ячеек, показанную ниже. Мы рассмотрим три разных примера HTML кода, которые приведут к одинаковой визуальной разметке.

Табличная CSS разметка - макет

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

<div class="container">
  <div class="row">
    <div class="cell">CELL A</div>
    <div class="cell">CELL B</div>
    <div class="cell">CELL C</div>
  </div>
</div>

Набор вложенных элементов div не выглядит как-то особенно, но скоро мы это изменим. CSS тоже очень простой:

.container {
  display: table;
}

.row {
  display: table-row;
}

.cell {
  display: table-cell;
  width: 100px;
  height: 100px;
  border: 1px solid blue;
  padding: 1em;
}

Этот CSS относит элемент с классом «container» к display: table;, элемент с классом «row» к display: table-row;, а элемент с классом «cell» — к display: table-cell; с заданием его границы, высоты и ширины.

Вышеописанная HTML разметка явно создает элементы для таблицы из строки с тремя ячейками, используя все CSS классы, созданные нами. Однако, мы можем уменьшить код, убирая строковые элементы div вот так:

<div class="row">
  <div class="cell">CELL A</div>
  <div class="cell">CELL B</div>
  <div class="cell">CELL C</div>
</div>

Несмотря на то, что в этой разметке пропущен элемент, представляющий таблицу, она будет создана браузером, как анонимный элемент. Мы можем ещё сильнее сократить код:

<div class="cell">CELL A</div>
<div class="cell">CELL B</div>
<div class="cell">CELL C</div>

В такой разметке пропущены элементы, описывающие таблицу и её строку, они оба создаются браузером, как анонимные элементы. Даже при пропуске элементов в разметке, конечный результат одинаков.

Правила создания анонимных элементов таблицы

Эти анонимные элементы создаются не магией, и они не будут автоматически появляться для любого недостатка вашего HTML кода. Чтобы полностью использовать преимущества анонимных элементов таблицы, желательно ознакомиться с правилами их создания. Если разметка запрашивает предполагаемый элемент, браузер создает анонимную ячейку и записывает ее CSS аттрибуту display одно из значений table, table-row, или table-cell, в зависимости от контекста.

Если у вас есть элемент, определенный, как display: table-cell;, но его непосредственный предок (элемент, содержащий его), не определен, как table-row, будет создан анонимный элемент table-row, чтобы включить в него ячейку и любые последующие родственные элементы, которые также определены table-cell, до тех пор, пока не попадется элемент, не относящийся к table-cell, таким образом они будут помещены в одну и ту же строку. Например, следующая разметка:

<div class="cell">CELL A</div>
<div class="cell">CELL B</div>
<div class="cell">CELL C</div>
<div>Not a cell</div>

Верхние три элемента div, имеющие класс «cell», определяются в display: table-cell; и будут отображены друг за другом, как если бы они были в однострочной таблице, а последний элемент div не будет включен в ряд, поскольку он не относится к display: table-cell;.

Если элемент относится к display: table-row;, в то время как его предок не определен, как table (или table-row-group), будет создан анонимный элемент, отнесенный к display: table; чтобы включить в него ряд и любые последующие родственные элементы, которые также определены display: table-row;. Также, если элементу, определенному как table-row, не хватает элемента table-cell непосредственно в нем, будет создан анонимный элемент table-cell, чтобы включить в него все элементы, определеные как table-row.

Рассмотрим на примере:

<div class="row">ROW A</div>
<div class="row">ROW B</div>
<div>Not a row</div>

Верхние два элемента div, имеющие класс «row», определяются в display: table-row; и будут отображены друг под другом, как если бы они были рядами в одностолбцовой таблице, а последний элемент div не будет включен в эту таблицу.

Аналогично, если элемент отнесен к любому другому параметру display , поддерживающему элементы, которые находятся прямо внутри родительского табличного элемента, такие как table-row-group, table-header-group, table-footer-group, table-column, table-column-group и table-caption, но не имеет предка, опеределенного как display: table;, будет создан анонимный элемент table, чтобы включить в него элемент и любые последующие родственные элементы, с подходящими значениями display.

Другие полезные аттрибуты таблиц

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

Table-layout

Присваивание table-layout значение fixed сообщает браузеру, что таблица должна вопроизводиться по фиксированному алгоритму форматирования ширины ячеек. Это полезно в разметке с фиксированной шириной, которую мы создавали ранее.

Border-collapse

Так же, как и с обычными HTML таблицами, вы можете использовать аттрибут border-collapse для выбора используемых границ между ячейками таблицы разметки из collapse или separate.

Border-spacing

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

Создание идеальной сетки

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

Табличная CSS разметка - галерея

Код для нашей галереи выглядит так:

<div class="grid"> 
  <div class="row"> 
    <div class="image"> 
      <img src="images/photo1.jpg" alt="A Lily" /> 
      <p>A lily in the gardens of The Vyne Country House</p> 
    </div> 
    <div class="image"> 
      <img src="images/photo3.jpg" alt="A Fuchsia plant" /> 
      <p>Fuchsia plant in my garden</p> 
    </div> 
  </div> 
  <div class="row"> 
    <div class="image"> 
      <img src="images/photo2.jpg" alt="A crazy looking Allium flower" />
      <p>A crazy looking flower</p>
    </div>
    <div class="image">
      <img src="images/photo4.jpg" alt="A Robin sitting on a fence" />
      <p>
        This robin has been visiting our garden over the summer. 
        He is very friendly and doesn't seem to be too worried about sharing the garden with us.
      </p>
    </div>
  </div>
</div>

Каждая ячейка изображения галереи содержит элемент img и заголовка в элементе p, находящегося в div c классом «image». Каждая строка содержится в div с классом «row», а вся галерея располагается в элементе div c классом «grid».

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

.grid { 
  display: table; 
  border-spacing: 4px; 
} 
.row { 
  display: table-row; 
} 
.image { 
  display: table-cell; 
  width: 240px; 
  background-color: #000; 
  border: 8px solid #000; 
  vertical-align: top; 
  text-align: center; 
} 
.image p { 
  color: #fff; 
  font-size: 85%; 
  text-align: left;
  padding-top: 8px;
}

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

Применение примеров на практике

В этой статье были рассмотрены основные примеры использования табличных параметров CSS аттрибута display, служащего долгожданной наградой в борьбе за создание надежных сеток разметки с использованием CSS! Мы разобрали многочисленные табличные параметры display, посмотрели на природу анонимных табличных элементов и открыли несколько полезных свойств таблиц CSS.

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

Версия на английском.

Подписаться на обновления блога

Вам понравился наш блог, хотите следить за обновлениями? Подпишитесь на RSS рассылку или рассылку по электронной почте. Так же вы можете следить за нами в Twitter.

Категории: CSS, Переводы | Комментировать

Комментарии (24)

  1. Игорь / 16.11.2008 в 19:10

    Это Вы, получается перевели забугорную статью?

    Извините, пожалуйста за наивный вопрос, а что, сейчас нельзя просто DIV’ами нормальную разметку для всех браузеров создать? Ну, имею ввиду «нормальные браузеры» и IE6-7

  2. Octane / 16.11.2008 в 21:27

    Читайте внимательнее, никакого перехода от DIV-ой верстки описано не было. В статье рассмотрено несколько CSS-свойст, которые заставляют отображаться блоки, как элементы таблицы и в некоторых ситуациях, их применение позволяет упростить код.

  3. Skaizer / 17.11.2008 в 02:14

    Это Вы, получается перевели забугорную статью?

    Английская версия: Published on October 21, 2008

  4. injun #576871 / 17.11.2008 в 15:42

    Я думаю, что IE должен быть умертвлён. Окончательно и бесповоротно.

  5. rotor / 19.11.2008 в 11:16

    Спасибо за перевод. Действительно отличный выход для вёрстки каталогов, галерей и всего где требуется эмулировать табличный вид средствами CSS. Да и людям, которые до сих пор не понимают как сделать колонки одинаковой высоты с помощью псевдоколонок или фона, это самый простой способ научиться.

    Будем ждать релиза IE8.

  6. Skaizer / 20.11.2008 в 00:16

    Спасибо за перевод.

    Всегда пожалуйста! Если есть какие-либо англоязычные статьи на примете, присылайте, выложим перевод :)

    Я думаю, что IE должен быть умертвлён. Окончательно и бесповоротно.

    ИМХО, просто надо правильно готовить. А IE8 я думаю будет отличным браузером!

  7. adw0rd / 20.11.2008 в 19:34

    Отличная статья, поскорее бы ИЕ8 :)

  8. Skaizer / 08.12.2008 в 14:09

    Кстати, по поводу релиза IE8, не известно когда он выйдет?

  9. rotor / 08.12.2008 в 19:57

    Точно неизвестно, но, если верить заявлениям разработчиков, поддержка Beta 2 была заявлена до 31.12.2008. Теоретически, в начале 2009 должен появиться первый релиз IE8.

  10. Skaizer / 09.12.2008 в 17:53

    О, отлично, уже скоро.

  11. IR / 03.02.2009 в 01:11

    Класс! Прям переворот в моем восприятии таких вещей. Уже сделала скрипт для уравнивания высот пар блоков, а, оказывается, в CSS есть такие вкусности! Жаль только, что шестой Эксплорер все это дело игнорирует. Результат-то действительно шедевральный.

  12. Skaizer / 04.02.2009 в 13:14

    Не сказать, что прям шедевральный :) Просто дает возможность значительно упростить код.

  13. Музыкант / 07.02.2009 в 15:58

    Придумал кроссбраузерный вариант на основе вашего: для нормальных браузеров — как у вас, выравнивание высоты с помощью display:table-cell. Для ИЭ:

    уравнивание высот для пар блоков — в css с помощью expression:

    #block1{height:expression( document.getElementById(«block1″).offsetHeight>document.getElementById(«block2″).offsetHeight ? document.getElementById(«block1″).offsetHeight : document.getElementById(«block2″).offsetHeight — 10 +»px»);}

    #block2{height:expression(document.getElementById(«block1″).offsetHeight-10+»px»);}

    (expression работает только в ИЭ)

    выстраивание двух блоков «бок о бок» — с помощью только для ИЭ работающего _display:block;_float:left; в стилевом файле

    Вроде работает нормально. Как вам такое решение?

  14. Некто / 28.02.2009 в 18:12

    Код из раздела «Создание идеальной сетки» отображается корректно только для FF,Mozilla,Opera, но никак для IE7, который показан на рисунке. Все это липа, т.к. поддержка значений атрибута display: table/table-row/table-cell для браузера IE будет только в версии 8 (по заявлению самих разработчиков Microsoft) …

  15. asm / 24.03.2009 в 03:11

    никто не будет пользовать методы, неработающие в ie6, поэтому это всё не важно. большинство любят гипножабу и юзают ие6

  16. Николай / 28.12.2009 в 16:25

    Спасибо за статью!!!
    В статье Я нашел один из способов решения «своей проблемы»!!!

    А то, что в IE7 или раних версиях НЕ будет проблем — ну, дык а что ВЫ хотели?!
    где ВЫ видили, чтобы разработчики ПРИДЕРЖИВАЛИСЬ рекомендаций W3?!?!?!?!

    понятно, что ЧТО-ТО не будет отображаться (отображаться правильно) во ВСЕЕЕЕХ браузерах!!!
    лично Я(со своим мААААленьким опытом сайтостроения) придерживаюсь того мнения, что:
    необходимо писать совместимы код со всеми(!) браузерами, но все равно делать акцент на более массовом(-ых) браузере(-ах)…. например: Опера… или ….Лисице»»»

  17. Илья / 13.01.2010 в 14:01

    Немного не понял, а как объединять «ячейки»?

  18. whirlwind / 18.01.2010 в 14:24

    «Объединение ячеек», подозреваю можно будет реализовать через создание в CSS дополнительного класса, c width 200 px, например,

    .cell2 {
    display: table-cell;
    width: 200px;
    height: 100px;
    border: 1px solid blue;
    padding: 1em;
    }

    и не забыть присвоить класс «сдвоенной» ячейке.

  19. Илья / 18.01.2010 в 16:09

    кривовато…

  20. ko1obok / 08.03.2010 в 05:53

    >>>лично Я(со своим мААААленьким опытом сайтостроения) придерживаюсь того мнения, что:
    >>>необходимо писать совместимы код со всеми(!) браузерами, но все равно делать акцент на >>>более массовом(-ых) браузере(-ах)…. например: Опера… или ….Лисице»»»
    самый массовый и популярный к сожалению IE

  21. Time / 31.08.2015 в 18:04

    ×àñû âàøå âðåìÿ

    êðàòêàÿ âûäåðæêà

  22. Williamnug / 25.11.2015 в 12:45

    скачать http://dll.pp.ua/

  23. RobertoniFumn / 31.12.2015 в 09:15

    Она любит жить полной жизнью, не ограничивая себя ни в чём.
    Этот астрологический прогноз относится и к ситуациям на дороге, и к контактам с людьми.
    Родился 3 октября (21 сентября по старому стилю) 1895 года в селе Константинове Рязанской губернии в крестьянской семье, рос и воспитывался в атмосфере глубокого народного православия.
    Благоприятный день, чтобы справиться с проблемами, обо всем договориться с партнерами и друзьями.
    всем постам (1985) Внимание!

    cccp

  24. WilliamTaf / 06.05.2016 в 21:31

    I am so grateful for your forum topic.Much thanks again. Will read on…

Оставить комментарий

480×60
480×60