{display: table} для IE6 и IE7

display-table.htc — JavaScript-библиотека класса polyfill, предназначенная для эмуляции CSS-свойств display: table* в браузере Internet Explorer версий 6/7, лишённых их встроенной поддержки.

Библиотека предназначена исключительно для IE6/IE7 и автоматически отключается в IE8 и выше.

Эмуляция работает путём генерации реальной HTML-таблицы, автоматически заменяющей исходный элемент, который должен вести себя как таблица. (Замена на таблицу происходит только в IE6/IE7. Более современные браузеры эмуляцией не затрагиваются.)

Поддерживаются прозрачная эмуляция display: table для всех элементов, имеющих нестандартное CSS-свойство -dt-display: table (без необходимости явной привязки display-table.htc к каждому такому элементу), и эмуляция CSS-свойства border-spacing (с помощью CSS-свойства -dt-border-spacing).

Внимание
  • Стили исходных элементов в сгенерированную таблицу не копируются. Их следует привязать явно.
  • При привязке HTC-компонента следует указать абсолютный путь к HTC-файлу.
  • Сервер должен отдавать для HTC-файлов HTTP-заголовок ответа Content-Type: text/x-component.

Использование

HTML-код:
<ul id="nav" class="example">
    <li><a href="/">Home</a></li>
    <li><a href="/products/">Products</a></li>
    <li><a href="/contacts/">Contacts</a></li>
</ul>
CSS-код для всех браузеров:
/* Стандартный CSS-код для браузеров, поддерживающих {display: table} */
#nav    {border-spacing: 5px; display: table; } /* таблица */
#nav LI {display: table-cell; } /* ячейка таблицы */
CSS-код для IE6/IE7:
/* HTC-компонент привязывается к элементу-таблице (рекомендуется) */
#nav {behavior: url(/_/js/display-table.min.htc); }

/* Свойства с префиксом -dt- необходимы для display-table.htc */
#nav    {-dt-border-spacing: 5px; } /* таблица */
#nav LI {-dt-display: table-cell; } /* ячейка таблицы */
/* HTC-компонент можно привязать к BODY */
BODY {behavior: url(/_/js/display-table.min.htc); }

/* и тогда элементу-таблице необходимо свойство -dt-display: table */
#nav    {-dt-border-spacing: 5px; -dt-display: table; } /* таблица */
#nav LI {-dt-display: table-cell; } /* ячейка таблицы */

Для привязки HTC-компонента к элементу следует указать путь к HTC-файлу в CSS-свойстве behavior этого элемента. display-table.htc можно привязать к элементу BODY (или HTML) либо непосредственно к элементу, подлежащему преобразованию в таблицу.

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

В случае привязки к BODY или HTML элементы, подлежащие преобразованию в таблицу, определяются по наличию у них псевдосвойства -dt-display: table.

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

В результате работы display-table.htc элемент, к которому он привязан, применительно к приведённому выше примеру, будет заменён такой таблицей:

<table id="nav" class="example UL" cellpadding="0" cellspacing="5"><tbody valign="baseline">
    <tr>
        <td class="LI first LI-first"><a href="/">Home</a></td>
        <td class="LI"><a href="/products/">Products</a></td>
        <td class="LI last LI-last"><a href="/contacts/">Contacts</a></td>
    </tr>
</tbody></table>

Возможности

  • Сгенерированным таблицам, строкам и ячейкам автоматически назначаются идентификаторы (атрибут id) и классы (атрибут class), имевшие место в исходных элементах, на основе которых табличные элементы генерируются.
  • Сгенерированным таблицам, строкам и ячейкам автоматически назначаются классы, соответствующием именам исходных HTML-элементов в верхнем регистре (все исходные классы при этом сохраняются). Это позволяет писать для IE6/7 почти такой же CSS-код, как для более современных браузеров:

    /* Для браузеров, поддерживающих {display: table}: */
    #example UL {...}
    #example LI {...}

    /* Для IE6/7: */
    #example .UL {...}
    #example .LI {...}

  • Первым и последним строкам и ячейкам назначаются, соответственно, классы first и last (если первый и последний элементы совпадают, единственному элементу будут назначены оба класса). Для дополнительного удобства назначаются составные классы вида ЭЛЕМЕНТ-first и ЭЛЕМЕНТ-last. Например, первой строке таблицы, сгенерированной из элемента UL, будут назначены классы UL, first и UL-first. Если элемент является единственным потомком своего родителя, ему дополнительно добавляется класс вида ЭЛЕМЕНТ-first-last — это позволяет обойти отсутствие поддержки выборки по нескольким классам (.first.last) в IE6.
  • Вертикальное выравнивание ячеек генерируемой HTML-таблицы — baseline (в соответствии с выравниванием по умолчанию для ячеек псевдотаблиц, создаваемых средствами CSS) — и может быть переопределено при помощи стандартного CSS-свойства vertical-align.
  • Внутренние отступы ячеек генерируемой HTML-таблицы обнулены (в соответствии с отступами по умолчанию в CSS-таблицах) и могут быть переопределены при помощи стандартного CSS-свойства padding элемента-ячейки.
  • Если непосредственными дочерними элементами таблицы являются не строки, а ячейки (без промежуточного элемента-строки), то дочерним элементам исходного элемента-таблицы следует назначить CSS-свойство -dt-display: table-cell — тогда подразумеваемая строка в результирующей таблице будет сгенерирована автоматически.
  • Если display-table.htc привязан не к элементу, подлежащему преобразованию в таблицу, а к элементу BODY или HTML, то эмуляция display: table будет прозрачно применена ко всем элементам на странице, имеющим CSS-свойство -dt-display: table.
  • Поддерживается эмуляция CSS-свойства border-spacing. Чтобы ей воспользоваться, следует добавить CSS-свойство -dt-border-spacing со значением, дублирующим значение, указанное для стандартного CSS-свойства border-spacing. Значением border-spacing по умолчанию является ноль (соответствует значению по умолчанию для CSS-псевдотаблиц).
  • Элементы-разделители HR, расположенные в иерархии в исходном элементе-таблице на месте строки или ячейки, автоматически удаляются.

