Опрос
Вы участвуете в программе Windows Insider?
Популярные новости
Обсуждаемые новости

13.05.2011 12:06 | dronov_va

Эта статья открывает цикл, описывающий возможности стилей CSS3, поддержка которых появится в Internet Explorer 10. На данный момент они поддерживаются Internet Explorer 10 Platform Preview 1.

И начнём мы с рассмотрения так называемой сеточной разметки (grid layout), как она называется в документах W3C. В документации Microsoft она носит название выравнивания по сетке (grid alignment). Ради соблюдения стандартов и во избежание путаницы мы будем называть её так, как рекомендует W3C.


1. Введение в сеточную разметку
Но что такое сеточная разметка? Зачем она нужна? И чем она лучше всего того, что уже присутствует в HTML и CSS? Ответы на все эти вопросы мы дадим во введении. Но приготовимся - введение будет долгим.

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

Надо также сказать несколько слов о размерах отдельных фрагментов. Они могут:

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


Размеры, относящиеся к первой разновидности, называются фиксированными, а относящиеся к остальным трём разновидностям - относительными. Фиксированные размеры не меняются при изменении размеров окна браузера, относительные - меняются.

Давайте рассмотрим пример такой сложно отформатированной веб-страницы. Её схема показана на рис. 1.


Рис. 1. Пример страницы со сложным форматированием


Здесь:

  • фрагмент 1 занимает всю ширину страницы и имеет фиксированную высоту в 50 пикселов;
  • фрагмент 5 занимает всю ширину страницы и имеет фиксированную высоту также в 50 пикселов;
  • фрагмент 2 имеет такую ширину, чтобы полностью вместить своё содержимое, и занимает оставшееся свободное пространство страницы по высоте;
  • фрагмент 4 имеет ширину, равную 1/4 от оставшегося свободного пространства страницы, и занимает оставшееся на ней свободное пространство по высоте;
  • фрагмент 3 имеет ширину, равную 3/4 от оставшегося свободного пространства -страницы, и имеет такую высоту, чтобы полностью вместить своё содержимое.


Как всё это реализовать на практике?

1.2. Три способа форматирования веб-страниц, их достоинства и недостатки
Существуют три способа. Рассмотрим их по порядку, так сказать, старшинства.

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

Достоинства фреймов:

  • Фреймы гарантированно поддерживаются всеми современными браузерами. Вообще, фреймы появились очень давно, ещё во времена HTML2; правда, тогда они ещё не входили в стандарт этого языка. Стандартными средствами они стали только в HTML4.
  • HTML-код, создающий фреймы, очень компактен.
  • Не требуется никаких веб-сценариев - всё реализуется средствами HTML.


Недостатки:

  • Для создания сложного форматирования требуется создать многократно вложенные друг в друга наборы фреймов, а это довольно трудоёмко.
  • Веб-страница, содержащая фреймы, не может иметь никакого другого содержимого.
  • Содержимое страницы оказывается разделённым на множество фрагментов, хранящихся в отдельных файлах, что может быть неприемлемо.
  • Если требуется управлять содержимым страницы из веб-сценариев, могут возникнуть трудности с получением доступа из содержимого одного фрейма к содержимому другого.
  • С помощью фреймов мы можем только отформатировать только страницу целиком, но не её фрагмент (например, содержимое ячейки таблицы или блочного контейнера <DIV>).
  • В конце концов, фреймы сейчас выглядят крайне архаично.


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

Достоинства таблиц разметки:

  • Таблицы гарантированно поддерживаются всеми современными браузерами. Их поддержка появилась в HTML4.
  • Всё содержимое страницы хранится прямо в ней.
  • С помощью таблиц разметки мы можем отформатировать и фрагмент страницы, например, содержимое ячейки другой таблицы или блочного контейнера <DIV>.


Недостатки:

  • Для реализации сложных веб-страниц придётся создавать набор таблиц, причём одни таблицы будут вложены в ячейки других. Во-первых, этот процесс очень трудоёмок. А во вторых, в результате мы получим громоздкую структуру таблиц и, соответственно, сложный HTML-код, разобраться в котором будет непросто.
  • Указанные нами размеры строк и столбцов таблицы - не более чем рекомендация браузеру. В реальности он вполне способен задать для них совершенно другие размеры, что может испортить дизайн.


Способ третий - плавающие контейнеры <DIV>. Мы создаём контейнеры, форматируем их как плавающие (float) средствами CSS и помещаем в них фрагменты содержимого веб-страницы.

