Лекция № 7. Дизайн веб-страницы 1. Блочные и строчные элементы 1.1. Блочные элементы Все элементы языка HTML можно разделить на две группы – блочные элементы и строчные элементы. Блочные элементы представляют собой прямоугольную область, которая делится на несколько частей – содержимое, отступы (paddings), граница и поля (margins). Блочные элементы всегда начинаются с новой строки. Содержимое блочного элемента может включать в себя строчные элементы, а также другие блочные элементы, хотя и с некоторыми ограничениями. «Высокоуровневые» блочные элементы, такие как section, article, div, могут включать другие такие же элементы, абзацы, списки, блочные цитаты. Списки тоже могут быть вложенными. А вот вложить один абзац в другой невозможно. Поэтому появление нового абзаца закрывает предыдущий абзац, даже если закрывающий тег отсутствует. Также абзац закрывается появлением списка или блочной цитаты (которая, по сути, также является разновидностью абзаца). Если после этого вы вставите закрывающий тег абзаца, это будет ошибкой. Таким образом, абзац, а также заголовки h1-h6, являются самыми «низкоуровневыми» блочными элементами, т.к. они не могут содержать другие блочные элементы. Отступ – это промежуток между содержимым элемента и его границей. Поля – это промежуток между границей элемента и содержимым родительского элемента. Разница также заключается в том, что отступ имеет такой цвет фона, как и содержимое, а поля элемента имеют цвет фона, совпадающий с цветом фона родительского элемента. Свойство width, которое можно задать для блочного элемента, определяет ширину именно содержимого элемента. Но элемент может также иметь отступы, границу и поля. Таким образом, место, занимаемое элементом, больше, чем собственно ширина, общая ширина элемента складывается из ширины содержимого, ширины отступов слева и справа (они могут иметь разную ширину), ширины двух линий границы и ширины левого и правого полей (которые тоже могут иметь разную ширину). Высота определяется аналогично. В обычном случае автор веб-страницы не задаёт ни ширину, ни высоту содержимого элементов. В этом случае общая ширина принимается равной ширине окна браузера, и ширина содержимого определяется как общая ширина минус ширина полей, границы и отступов. Высота элемента определяется браузером таким образом, чтобы можно было разместить всё содержимое элемента. По умолчанию блочные элементы, которые в HTML-файле расположены последовательно, также последовательно, один под другим, располагаются на веб-странице. Даже если ширины окна будет хватать для размещения двух блочных элементов, они всё равно не будут располагаться рядом друг с другом. Однако есть способы заставить браузер сделать исключение для того или иного элемента. 1.2. Строчные элементы Строчные элементы, по сути, представляют собой часть строки. Они размещаются последовательно слева направо до тех пор, пока ширины родительского блочного элемента хватает для размещения очередного строчного элемента. После этого происходит переход на следующую строку. Блочные элементы, как мы говорили, могут включать как другие блочные элементы (за некоторым исключением), так и строчные элементы. А вот строчные элементы ни в коем случае не могут включать блочные элементы, но могут включать другие строчные элементы. Для строчных элементов также можно задавать отступы, границы и поля, но результат установки этих параметров для строчного элемента будет не таким, как для блочного элемента. Отступы, границы и поля слева и справа будут увеличивать ширину элемента, а вот отступы, границы и поля сверху и снизу на высоту элемента и, следовательно, на высоту строки, никак не повлияют, а будут лишь перекрывать часть содержимого родительского элемента. Исключение составляет элемент img. Он считается строчным элементом, но высота строки подгоняется под его высоту с учётом отступов, границ и полей. 35 1.3. Прозрачный элемент a Из элементов, рассмотренных нами на предыдущей лекции, к блочным относятся элементы body, p, h1-h6, hr, li, ol, ul, div, section, article, nav, aside, header, footer, address, pre, blockquote. К строчным относятся элементы img, br, i, b, em, strong, sup, sub, span, q, abbr. Слова обычного текста также являются строчными элементами, несмотря на отсутствие какой-либо специальной разметки. Элемент html можно условно отнести к блочным, но надо понимать, что это корневой элемент всей веб-страницы, и их не может быть два и более, поэтому бессмысленно говорить об их размещении друг под другом. Но при желании для элемента html можно задать отступы, границы и поля. Элементы head, title, link, meta, style представляют собой исключение – эти элементы не отображаются в теле веб-страницы, а задают метаданные страницы. Ещё одним интересным исключением является элемент a. Он, несомненно, отображается в теле веб-страницы, но является прозрачным элементом. Смысл в том, что элемент a может встречаться внутри строчных и внутри блочных элементов, и может содержать как строчные, так и блочные элементы. Поэтому в зависимости от ситуации элемент a может быть отнесён браузером как к строчным, так и к блочным элементам, и будет отображаться соответствующим образом. Если элемент a содержит строчные элементы, то сам он тоже будет строчным. Если же элемент a содержит блочные элементы, он также будет блочным элементом. 2. Позиционирование 2.1. Обычное позиционирование Как уже было сказано, блочные элементы одного уровня располагаются на веб-странице последовательно, также как и в HTML-файле. Ширина элемента может быть задана как в абсолютных, так и в относительных величинах (в процентах). По умолчанию ширина элемента принимается равной 100%, т.е. содержимое элемента занимает всё доступное пространство с учётом ширины отступов, границ и полей. Если один блочный элемент вложен в другой блочный элемент, то ширина вложенного элемента рассчитывается относительно ширины родительского элемента. Элемент body является родительским элементом для всех других блочных элементов. Его ширина равна ширине окна браузера. Высота элемента по умолчанию задаётся таким образом, чтобы её было достаточно для размещения всего содержимого. Поля двух соседних блочных элементов соединяются в одно. Высота полученного поля равняется высоте большего из двух полей. Если автор задаёт высоту элемента, недостаточную для содержимого, то содержимое может отображаться браузером за пределами элемента. Однако следующий элемент не будет перекрывать содержимое предыдущего элемента. Кроме того, с помощью таблиц стилей можно обрезать содержимое элемента и добавить к элементу полосы прокрутки. 2.2. Плавающие элементы Что делать, если мы всё-таки захотим разместить один блочный элемент рядом с другим? Для этого существует так называемое плавающее размещение элементов. Для этого для элемента необходимо установить стиль float: left или float: right. Кроме того, плавающие элементы должны иметь фиксированную ширину. При размещении такого элемента браузер будет выполнять следующие действия: 1. сначала браузер размещает на страницы элементы, расположенные в HTML-файле до плавающего, в обычном порядке сверху вниз; 2. когда браузер встречает плавающий элемент, он размещает этот элемент слева или справа и исключает его из общего потока, в результате элемент «плавает» на странице; 3. поскольку плавающий элемент был исключён из общего потока, то остальные блочные элементы размещаются на странице так, будто этого элемента вовсе нет; 4. когда размещаются строчные элементы, учитываются границы плавающего элемента, поэтому строчные элементы обтекают его. Если необходимо, чтобы какой-либо блочный элемент не оказывался под плавающим элементом, то для него необходимо задать свойство clear. Это свойство может иметь одно из трёх 36 значений: left, right или both. Значение left устанавливает, что на элемент не должен накладываться плавающий элемент слева, значение right – что на элемент не должен накладываться плавающий элемент справа, значение both – что на элемент не должны накладываться плавающие элементы ни слева, ни справа. 2.3. Абсолютное позиционирование Ещё один способ нестандартного размещения элементов – абсолютное позиционирование. Абсолютное позиционирование задаётся с помощью значения absolute свойства position. Абсолютно позиционированный элемент, также как и плавающий, должен иметь фиксированную ширину, а его позиция задаётся свойствами top/bottom и left/right. Такой элемент, также как и плавающий, исключается из общего потока и накладывается на другие элементы. При этом строчное содержимое элементов не обтекает абсолютно позиционированный элемент. Такие элементы всегда накладываются на обычные элементы, независимо от порядка размещения элементов в HTML-файле. Несколько абсолютно позиционированных элементов могут накладываться друг на друга. При этом сверху будет располагаться элемент, который в HTML-файле расположен позже. Однако этот порядок можно изменить с помощью свойства z-index. Если же один абсолютно позиционированный элемент находится внутри другого абсолютно позиционированного элемента, то, во-первых, позиция дочернего элемента будет отсчитываться относительно позиции родительского элемента, а во-вторых, дочерний элемент будет расположен над родительским, независимо от значения свойства z-index. 2.4. Относительное позиционирование Элемент, позиционированный относительно, является частью общего потока вебстраницы, но в последний момент перед тем, как отобразить этот элемент, браузер смещает его. Относительное позиционирование задаётся с помощью значения relative свойства position. Смещение задаётся свойствами top/bottom и left/right. 2.5. Фиксированное позиционирование Все предыдущие способы позиционирования предполагали, что после размещения элемента на странице он будет перемещаться вверх и вниз при использовании прокрутки. При фиксированном позиционировании, также как и при абсолютном, свойствами top/bottom и left/right задаётся позиция элемента, но она вычисляется не относительно веб-страницы, а относительно окна браузера. При этом элемент всегда остаётся там, куда его поместили, и не перемещается даже тогда, когда используется прокрутка страницы. Фиксированное позиционирование задаётся с помощью значения fixed свойства position. 3. Дизайн веб-страницы Если всё содержимое веб-страницы размещается в одной колонке, то в HTML-файле необходимо просто расположить все элементы в нужном порядке. Если же веб-страница должна содержать две или более колонки, то возможны различные варианты дизайна веб-страницы. Рассмотрим варианты дизайна следующей страницы. <!doctype html> <html lang = "ru-RU"> <head> <meta http-equiv = "Content-Type" content = "text/html; charset=windows-1251"> <title> Конспект лекций по С &amp; C++ </title> </head> <body> <header> <p> C &amp; C++ </header> <nav> <p> <a <p> <a <p> <a <p> <a <p> <a <p> <a <p> <a </nav> href href href href href href href = = = = = = = "index.php?sezione=lezioni"> Лекции </a> "index.php?sezione=compiti"> Задания </a> "index.php?sezione=letture"> Литература </a> "index.php?sezione=materie"> Предметный указатель </a> "index.php?sezione=calcolo16"> Типовой расчёт (А-16) </a> "index.php?sezione=calcolo13"> Курсовой проект (А-13) </a> "domande.php"> Контрольные вопросы </a> 37 <section> <p> <a href <p> <a href <p> <a href <p> <a href <p> <a href <p> <a href <p> <a href <p> <a href <p> <a href <p> <a href <p> <a href <p> <a href <p> <a href <p> <a href <p> <a href <p> <a href <p> <a href <p> <a href </section> = = = = = = = = = = = = = = = = = = "lezione1.html">Алфавит и основные понятия языка С++ </a> "lezione2.html">Операторы языка С++. Структура программы </a> "lezione3.html">Одномерные и двумерные массивы и их обработка </a> "lezione4.html">Ввод/вывод </a> "lezione5.html">Указатели и ссылки. Работа со строками </a> "lezione6.html">Перечислимый тип. Структуры. Объединения </a> "lezione7.html">Динамическое распределение памяти. Списки </a> "lezione8.html">Поразрядные операции </a> "lezione9.html">Время жизни и область видимости. Пространства имён. Компоновка </a> "lezione10.html">Понятие класса </a> "lezione11.html">Специальные функции-члены класса </a> "lezione12.html">Перегрузка операций </a> "lezione13.html">Статические члены класса. Друзья класса </a> "lezione14.html">Обработка исключительных ситуаций </a> "lezione15.html">Шаблоны </a> "lezione16.html">Наследование </a> "lezione17.html">Виртуальные функции. Абстрактные классы </a> "lezione18.html">Множественное наследование </a> <footer> <p> Данный конспект лекций предназначен для всех студентов, желающих освоить программирование на языке С++. <p><b>Автор:</b> доцент кафедры Прикладной математики МЭИ(ТУ) Чибизова Наталья Владимировна. </footer> </body> </html> 3.1. Дизайн с непостоянной шириной Прежде всего, можно использовать плавающие элементы. Зададим свойство float для элемента nav. <nav style = "width: 160pt; float: left; padding: 20pt"> Однако если элемент section будет иметь большую высоту, чем элемент nav, то содержимое элемента section будет расположено справа и снизу от элемента nav. Если же мы хотим, чтобы содержимое элемента section не было расположено под элементом nav, можно использовать такой приём – задать левое поле для элемента section, равное ширине плавающего элемента (не забываем, что ширина элемента состоит из ширины содержимого, полей, границ и отступов). <section style = "margin-left: 205pt"> Теперь позаботимся о том, чтобы нижний колонтитул страницы в любом случае был расположен ниже элемента nav. Для того чтобы плавающий элемент не заходил на элемент footer, для него нужно задать свойство clear. <footer style = "clear: both"> 3.2. Использование абсолютного позиционирования В принципе, аналогичных результатов можно добиться с использованием абсолютного позиционирования – также задать левое поле для элемента section, а элемент nav разместить в нужном месте. <nav style = "width: 160pt; position: absolute; top: 70pt; padding: 20pt"> <section style = "margin-left: 205pt"> Но в этом случае возникают проблемы с позиционированием элемента footer. Если оставить для элемента footer стандартное позиционирование, то элемент footer будет располагаться под элементом section и если этот элемент имеет высоту меньшую, чем высота элемента nav, элемент nav будет перекрывать элемент footer. Если же использовать для элемента footer абсолютное позиционирование, то он будет перекрывать элемент section при увеличении высоты последнего. 3.3. Дизайн с фиксированной шириной Если мы захотим, чтобы страница содержала две колонки фиксированной ширины, то это, конечно, сделать несложно, но возникают другие проблемы. Можно сделать плавающей только одну колонку, а для другой просто задать фиксированную ширину. 38 <nav style = "width: 160pt; float: left; padding: 20pt"> <section style = "width: 580pt; margin-left: 205pt"> <footer style = "clear: both"> Однако если ширина окна браузера недостаточна, то часть содержимого будет невидна, а если ширина окна браузера больше ширины двух элементов, то справа будет оставаться свободное место. Можно сделать плавающими оба элемента. <nav style = "width: 160pt; float: left; padding: 20pt"> <section style = "width: 580pt; float: right"> <footer style = "clear: both"> Однако теперь при большой ширине окна свободное пространство будет оставаться между элементами. 3.4. Гибкая разметка Однако есть способ улучшить дизайн страниц с фиксированной шириной. Для этого придётся ввести ещё один элемент, объединяющий элементы nav и section. После этого для него задаётся фиксированная ширина и для левого и правого полей задаётся значение auto. Это заставляет браузер задавать одинаковое значение для левого и правого полей и центрировать содержимое страницы. <section style = "width: 705pt; margin-left: auto; margin-right: auto"> <nav style = "width: 160pt; float: left; padding: 20pt"> <p> <a href = "index.php?sezione=lezioni"> Лекции </a> ... <p> <a href = "domande.php"> Контрольные вопросы </a> </nav> <section style = "width: 500pt; margin-left: 205pt"> <p> <a href = "lezione1.html">Алфавит и основные понятия языка С++ </a> ... <p> <a href = "lezione18.html">Множественное наследование </a> </section> <footer style = "clear: both"> <p> Данный конспект лекций предназначен для всех студентов, желающих освоить программирование на языке С++. <p><b>Автор:</b> доцент кафедры Прикладной математики МЭИ(ТУ) Чибизова Наталья Владимировна. </footer> </section> Данный вариант не решает проблему с недостаточной шириной окна браузера, однако такая страница выглядит лучше, чем страницы, созданные в предыдущем разделе. 4. Таблицы Представление данных в табличной форме используется во многих документах. Вебстраницы не представляют исключения. Для создания таблиц существуют специальные элементы. Элемент table представляет таблицу. Элемент caption представляет заголовок таблицы. Элемент colgroup представляет группу столбцов. Элемент thead представляет группу строк, являющуюся заголовком таблицы. Элемент tbody представляет группу строк. Таблица может содержать более одного элемента tbody. Элемент tr представляет строку таблицы. Элемент td представляет ячейку таблицы. Элемент th представляет ячейку заголовка таблицы. Таким образом, таблица состоит из необязательного элемента caption, одного или нескольких необязательных элементов colgroup, необязательного элемента thead и элемента tbody. Элементы thead и tbody состоят из одного или нескольких элементов tr, а те в свою очередь – из одного или нескольких элементов th или td. Приведём пример простейшей таблицы. <table> <tr> 39 <td> <td> </tr> <tr> <td> <td> </tr> <tr> <td> <td> </tr> </table> 1 </td> 2 </td> 3 </td> 4 </td> 5 </td> 6 </td> В данном случае таблица состоит из одного элемента tbody, для которого опущены как открывающий, так и закрывающий теги. Закрывающие теги элементов tr, th и td также могут быть опущены. Приведём примеры более сложных таблиц. <table> <thead> <tr> <th> </thead> <tbody> <tr> <td> <tr> <td> </tbody> <tbody> <tr> <td> <tr> <td> </tbody> </table> 1 <th> 2 3 <td> 4 5 <td> 6 7 <td> 8 9 <td> 0 <table> <caption> Название таблицы <colgroup span = 3> <colgroup span = 3> <colgroup span = 3> <tbody> <tr> <td> 1 <td> <td> 3 <tr> <td> <td> 2 <td> <tr> <td> 7 <td> <td> <tbody> <tr> <td> 2 <td> <td> 4 <tr> <td> <td> <td> <tr> <td> 5 <td> <td> <tbody> <tr> <td> 6 <td> <td> <tr> <td> <td> <td> <tr> <td> 9 <td> <td> </table> </caption> <td> 6 <td> <td> 4 <td> 7 <td> <td> 9 <td> <td> 9 <td> <td> <td> 1 <td> <td> <td> <td> <td> <td> <td> 6 <td> <td> 3 <td> <td> 9 <td> <td> <td> <td> <td> <td> <td> 9 <td> <td> 7 <td> <td> <td> 8 <td> <td> 1 <td> <td> 5 <td> <td> <td> <td> 7 <td> <td> <td> 8 <td> <td> 2 <td> <td> 2 <td> <td> 5 <td> <td> <td> <table> <tr> <th> 1 <td> 2 <td> 3 <tr> <th> 4 <td> 5 <td> 6 <tr> <th> 7 <td> 8 <td> 9 </table> Элементы th не обязательно должны входить в элемент thead. Как видно из последнего примера можно в качестве заголовка использовать первый столбец таблицы. Собственно между элементами th и td нет принципиальной разницы. Два отдельных элемента, также как и возможность деления таблицы на группы строк (с помощью элементов tbody) и группы столбцов (с помощью элементов colgroup) введены для удобства форматирования таблицы. Элементы th и td могут иметь атрибуты rowspan и colspan, которые позволяют объединять ячейки, находящиеся в разных строках и столбцах. Значение этих атрибутов представляет собой положительное целое число, указывающее, сколько строк или столбцов надо объединить. <table> <tr> <td> 1 <td> 2 <td rowspan = 2> 3 <td> 4 <td> 5 <tr> <td> 6 <td> 7 <td> 8 <td> 9 <tr> <td> 10 <td colspan = 3> 11 <td> 12 </table> 40