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

30.03.2011 13:28 | dronov_va

Генерируемое содержимое - очень интересная и полезная возможность, поддерживаемая всеми современными браузерами. Internet Explorer, к примеру, поддерживает её, начиная с версии 8. К сожалению, до сих пор она очень редко используется на практике. Эта статья призвана популяризовать её среди веб-дизайнеров.


1. Что такое генерируемое содержимое
Большую часть содержимого веб-страницы, которое должно на ней присутствовать, мы задаём сами - в её HTML-коде. Это всевозможный текст, изображения, горизонтальные линии, таблицы, аудио- и видеоролики, модули расширения браузера, элементы ActiveX, апплеты Java и мн. др. Web-обозреватель, прочитав HTML-код, выводит это содержимое на веб-страницу, ничего от себя не добавляя.

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

Да-да, это постарался браузер, пытаясь облегчить нашу работу. Он сам сгенерировал маркёры или нумерацию для пунктов списка и вывел их на веб-страницу. Таково его поведение по умолчанию для тегов <LI> (пунктов списка), вложенных в тег <UL> (маркированный список) или <OL> (нумерованный список).

Подобное содержимое веб-страницы, не задаваемое в её HTML-коде, а создаваемое браузером на основе заданных в нём правил и указанных нами стилей CSS, носит название генерируемого.

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

До выхода стандарта CSS2.1 ответ был прост - никак. Нам самим приходилось проставлять нумерацию заголовков и указывать соответствующие пометки в HTML-коде. Что, согласитесь, трудоёмко и чревато ошибками...

Но с появлением стандарта CSS2.1 и выходом поддерживающих его браузеров (в частности, версии 8 нашего любимого Internet Explorer) положение радикально изменилось. Теперь мы можем задавать для элементов веб-страницы генерируемое содержимое в виде произвольного текста и даже порядковой нумерации. Как это делается? Скоро узнаем.


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

Если страница написана с применением новой версии языка HTML - HTML5, мы должны явно указать это в её HTML-коде, вставим в самом его начале, перед открывающим тегом <HTML>, такой тег:

<!DOCTYPE html>


Однако такие веб-страницы будут правильно обработаны только самыми современными браузерами, поддерживающими HTML5, например, Internet Explorer 9.

Страницы, написанные на старой версии языка HTML - HTML4.01, будут нормально открываться во всех браузерах, что в данный момент присутствуют на рынке (за исключением совсем уж древних). Именно в этой версии языка HTML создаётся большая часть современных веб-страниц.

Но здесь есть один нюанс. Дело в том, что Internet Explorer 8 (это, как мы помним, первая версия Internet Explorer, в которой появилась поддержка генерируемого содержимого) по умолчанию выводит все веб-страницы в режиме совместимости с его предыдущими версиями. Генерируемое содержимое, как и все нововведения, появившиеся в CSS2.1, в этом режиме не поддерживается.

Поэтому нам придётся явно указать Internet Explorer 8, чтобы он вывел нашу веб-страницу в обычном режиме, когда поддерживаются все возможности CSS2.1. Для этого нам следует в самом начале HTML-кода, перед открывающим тегом <HTML>, поместить вот такой тег:

<META HTTP-EQUIV="X-UA-Compatible" CONTENT="IE=8">


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


3. Вывод обычных надписей
Проще всего создать генерируемое содержимое в виде обычной текстовой надписи, которая будет помещена перед или после содержимого какого-либо тега. Например, мы можем вывести таким образом надпись "Примечание" перед текстом определённых абзацев.

Для вывода обычных надписей в качестве генерируемого содержимого применяется атрибут стиля content. Формат его написания таков:

content: <текст надписи>

>[/code]
<Текст надписи> должен быть помещён в одинарные или двойные кавычки.

Но указать сам текст выводимой надписи - это ещё полдела. Нам ещё следует задать местоположение генерируемого содержимого относительно содержимого тега, в котором оно будет присутствовать.