Достоинства плавающих контейнеров:

  • Плавающие контейнеры гарантированно поддерживаются всеми современными браузерами. Их поддержка появилась в HTML4 и CSS1.
  • HTML-код, создающий контейнеры, исключительно компактен.
  • Всё содержимое страницы хранится прямо в ней.


Недостатки:

  • Одними лишь средствами CSS очень трудно создать контейнеры с относительными размерами; для этого придётся использовать набор многократно вложенных друг в друга контейнеров и сложные стили. Как вариант, можно задействовать веб-сценарии, которые будут изменять размеры контейнеров, но это также нетривиальная задача, особенно при сложном форматировании.
  • С помощью плавающих контейнеров можно просто отформатировать Web-страницу целиком, но очень трудно - её фрагмент. Хотя средства CSS вроде бы предусматривают возможность сделать это.


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

1.3. Четвёртый способ - сеточная разметка CSS3
Давайте сформулируем требования к средствам форматирования веб-страниц, который мы хотели бы получить в своё распоряжение.

Прежде всего, желательно, чтобы эти средства основывались на контейнерах <DIV>. Благодаря этому в список их достоинств добавятся компактность HTML-кода и "монолитность" веб-страницы.

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

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

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

Наконец, эти средства не должны требовать для реализации сложного HTML- и CSS-кода. В конце концов, любое нововведение должно облегчать наш труд, а не усложнять его.

Что же мы получим в результате?

А получим мы четвёртый способ форматирования веб-страниц - сеточную разметку (grid layout), являющуюся частью разрабатываемого в настоящий момент стандарта CSS3. Всеми заявленными нами требованиями она обладает в полной мере.

Единственный недостаток сеточной разметки - крайне ограниченная поддержка браузерами. В самом деле, очень немногие из даже самых современных на данный момент программ поддерживают её; так, совсем недавно вышедший Internet Explorer 9 "не понимает" сеточной разметки.

Впрочем, ситуация со временем изменится. А пока что давайте готовиться, чтобы встретить сеточно-разметочное будущее Интернета во всеоружии.


2. Реализация сеточной разметки
Сеточная разметка реализуется с помощью особых атрибутов стилей CSS. Эти атрибуты мы сейчас рассмотрим.

Примечание:
Имена всех атрибутов стилей, что будут описаны в этой статье, предваряются символами "-ms-". Именно в таком виде они поддерживаются Internet Explorer 10 Platform Preview 1. В последующих редакциях Internet Explorer 10, вероятно, эти атрибуты стилей будут поддерживаться в том виде, в каком они указаны в стандарте CSS3, - без вышеуказанных символов в именах; так, атрибут стиля -ms-grid-columns будет называться grid-columns.

2.1. Указание на использование сеточной разметки в элементе-родителе
Первое, что нам нужно сделать для реализации сеточной разметки, - собственно указать, что она будет реализована. Это нужно сделать в элементе веб-странице, который станет родителем для содержимого, что будет отформатировано с её применением: контейнере <DIV>, ячейке таблицы или даже секции тела страницы (теге <BODY>).

Сделать это можно с помощью знакомого нам атрибута стиля display. Для него нужно задать значение -ms-grid.

#divGrid { display: -ms-grid; }


Задаём сеточную разметку для контейнера divGrid.

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

При использовании сеточной разметки в пространстве внутри элемента-родителя формируется своего рода невидимая таблица - сетка разметки. Контейнеры будут размещаться в ячейках этой таблицы-сетки.


Рис. 2. Сетка разметки для страницы, показанной на рис. 1



Посмотрим на рис. 2. Там мы видим тонкие пунктирные линии чёрного цвета - это воображаемые линии, формирующие сетку разметки. А границы отдельных контейнеров показаны толстыми чёрными линиями.

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

Атрибут стиля -ms-grid-columns служит для указания значений ширины отдельных столбцов сетки разметки. Сколько значений указано в нём, столько столбцов будет содержать сетка разметки. Отдельные значения разделяются пробелами.

