Элементы HTML страницы обычно делятся на блочные и строчные.
- Блочные элементы можно представлять как прямоугольные области на странице. Они имеют следующие особенности:
- До и после блочного элемента существует перенос строки.
- Блочным элементам можно задавать ширину, высоту, внутренние и внешние отступы.
- Занимают всё доступное пространство по горизонтали.
К блочным элементам относятся такие теги как: p, h1, h2, ul, div – (просто «блок» или «прямоугольный контейнер») и так далее.
- Строчные элементы располагаются друг за другом в одной строке, при необходимости строка переносится. Особенности строчных элементов:
- До и после строчного элемента отсутствуют переносы строки.
- Ширина и высота строчного элемента зависит только от его содержания, задать размеры с помощью CSS нельзя.
- Можно задавать только горизонтальные отступы.
К строчным элементам относятся такие теги как: a, strong, em, span и так далее.
Строчные элементы предназначены для оформления текста на уровне небольших фраз и отдельных слов. Блочные же элементы предназначены для разметки крупных блоков текста (заголовки, абзацы, списки) и создания сетки.
Ширина и высота элементов задаются с помощью свойств width и height соответственно. По умолчанию блочные элементы занимают всю доступную ширину, которая равна ширине родительского контейнера или окна браузера.Высота по умолчанию блочных элементов зависит от их содержимого. Если задать блочному элементу ширину и высоту так, что содержимое элемента не будет в него помещаться, то оно как бы «выпадет» из него. Строчные элементы не реагируют на задание ширины и высоты в CSS.
Свойство padding задает внутренние отступы элемента — отступы от внешней границы элемента до его содержания. Эти отступы еще иногда называют полями. Также можно задавать отступы для разных сторон с помощью свойств padding-left, padding-right, padding-top, padding-bottom. Для строчных элементов лучше не задавать вертикальных отступов, т.к. они ведут себя непредсказуемо. Например: padding: 5px 10px 15px; – задает отступ сверху 5px, слева и справа 10px, снизу 15px.
Свойство margin задает внешние отступы элемента — отступы от внешней границы элемента до границ родительского элемента или до соседних элементов. Можно задавать отступы для разных сторон с помощью свойств margin-left, margin-right, margin-top, margin-bottom. Строчные элементы реагируют только на горизонтальные отступы. Например: margin: 5px 10px 15px; – задает отступ сверху 5px, слева и справа 10px, снизу 15px.
Рамка задаётся с помощью свойства border, которое состоит из трёх компонентов: ширина рамки, стиль рамки и цвет. Задавать рамку можно одним свойством border, а можно и с помощью отдельных свойств border-width, border-style, border-color. Рамку можно задавать и строчным, и блочным элементам. (самые частые стили рамки: solid — сплошная, dashed — пунктирная dotted — точками). div{ border: 5px solid red; } – задает красную сплошную рамку, толщиной 5 пикселей, вокруг блока.
Область, занимаемая блочным элементом, складывается из его ширины и высоты содержания, внутренних и внешних отступов, ширины рамок.
- ширина/высота содержания — свойства width и height (синий прямоугольник на схеме);
- внутренние отступы — свойство padding;
- рамки — свойство border;
- внешние отступы — свойство margin.
Для внешних отступов имеется ряд эффектов. Вертикальный отступ между двумя соседними элементами равен максимальному отступу между ними и называется эффектом «схлопывания» внешних отступов (но только для вертикальных отступов), а горизонтальные отступы между элементами просто складываются. Если отступ одного элемента равен 20px, а второго 40px, то отступ между ними будет 40px, а если горизонтальный отступ между двумя элементами с отступами 45px будет равен 90px. Кроме того, если внутренний блок имеет внешние отступы, то эти отступы влияют не на внутренний блок, а на родительский, то есть если внутри родительского блока расположить блок и задать ему отступ сверху, то внутренний блок прижмется к верхнему краю родительского, а у родительского элемента появится отступ сверху, получается эффект «выпадения» отступа внутреннего элемента за пределы родительского. Если у родительского элемента тоже был задан внешний отступ, то выберется максимальный отступ между собственным и «выпавшим». Однако эффект “выпадания” – случается только если родительский блок не имеет рамки или установленных внутренних отступов, если же есть то отступ будет уже внутри родительского блока. Чтобы избавиться от эффекта выпадания, можно задать родительскому элементу внутренний отступ (паддинг) сверху или добавить рамку сверху. Из данного правила есть исключения,а именно схлопывание не работает в следующих случаях:
- с «плавающими» блоками, которые используют свойство float;
- с корневыми элементами(html, body);
- с абсолютно позиционируемыми элементами, имеющих свойство и значение position:absolute;
- в строчных элементах.
- Если элементы имеют значение свойства overflow, отличимое от visible, то в таких элементах не схлопываются отступы с отступами их наследников.
- Элементы со свойством cleared не схлопываются верхними отступами с нижними отступами их родителей.
Внешние и внутренние отступы всегда складываются.
Разместить блочный элемент по центру родительского, можно выполнив следующее действие: задать элементу ширину (при этом ширина блока должна быть меньше ширины родительского) и задать значение внешних отступов справа и слева в значение auto. Пример: .inner { width: 100px; margin: 0 auto; }
Ширина блока заданная через свойство width задает не общую ширину, а лишь ширину содержимого блока, а законченная ширина элемента вычисляется с учетом внутренних отступов и размеров рамок.При этом есть несколько особенностей влияющих на поведение блока: Если ширина не задана или задана значением auto, то тогда блок занимает всю ширину родителя, а отступы и рамки уменьшать ширину содержимого блока (так, что бы он вписался в родителя), если значение ширины 100% – то содержимое блока занимает всю ширину родительского блока, а внутренние отступы и рамки делают блок больше ширины родителя. Однако такое поведение создает некоторые проблемы при создании “резинового” дизайна (который растягивается), если необходим блок который должен занимать все ширину родителя но при этом иметь фиксированные внутренние отступы. И простой вариант с заданием 100% ширины и отступов сделает блок шире своего родителя. Решением данной проблемы будет применение свойства box-sizing (только CSS3) которое меняет алгоритм расчета общей ширины и имеет два значения: content-box – значение по умолчанию, указывающие на то, что свойство width задает ширину только содержимого; значение border-box – указывающие на то, что свойство width задает общую ширину всего блока. Например: input[type="text"] { box-sizing: border-box; width: 100%; padding: 5px 10px; color: #666666; border: 2px solid #cccccc; border-radius: 5px;}
Особенности поведения строчных элементов
- Не реагируют на CSS-свойства width и height
- Внешние границы margin – влияют только на горизонтальные отступы, а все вертикальные игнорируются
- Внутренние границы padding – влияют только на горизонтальные отступы, а все вертикальные визуально увеличивают размер по вертикале, но без увеличения занимаемого места (то есть не отталкиваю другие элементы)
- Границы (рамки) border – влияют только на горизонтальные отступы, а все вертикальные визуально увеличивают размер по вертикале, но без увеличения занимаемого места (то есть не отталкиваю другие элементы), по аналогии с внутренними границами
Свойство display
Данное свойство меняет поведение элемента в плане соответствия блочной модели и способно сделать из строчный элементов блочные и наоборот.
Значения свойства display:
Значение | Описание |
none | Временно удаляет элемент из документа. Занимаемое им место не резервируется и веб-страница формируется так, словно элемента и не было.Есть еще одно CSS-свойство, которое используется для сокрытия элементов. Это свойство visibility со значением hidden. Оно «прячет» элемент — он становится невидимым, но занимает место на странице.
Данное свойство применяется при создании выпадающих меню, динамических галерей, переключающихся вкладок и много где еще. |
block | Элемент будет генерировать блок (перенос строки до и после элемента), а также реагировать на размеры, рамки и отступы, как и подобает блочным элементам; |
inline | Элемент будет генерировать инлайновый блок (нет переноса строки до и после элемента). Значение по умолчанию. |
inherit | Значение должно быть унаследовано от элемента родителя |
inline-block | “Блочно-строчный”. Блочный элемент, который обтекается другими элементами веб-страницы подобно встроенному элементу. Фактически такой элемент по своему действию похож на встраиваемые элементы (вроде тега img). При этом его внутренняя часть форматируется как блочный элемент, а сам элемент — как встроенный. Для блоков с таким значением свойства display есть следующие особенности:
Блочно-строчные элементы ведут себя двояко. Снаружи они выглядят как обычные строчные, но внутри они ведут себя как блочные. От строчных им достались следующие черты:
От блочных:
Блочно-строчные элементы могут выстраиваться друг за другом, а если не хватает места, то они переносятся на следующую строку. Поведение похоже на флоатные элементы, однако, есть существенное отличие. При переносе на следующую строку блочно-строчные ведут себя намного логичней. Высота строк у них рассчитывается по максимальному элементу с учётом отступов. Применяться для случаев расположения в ряд нескольких элементов с заданными размерами. Блочно-строчные элементы очень часто используют для создания декоративных элементов: кнопок, плашек, блочков. Также благодаря их умному поведению с их помощью создают различные списки товаров в каталогах. Блочно-строчные ведут себя как текст, поэтому если в коде есть пробел между элементами, то он отображается и на странице. Бороться с пробелом после блочно-строчных можно несколькими способами:
Способ со шрифтом заключается в том, что мы задаём нулевой размер шрифта у контейнера инлайн-блоков, а самим инлайн-блокам задаём исходный размер шрифта. Способ не работает, если вы используете относительные размеры шрифта. Способ с маргинами заключается в том, что мы уменьшаем отступ после инлайн-блока на ширину пробела, около 4-5px. А если нам нужно, чтобы элементы стояли вплотную друг к другу, то задаём отрицательный отступ. Проблема с этим способом заключается в том, что размер пробела может быть разным в разных шрифтах и может изменяться при изменении размера шрифта. |
inline-table | Определяет, что элемент является таблицей как при использовании тега , но при этом таблица является встроенным элементом и происходит ее обтекание другими элементами, например, текстом. |
list-item | Элемент выводится как блочный и добавляется маркер списка |
run-in | Устанавливает элемент как блочный или встроенный в зависимости от контекста. |
table | Определяет, что элемент является блочной таблицей подобно использованию тега table. Табличные элементы похожи на блочные за исключением ширины по умолчанию.Особенности табличных элементов:
Любая таблица содержит элементы строка таблицы, внутри которых должны содержаться элементы ячейка таблицы. Позволяет задавать отступы между ячейками (border-spacing) или режим схлопывания границ (border-collapse). |
table-row | Элемент отображается как строка таблицы (тег TR). Строка таблицы — необычный элемент. Она является контейнером для ячеек и практически не имеет собственного отображения. Для нее можно только задавать цвет фона. |
table-cell | Указывает, что элемент представляет собой ячейку таблицы (как теги td и th).Вы можете просто задать элементу тип ячейка таблицы, не добавляя вокруг него дополнительных элементов-строк и таблиц. В этом случае браузер создаст дополнительные анонимные элементы строки и таблицы. Неудобство заключается в том, что вы не сможете ими управлять. Конечно, лучше чтобы элементы-ячейки находились внутри элементов-строк, которые находятся внутри элементов-таблиц. К таблицам, созданным с помощью CSS, можно применять те же свойства, что и к обычным таблицам. |
table-caption | Задает заголовок таблицы подобно применению тега caption |
table-column | Назначает элемент колонкой таблицы, словно был добавлен тег col |
table-column-group | Определяет, что элемент является группой одной или более колонок таблицы, как при использовании тега colgroup |
table-footer-group | Используется для хранения одной или нескольких строк ячеек, которые отображаются в самом низу таблицы. По своему действию сходно с работой тега tfoot |
table-header-group | Элемент предназначен для хранения одной или нескольких строк ячеек, которые представлены вверху таблицы. По своему действию сходно с работой тега thead |
table-row-group | Создает структурный блок, состоящий из нескольких строк таблицы аналогично действию тега tbody |
Поток и сетка
Поток — это порядок отображения элементов на странице. По умолчанию блочные элементы отображаются как прямоугольные области, идущие друг за другом сверху вниз, а строчные элементы располагаются сверху вниз и слева направо и при необходимости переносятся на новую строку. Потоком можно управлять и изменять привычное поведение элементов в потоке. Например, можно заставить блочные элементы двигаться не сверху вниз, а выстраиваться в несколько колонок.
Сетка — это взаимное расположение крупных блоков сайта.
Существует несколько способов управлять потоком и строить сетки:
- флоаты;
- инлайн-блоки;
- табличная вёрстка;
- флексбоксы.
Табличная вёрстка — самый простой для понимания способ построения сеток. Но он считается устаревшим и использовать его не рекомендуется. В будущем можно будет использовать для такой вёрстки не таблицы, а элементы с display: table, display: table-row и display: table-cell.
Флексбоксы — это новая и очень мощная технология для построения сеток. К сожалению, её поддержка браузерами ещё достаточно слабая.
Свойство float
Изначально float было предназначено для того, чтобы включать обтекание элементов текстом. Наподобие того, как в более старой версии HTML текст обтекал изображения c атрибутами align=”left” или align=”right”.
То есть, можно сказать, что float — это свойство, включающее режим обтекания. Но, как часто бывает, судьба уготовила ему совсем другую роль.
Свойство float имеет следующие значения:
- left — прижимает элемент к левому краю родителя, другие элементы обтекают его справа;
- right — прижимает элемент к правому краю родителя, другие элементы обтекают его слева;
- none — отключает режим обтекания и возвращает элементу нормальное поведение.
Обратите внимание, что зафлоатить элемент по центру нельзя.
Если мы задаём элементу свойство float:left или float:right, то он прижимается к левому или правому краю, а также начинает ужиматься по ширине под своё содержимое. С той стороны, которая не прижата к краю родителя, появляется свободное место. Это место может быть занято другими элементами. Зафлоаченному элементу можно явно задавать размеры и отступы. Есть тонкость, связанная со строчными элементами. Если зафлоатить строчный элемент, то он начинает вести себя как блочный, а именно: воспринимать размеры и отступы.
Зафлоаченные элементы выпадают из потока, но лишь частично:
- Блочные элементы, которые идут в коде после зафлоаченного блока, перестают его замечать. Они подтягиваются вверх и занимают его место, как будто его и нет.
- Строчные же элементы, расположенные в коде после зафлоаченного блока, начинают обтекать его со свободной стороны.
Ещё раз: для блочных элементов флоатные не существуют, но текст внутри этих блочных элементов будет обтекать блок у которого установлено значение float с указанной стороны.
Такое поведение флоатов даёт интересные эффекты:
- Эффект прохождения сквозь блоки. Проявляется, когда зафлоаченный элемент выше, чем несколько последующих за ним блоков.
- Эффект выпадания из родителя или схлопывания родителя. Проявляется тогда, когда все дочерние блоки в родителе зафлоачены. В этом случае родитель схлопывается по высоте, как будто в нём нет содержимого, а блоки выпадают из него.
Идущие друг за другом флоаты выстраиваются в ряд, пока им хватает свободного места. Если места не хватает, то они начинают переноситься на следующую строчку. Почти как текст. Когда не влезающий флоат переносится на новую строку, возможно несколько вариантов и не все из них логичны. Например, флоат может «зацепиться» за один из предшествующих флоатов и встать ниже не в самом начале строки, а за предшествующим.
Напомним об одной тонкости: для того, чтобы флоатный блок мог обтекаться обычным, он должен в коде располагаться выше обычного.
Свойство clear
Свойство clear запрещает обтекание элемента другими элементами. Вот его значения:
- left — запрещено обтекание слева;
- right — запрещено обтекание справа;
- both — запрещено обтекание с обеих сторон;
- none — обтекание разрешено.
Если после флоатного элемента расположен элемент с запрещённым обтеканием, то последний опускается под флоатный.
Свойство clear учит блочные элементы «видеть» зафлоаченные.
Эффект выпадания флоатов из родителя был большой проблемой при построении сеток. Ведь сетки на флоатах обычно делаются вот так:
- Создаём блок-контейнер для колонок.
- В контейнер добавляем флоатные блоки-колонки.
- Рассчитываем ширины колонок так, чтобы им хватало места в родителе.
Такой подход работает неплохо. Но проблемы начинаются тогда, когда у контейнера есть фон, отличный от фона страницы. Когда колонки выпадали, родитель схлопывался и фон пропадал.
Необходимо было найти способ борьбы с выпаданием. Тут и пригодилось свойство clear:both. Стали применять такую структуру:
1 2 3 4 5 |
<div class="container"> - блок-контейнер <div class="column1">...</div> - колонка, флоат <div class="column2">...</div> - колонка, флоат <div class="clearfix"></div> - распорка с clear:both </div> |
Т. е. начали добавлять после зафлоаченных колонок пустой элемент-распорку со свойством clear:both. Этот элемент видел колонки, не давал им пройти через себя, а заодно и растягивал родительский блок по высоте.
Для таких распорок прижилось специальное название класса — clearfix.
Псевдоэлементы позволяют с помощью CSS вставить в структуру HTML-документа узлы, которых нет в HTML коде. Т. е. можно вставить в код элемент и не писать его в HTML. Благодаря псевдоэлементам появилось решение проблемы флоатов без использования дополнительного элемента.
Назовём это решение псевдораспорками. Есть несколько его вариаций, но вот одна из распространённых. В CSS добавляется следующее правило:
1 2 3 4 5 6 7 8 9 10 11 |
.clearfix::after { content: ""; display: table; clear: both; /* Просто добавлены размеры и фон для псевдоэлемента, чтобы посмотреть, где он находится width: 100%; height: 10px; background: #e74c3c; */ } |
А затем класс clearfix добавляется к контейнеру, внутри которого лежат флоатные колонки. После этого в контейнер не нужно добавлять дополнительный элемент-распорку, т. к. распорка создаётся с помощью псевдоэлемента.
Пример простой сетки:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
<style> .wrapper { width: 550px; margin: 0 auto; box-shadow: 0 0 2px #cccccc; } .header, .footer { padding: 10px; background: #ecf0f1; } .sidebar { float: left; width: 150px; min-height: 150px; padding: 10px; color: white; background: rgba(46, 204, 113, 0.8); } .content { min-height: 100px; margin-left:170px; padding: 10px; color: white; background: #3498db; } .clearfix::after { display: table; content: ""; clear: both;; } </style> <body> <div class="wrapper"> <div class="header">Хедер</div> <div class="content-container clearfix"> <div class="sidebar"> <p>Для нужного нам эффекта мы дадим основному блоку левый margin, чтобы он ужался направо, а боковую панель заfloat'им.</p> </div> <div class="content"> <p>У этого способа есть один очень серьезный недостаток. Обратите внимание, что в исходном HTML блок "sidebar" идет до блока "content" с основным содержимым. Не нужно думать, что так сделано случайно. Так сделано специально, потому что иначе этот самый способ с наложением колонки поверх margin'а не работал бы.</p> </div> </div> <div class="footer">Футер</div> </div> </body> |
Таким образом, у нас получилась сетка из двух колонок, одна из которых фиксированная, а вторая тянется. Здесь важно следующее — сайдбар в HTML коде должен располагаться до блока контента, иначе такого эффекта не получится.
Обратите внимание еще на один подход построения сеток. Он заключается в том, что блокам разметки задаются только размеры и внешние отступы. Внутренние же отступы добавляются дополнительным элементам, вложенным в ячейки сетки.
Такой подход упрощает расчет сеток. Как вы помните, блочная модель устроена таким образом, что общий размер элемента складывается из ширины/высоты, маргинов и паддингов, а также ширины рамок. Поэтому, чтобы получить правильные размеры блоков сетки, всегда нужно помнить об этом. Если же блокам сетки задавать только ширину и внешние отступы, то слагаемых становится намного меньше, а шанс совершить ошибку уменьшается.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
<style> .clearfix::after { display: table; content: ""; clear: both; } .layout-positioner { width: 430px; margin: 0 auto; border: 2px dashed #3498db; } .layout-positioner::after { display: table; content: ""; clear: both; } .header { margin-bottom: 10px; color: white; background: #34495e; } .header .layout-column { min-height: 50px; background: rgba(192, 57, 43, 0.9); } .header .layout-column-1 { float: left; width: 280px; } .header .layout-column-2 { float: right; width: 130px; } .features { margin-bottom: 10px; } .features .layout-column { float: left; margin-right: 20px; width: 130px; min-height: 100px; background: rgba(236, 240, 241, 0.9); } .features .layout-column:last-child { margin-right: 0; } .footer { min-height: 50px; color: white; background: #34495e; } /* Стили содержания */ .hidden { display: block; } .logo { padding: 10px; } .logo p { margin: 0; } .menu { margin: 0; padding: 10px; list-style: none; } .menu li { margin-bottom: 5px; padding: 5px; text-align: center; background: #2c3e50; border-radius: 5px; } .feature { padding: 10px; text-align: center; } .footer-logo { padding: 10px; } </style> <body> <div class="header"> <div class="layout-positioner"> <div class="layout-column-1 layout-column"> <div class="logo hidden"> <img width="140" src="/themes/htmlacademy/img/logo.png"> <p>Научитесь создавать современные веб-интерфейсы, оттачивайте своё мастерство, станьте настоящим профессионалом.</p> </div> </div> <div class="layout-column-2 layout-column"> <ul class="menu hidden"> <li>Курсы</li> <li>Интенсив</li> </ul> </div> </div> </div> <div class="features"> <div class="layout-positioner"> <div class="layout-column"> <div class="feature hidden"> Вы научитесь создавать современные веб-интерфейсы, работать с живым кодом, использовать новейшие технологии. </div> </div> <div class="layout-column"> <div class="feature hidden"> Минимум скучной теории и максимум практических упражнений, решение реальных задач и настоящие испытания. </div> </div> <div class="layout-column"> <div class="feature hidden"> Интересные, наглядные и затягивающие курсы, интерактивные интерфейсы, достижения — всё для обучения с удовольствием. </div> </div> </div> </div> <div class="footer"> <div class="layout-positioner"> <div class="footer-logo hidden"> <img width="140" src="/themes/htmlacademy/img/logo.png"> </div> </div> </div> </body> |
Приём с дополнительными блоками, которые позиционируют содержание, чтобы родительские блоки могли тянуться на всю ширину окна, достаточно распространён. Дизайн с подобными сетками тоже встречается очень часто.