Для указания местоположения применяются два псевдоэлемента, перечисленные ниже.

  • :before - вывести генерируемое содержимое перед содержимым тега.
  • :after - вывести генерируемое содержимое после содержимого тега.


Ниже представлен HTML-код веб-страницы с абзацем. Перед содержимым этого абзаца будет выведено генерируемое содержимое - надпись "Примечание: ".

[code]<META HTTP-EQUIV="X-UA-Compatible" CONTENT="IE=8">
<HTML>
<HEAD>
. . .
<TITLE>Генерируемое содержимое</TITLE>
<STYLE>
.remark:before { content: "Примечание: " }
. . .
</STYLE>
</HEAD>
<BODY>
. . .
<P CLASS="remark">Это текст примечания.</P>
. . .
</BODY>
</HTML>[/code]
Теперь рассмотрим несколько важных моментов, связанных с текстом надписей, которые выводятся в качестве генерируемого содержимого.

Мы можем поместить в текст надписи двойные кавычки. Проще всего использовать для этого последовательность символов \".

[code].remark:before { content: "Примечание к статье \"Генерируемое содержимое\": " }[/code]
Этот стиль укажет браузеру вывести перед текстом абзацев надпись "Примечание к статье "Генерируемое содержимое": ".

Если мы заключили текст надписи в одинарные кавычкы, то можем вставить в него двойные кавычки как есть:

[code].remark:before { content: 'Примечание к статье "Генерируемое содержимое": ' }[/code]
Если строка CSS-кода, описывающая генерируемое содержимое, слишком длинная, мы можем разбить её на несколько строк. При этом в местах разрыва следует поставить символы обратного слеша (\). Отметим, что само генерируемое содержимое будет выведено на веб-страницу без всяких разрывов, в одну строку.

[code].remark:before { content: 'Примечание к статье \
"Генерируемое содержимое": ' }[/code]
Здесь мы разорвали значение атрибута стиля content, указывающее генерируемое содержимое, на две строки. Обратим внимание, где мы поставили символ обратного слеша. При этом надпись "Примечание к статье "Генерируемое содержимое": " будет выведена на веб-страницу без разрывов.

Если же мы хотим вывести генерируемое содержимое на веб-страницу разорванным на несколько строк, то в тех местах, где его следует разорвать, вставим последовательности символов \A, а в самом стиле укажем атрибут стиля white-space со значением pre-wrap.

[code]<STYLE>
.remark:before { content: "Примечание:\A";
white-space: pre-wrap }
</STYLE>
. . .
<P CLASS="remark">Это текст примечания.</P>[/code]
Стиль, код которого указан выше, выведет на экран следующее:

[code]Примечание:
Текст примечания.[/code]
К сожалению, мы не можем использовать в качестве генерируемого содержимого HTML-код. Даже если мы поместим в текст надписи какой-либо тег HTML, он будет выведен браузером как есть. Вероятно, это было сделано в целях безопасности.


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

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

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

Счётчик создаётся с помощью атрибута тега counter-increment. Вот формат его записи:

[code]counter-increment: <имя счётчика>[ <значение инкремента счётчика>][/code]
<Имя счётчика> указывается без кавычек и должно быть уникальным в пределах данной веб-cтраницы. Оно будет использовано в значении атрибута стиля content, указывающем само генерируемое содержимое (подробнее об этом мы поговорим потом).

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

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

<Значение инкремента счётчика> должно быть целым числом; допускаются как положительные, так и отрицательные значения. Если оно не указано, значение счётчика будет каждый раз увеличиваться на 1.

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

[code]H1 { counter-increment: header1 }[/code]
Здесь мы создаём счётчик с именем header1 для заголовков первого уровня. После этого заголовки первого уровня будут иметь номера 1, 2, 3 и т. д.

[code]H1 { counter-increment: header1 2 }[/code]
А здесь мы создаём такой же счётчик, но указываем ему в качестве значения инкремента 2. Таким образом, заголовки первого уровня будут иметь номера 2, 4, 6 и т. д.