В качестве значений ширины можно использовать следующие величины:

  • Значения, заданные в любых поддерживаемых CSS единицах измерения размеров. Они задают фиксированные значения ширины столбцов в сетке разметки.

    -ms-grid-columns: 100px 20ex 3cm;


    Сетка разметки будет иметь три столбца; первый столбец получит ширину 100 пикселов, второй - 20 букв "x", третий - 3 сантиметра.

  • Значение auto. Оно указывает, что данный столбец будет иметь такую ширину, чтобы полностью вместить своё содержимое, и не более.

    -ms-grid-columns: 100px auto 3cm;


    Здесь второй столбец сетки разметки будет иметь такую ширину, чтобы полностью вместить своё содержимое. Остальные столбцы получат фиксированные значения ширины.

  • Значения вида <число>fr. Такое значение задаёт ширину столбца, равную доле от оставшегося пространства контейнера, которая указывается <числом>.

    -ms-grid-columns: 100px auto 3fr 1fr;


    Первый столбец сетки разметки получит фиксированную ширину в 100 пикселов, а второй - такую, чтобы полностью вместить своё содержимое. Оставшееся пространство в контейнере по ширине будет разделено на 4 (3+1) части; третий столбец получит ширину, равную 3 таким частям (3/4 от оставшегося пространства), а четвёртый - ширину, равную 1 части (1/4 оставшегося пространства).


Аналогично, для задания высоты строк сетки разметки используется атрибут стиля -ms-grid-rows. Он ведёт себя так же и поддерживает те же значения, что и атрибут стиля -ms-grid-columns.

#divGrid { -ms-grid-columns: auto 3fr 1fr;
                 -ms-grid-rows: 50px auto 50px; }


Формируем сетку разметки для нашей веб-странички (см. рис. 1 и 2).

2.3. Расстановка контейнеров в ячейках сетки разметки
Теперь мы можем создать отдельные контейнеры для различных фрагментов содержимого Web-страницы и расставить их в соответствующих ячейках сетки разметки.

Таких контейнеров будет у нас пять (см. рис. 1). Мы вложим их в контейнер divGrid.

<DIV ID="divGrid">
  <DIV ID="div1">Фрагмент 1</DIV>
  <DIV ID="div2">Фрагмент 2</DIV>
  <DIV ID="div3">Фрагмент 3</DIV>
  <DIV ID="div4">Фрагмент 4</DIV>
  <DIV ID="div5">Фрагмент 5</DIV>
</DIV>

>
</DIV>[/code]
Чтобы указать, в какой ячейке сетки разметки будет помещён контейнер, используются атрибуты стиля -ms-grid-column и -ms-grid-row. Они указываются для контейнеров, которые будут расставляться в ячейках сетки разметки.

Атрибут стиля ms-grid-column указывает номер столбца, а атрибут стиля -ms-grid-row - номер строки, на пересечении которых находится нужная ячейка. Номера задаются в виде целых чисел. Отметим также, что нумерация строк и столбцов сетки разметки начинается с единицы.

Значение атрибутов ms-grid-column и -ms-grid-row по умолчанию - 1. То есть, чтобы поместить какой-либо контейнер в ячейку первой строки или первого столбца, мы можем не указывать соответствующий атрибут стиля.

[code]#div1 { -ms-grid-row: 1;
-ms-grid-column: 1; }[/code]
Помещаем первый контейнер (он имеет имя div1) в ячейку, формируемую на пересечении первой строки и первого столбца сетки разметки.

Вообще-то, нам не обязательно задавать для контйнера div1 этот стиль. Вспомним, что говорилось чуть ранее: значение атрибутов ms-grid-column и -ms-grid-row по умолчанию - 1. Так что и без этого стиля контейнер div1 всё равно окажется в ячейке первой строки и первого столбца сетки разметки.

[code]#div2 { -ms-grid-row: 2;
-ms-grid-column: 1; }
#div3 { -ms-grid-row: 2;
-ms-grid-column: 2; }
#div4 { -ms-grid-row: 2;
-ms-grid-column: 3; }
#div5 { -ms-grid-row: 3;
-ms-grid-column: 2; }[/code]
Расставляем по ячейкам остальные контейнеры.

  • Второй контейнер (div2) - в ячейку, образованную пересечением второй строки и первого столбца сетки разметки.
  • Третий контейнер (div3) - в ячейку, образованную пересечением второй строки и второго столбца.
  • Четвёртый контейнер (div4) - в ячейку, образованную пересечением второй строки и третьего столбца.
  • Пятый контейнер (div5) - в ячейку, образованную пересечением третьей строки и второго столбца.


Чтобы контейнеры были ясно различимы, давайте зададим для них тонкую чёрную рамку.

[code]DIV { border: black solid thin; }[/code]
И уберём её у контейнера divGrid.

[code]#divGrid { border: none; }[/code]
Результат показан на рис. 3.


Рис. 3. Результат расстановки контейнеров в ячейках сетки разметки


Интересно, что нам совсем не обязательно заполнять все ячейки сетки разметки. Некоторые ячейки можно оставить пустыми (как, например, в нашем случае - см. рис. 3).