Ограничения

  • Прозрачная автоматическая привязка значений CSS-свойств исходных элементов к элементам сгенерированной HTML-таблицы не производится. По этой причине необходима явная привязка значений всех необходимых CSS-свойств к элементам сгенерированной HTML-таблицы при помощи дополнительных CSS-правил, предназначенных именно для IE6/7.
  • Поддерживается генерация только обычных строк (table-row; не table-header-group и проч.).
  • Между таблицей и её строками в DOM-иерархии генерируется дополнительный элемент TBODY, необходимый для IE6/IE7. Таким образом, результирующая иерархия элементов в сгенерированной таблице будет такой: TABLE > TBODY > TR > TD. Это следует учитывать при использовании дочерних CSS-селекторов (вида E1 > E2).
  • Если исходным элементом, на основе которого следует сгенерировать таблицу, является элемент, прямая замена которого на таблицу семантически недопустима (DT, DD, LI), либо если функциональность исходного элемента при замене на таблицу была бы нарушена (FORM, A), сгенерированной таблицей заменяется не сам элемент, а его содержимое.

Настройки веб-сервера

Content-Type

Для гарантированной работы HTC-компонента необходимо, чтобы сервер отдавал для таких файлов HTTP-заголовок Content-Type со значением text/x-component. В веб-сервере Apache это можно сделать при помощи следующей строки в файле .htaccess, расположенном в одной из родительских директорий htc-файла:

AddType text/x-component .htc

Веб-сервер Microsoft IIS обычно отдаёт правильный заголовок Content-Type по умолчанию, без дополнительной настройки.

Кэширование

По умолчанию HTC-файлы не кэшируются в браузере и повторно загружаются с сервера при загрузке каждой страницы. Чтобы HTC-файл кэшировался, сервер должен отдавать HTTP-заголовок Expires с ненулевым сроком «годности» файла. В веб-сервере Apache это можно сделать при помощи следующих строк в файле .htaccess:

# кэшируем любой файл на час (3600 секунд)
ExpiresActive on
ExpiresDefault A3600

При этом в конфигурации Apache должен быть включён модуль mod_expires (обычно включён).

Рекомендации по быстродействию

  • Привязка display-table.htc к элементу BODY/HTML удобнее, но при привязке непосредственно к элементу, подлежащему преобразованию в таблицу, эмуляция отработает намного быстрее. Это связано с тем, что при привязке к BODY/HTML последовательно перебираются и проверяются на наличие свойства -dt-display: table все элементы HTML-документа — даже если среди них вообще нет ни одного элемента, подлежащего преобразованию в таблицу. Чем больше элементов в документе, тем больше времени займёт их перебор и тем заметнее будет задержка между первичной отрисовкой страницы и повторной отрисовкой после замены элементов на таблицы.
  • Чтобы избежать повторного применения HTC-компонента к уже сгенерированной таблице, имеет смысл в CSS-селектор правила, содержащего подключение display-table.htc, включать имя исходного элемента (например, не #nav, а DIV#nav). Тогда селектор будет соответствовать исходному элементу, но не сгенерированной таблице. Защита от зацикливания предусмотрена (эмулирующий скрипт автоматически завершает свою работу, если элемент уже является таблицей), но предотвращение холостого повторного запуска эмуляции в любом случае положительно скажется на быстродействии.
  • Чтобы HTC-компонент кэшировался в браузере, не загружаясь повторно с каждой страницей, сервер должен отдавать правильный HTTP-заголовок Expires (см. секцию «Настройки веб-сервера» → «Кэширование» выше).