Мы можем указать в значении атрибута тега counter-increment сразу несколько счётчиков, разделив их определения пробелами.

[code]H1 { counter-increment: header1 header2 }[/code]
Здесь мы создали для заголовков первого уровня сразу два счётчика - header1 и header2.

[code]H1 { counter-increment: header1 header2 2 }[/code]
А здесь мы дополнительно указали для счётчика header2 величину инкремента - 2.

4.2. Вывод нумерации
Итак, счётчики мы создали. Теперь нужно как-то вывести их значения на веб-страницу, создав тем самым нумерацию.

Для этого применяется уже знакомый нам по параграфу 3 атрибут стиля content. Имя счётчика, значение которого следует вывести в составе генерируемого содержимого, указывается в его значении в следующем формате:

[code]counter(<имя счётчика>[, <тип нумерации>])[/code]
Счётчик, <имя> которого мы укажем здесь, уже должен быть создан.

Дополнительно мы можем указать <тип нумерации>. Его доступные значения перечислены ниже.

  • decimal - арабские цифры.
  • decimal-leading-zero - арабские цифры с начальным нулём.
  • lower-alpha и lower-latin - строчные (маленькие) латинские буквы.
  • upper-alpha и upper-latin - прописные (большие) латинские буквы.
  • lower-roman - маленькие римские цифры: i, ii, iii, vi и т. д.
  • upper-roman - большие римские цифры: I, II, III. VI и т. д.
  • lower-greek - строчные греческие буквы.
  • armenian - прописные армянские буквы.
  • georgian - строчные грузинские буквы.


Если <тип нумерации> не указан, выполняется нумерация арабскими цифрами (как если бы был указан тип decimal).

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

[code]H1:before { content: counter(header1) }[/code]
Этот стиль выводит текущее значение созданного ранее счётчика header1 (то есть сам порядковый номер) перед текстом каждого заголовка первого уровня.

[code]H1:before { content: counter(header1, upper-roman) }[/code]
А здесь мы дополнительно указали, чтобы браузер выполнял нумерацию большими римскими цифрами.

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

[code]H1:before { content: counter(header1) ". " }[/code]
Здесь мы указали браузеру выводить в начале каждого заголовка первого уровня текущее значение счётчика header1 и строку, содержащую точку и пробел. Так мы визуально отделим сам номер от текста заголовка.

[code]H1:before {content: counter(header1, upper-roman) "." counter(header2) " " }[/code]
А здесь мы выводим значение счётчика header1, причём большими римскими цифрами, точку, значение счётчика header2 и пробел.

[code]H1:after { " (" content: counter(header1) ")" }[/code]
А здесь мы выводим номера заголовков первого уровня после самого их текста в скобках.

4.3. Сброс счётчика. Создание многоуровневой нумерации
Предположим, мы собираемся опубликовать в Интернете большую статью, разделённую на главы, подглавы и параграфы. Главы мы озаглавим заголовками первого уровня, подглавы - заголовками второго уровня, а параграфы - заголовками третьего уровня.

Для всего этого мы применим многоуровневую нумерацию. Вот такую:

[code]1. Глава
1.1. Подглава
1.1.1. Параграф
1.1.2. Параграф
1.2. Подглава
1.2.1. Параграф
1.2.2. Параграф
2. Глава
2.1. Подглава
2.1.1. Параграф
2.1.2. Параграф
2.2. Подглава
2.2.1. Параграф
2.2.2. Параграф[/code]
Как видим, подглавы внутри главы имеют свою собственную нумерацию, как и параграфы внутри подглавы.

Чтобы реализовать такую нумерацию, мы создадим следующие стили:

[code]H1 { counter-increment: header1 }
H2 { counter-increment: header2 }
H3 { counter-increment: header3 }
H1:before {content: counter(header1) ". " }
H2:before {content: counter(header1) "." counter(header2) ". " }
H3:before {content: counter(header1) "." counter(header2) "." counter(header3) ". " }[/code]
И что получим в результате?