2.4. Размещение контейнеров сразу в нескольких ячейках сетки разметки
Да, показанное на рис. 3 сильно отличается от того, что мы планировали (см. рис. 1 и 2)...

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


Выходит, нам как-то нужно указать Web-обозревателю, что эти три контейнера должны занимать не по одной, а по нескольку ячеек. Но как?

С помощью атрибутов стиля -ms-grid-column-span и -ms-grid-row-span. Они также указываются для контейнеров, которые будут расставляться в ячейках сетки разметки.

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

Осталось только сказать, что значение атрибутов стиля -ms-grid-column-span и -ms-grid-row-span по умолчанию - 1. То есть, если мы не укажем какой-либо из этих атрибутов стиля, контейнер займёт только одну ячейку в соответствующем направлении (что мы и наблюдали ранее).

[code]#div1 { -ms-grid-column-span: 3; }[/code]
Размещаем первый контейнер (div1) сразу в трёх ячейках по горизонтали.

[code]#div2 { -ms-grid-row-span: 2; }
#div5 { -ms-grid-column-span: 2; }[/code]
Размещаем второй контейнер (div2) в двух ячейках по вертикали, а пятый (div5) - в трёх по горизонтали.

И посмотрим на результат - см. рис. 4. То, что мы и хотели получить!


Рис. 4. Результат этапа размещения контейнеров в нескольких ячейках сетки разметки


Для желающих получить всё и сразу - ниже приведён полный код окончательного варианта нашей веб-страницы.

[code]<!DOCTYPE html>
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
<TITLE>Сеточная разметка</TITLE>
<STYLE>
#divGrid { display: -ms-grid;
-ms-grid-rows: 50px auto 50px;
-ms-grid-columns: auto 3fr 1fr;
border: none; }
DIV { border: black solid thin; }
#div1 { -ms-grid-row: 1;
-ms-grid-column: 1;
-ms-grid-column-span: 3; }
#div2 { -ms-grid-row: 2;
-ms-grid-column: 1;
-ms-grid-row-span: 2; }
#div3 { -ms-grid-row: 2;
-ms-grid-column: 2; }
#div4 { -ms-grid-row: 2;
-ms-grid-column: 3; }
#div5 { -ms-grid-row: 3;
-ms-grid-column: 2;
-ms-grid-column-span: 2; }
</STYLE>
</HEAD>
<BODY>
<DIV ID="divGrid">
<DIV ID="div1">Фрагмент 1</DIV>
<DIV ID="div2">Фрагмент 2</DIV>
<DIV ID="div3">Фрагмент 3</DIV>
<DIV ID="div4">Фрагмент 4</DIV>
<DIV ID="div5">Фрагмент 5</DIV>
</DIV>
</BODY>
</HTML>[/code]
Отметим, что эта веб-страница должна быть сохранены в кодировке UTF-8. Эта кодировка рекомендуется для всех веб-страниц, создаваемых с использованием HTML5 и CSS3.


Дополнительные материалы


Окончание следует...


dronov_va, TheVista.Ru Team
Май 2011

Комментарии

Не в сети

Ок, будем знать, что вместо хорошего, быстрого, удобного и наиболее совместимого второго способа есть ещё и другие ;)
Хотя иногда доставляет наслаждение потратить несколько часов на гиморрой с третьим, вместо нескольких минут использования второго. Но отделить таки мух от контент, потому что "это правильно!".
Теперь будет четвёртый. Нечто среднее.

13.05.11 21:12
0
Не в сети

Четвёртый - IMHO, не среднее, а лучшее!

14.05.11 19:48
0
Не в сети

Да так и есть, всё правильно. Удобство таблиц, но при этом контент отделяем от представления. Просто побрюзжать немного захотелось. Убили ещё одну тему для холивара - табличные прагматики vs дивные идеалисты.

15.05.11 18:26
0
Для возможности комментировать войдите в 1 клик через

По теме

Акции MSFT
420.55 0.00
Акции торгуются с 17:30 до 00:00 по Москве
Все права принадлежат © ms insider @thevista.ru, 2022
Сайт является источником уникальной информации о семействе операционных систем Windows и других продуктах Microsoft. Перепечатка материалов возможна только с разрешения редакции.
Работает на WMS 2.34 (Страница создана за 0.053 секунд (Общее время SQL: 0.015 секунд - SQL запросов: 57 - Среднее время SQL: 0.00026 секунд))
Top.Mail.Ru