Первая глава получит номер 1, первая подглава этой главы - номер 1.1, первый и второй параграфы этой подглавы - 1.1.1 и 1.1.2 соответственно. Пока всё нормально.

Далее, вторая подглава первой главы получит номер 1.2. Пока тоже всё нормально.

Но дальше начинаются проблемы. Нам нужно, чтобы первый параграф второй подглавы получил номер 1.2.1. Но он получит номер 1.2.3. Далее мы столкнёмся с тем, что первая подглава второй главы получит номер 2.3 вместо необходимого нам 2.1, а первый параграф первой подглавы второй главы - номер 2.3.5 вместо необходимого 2.1.1.

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

Вот как бы сделать так, чтобы при достижении определённого элемента веб-страницы значение счётчика сбрасывалось в ноль?.. Применительно к нашему случаю - чтобы при достижении заголовка второго уровня (подглавы) сбрасывался бы счётчик header3 (нумерация параграфов), а при достижении заголовка первого уровня (главы) сбрасывались бы счётчики header2 (нумерация подглав) и header3. Тогда бы подглавы внутри главы и параграфы внутри подглавы нумеровались бы отдельно, и мы получили бы нужную нам нумерацию.

Такой способ есть! Специально для таких случаев предназначен атрибут стиля counter-reset. Он как раз и указывает, какой счётчик следует сбросить при достижении данного элемента веб-страницы, и, возможно, указать для него изначальное значение, которое он получит в результате сброса.

Формат записи атрибута counter-reset таков:

[code]counter-reset: <имя счётчика>[ <изначальное значение счётчика>][/code]
Счётчик, <имя> которого мы укажем здесь, уже должен быть создан.

<Изначальное значение счётчика> указывает значение, которое счётчик получит в результате сброса. Если мы его не укажем, счётчик получит значение 0.

[code]H2 { counter-reset: header3 }[/code]
Здесь мы указали браузеру, чтобы он каждый раз при достижении заголовка второго уровня сбрасывал счётчик header3. Поскольку мы не указали для него изначального значения, данный счётчик в результате сброса получит значение 0.

[code]H2 { counter-reset: header3 20 }[/code]
А здесь мы указали для счётчика header3 изначальное значение, равное 20.

Мы можем указать в значении атрибута тега counter-reset сразу несколько счётчиков, разделив их определения пробелами.

[code]H1 { counter-reset: header2 header3 }[/code]
Здесь мы указали браузеру, чтобы он каждый раз при достижении заголовка первого уровня сбрасывал счётчики header 2 и header3.

[code]H1 { counter-reset: header2 header3 20 }[/code]
А здесь мы дополнительно указали для счётчика header3 изначальное значение, равное 20.

Теперь давайте исправим приведённый ранее CSS-код стилей, чтобы они создали нужную нам многоуровневую нумерацию.

[code]BODY { counter-reset: header1 }
H1 { counter-increment: header1;
counter-reset header2 header3 }
H2 { counter-increment: header2;
counter-reset: header3 }
H3 { counter-increment: header3 }
H1:before {content: counter(header1) ". " }
H2:before {content: counter(header1) "." counter(header2) ". " }
H3:before {content: counter(header1) "." counter(header2) "." counter(header3) ". " }[/code]
Здесь мы дополнительно добавили стиль переопределения тега <BODY>, в котором указали, чтобы браузер при достижении этого тега (фактически - сразу при открытии веб-страницы) сбрасывал счётчик header1 (нумерация глав). В принципе, это необязательно, поскольку является перестраховкой, но в любом случае лучше перестраховаться...


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



dronov_va, TheVista.Ru Team
Март 2011

Комментарии

Не в сети

Ммм... интересно!

30.03.11 15:44
0
Не в сети

2 Sm1le: Ещё бы не интересно!.. И ведь мало где применяется...

31.03.11 08:56
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.03 секунд - SQL запросов: 55 - Среднее время SQL: 0.00055 секунд))
Top.Mail.Ru