Базовый поток документа
HTML-документ состоит из большого количества элементов, вложенных друг в друга. Чтобы из этих элементов и CSS построить изображение страницы, их необходимо как-то в ней расположить. По умолчанию размещение всех элементов на странице осуществляется в нормальном или базовом потоке.
Что это значит? Во-первых, вывод элементов на страницу браузер осуществляет в том порядке, в котором они следуют в HTML коде.
<body> <div>1</div> <div>2</div> <div>3</div> </body>
Во-вторых, в коде элементы вложены друг в друга, и чтобы это учитывать при выводе используют так называемые воображаемые слои для отображения элементов. При этом слой элемента тем выше (ближе к нам), чем данный элемент является более вложенным в коде, т.е. глубже расположен в нём.
<body> Этот элемент находится позади других элементов. <div> Этот вложенный элемент принадлежит воображаемому слою, который находится поверх слоя родителя. <span>Этот элемент ещё ближе к нам, его слой располагается над слоем уже его родителя.</span> </div> </body>
В-третьих, положение элемента в потоке зависит от значения свойства display
.
<body> <div class="block-1"><span class="inline-1">inline 1</span><span class="inline-2">inline 2</span><span class="inline-3">inline 3</span><span class="inline-4">inline 4</span></div> <div class="block-2"><span class="inline-1">inline 1</span><span class="inline-2">inline 2</span></div> <div class="block-3"><span class="inline-1">inline 1</span><span class="inline-2">inline 2</span><span class="inline-3">inline 3</span></div> </body>
Например, элементы, имеющее блочное отображение (display: block
) отображаются в потоке как прямоугольные области, каждый из них на новой линии друг под другом сверху вниз.
Ширина элементов с блочным отображением по умолчанию равна доступной ширине родительского элемента, т.е. элемента, в который каждый из них непосредственно вложен. Высота их по умолчанию равна такой величине, которой будет достаточно, чтобы отобразить весь контент, который находится в каждом из них.
Элементы со строчным отображением (display: inline
) выводятся иначе. Они в отличии от блочных элементов не размещаются каждый на новой строке, а следуют друг за другом слево направо. Если пространство справа закончилось, то они переносятся на следующую строку, а не на новую линию как элементы с блочным отображением.
Кроме block
, inline
есть и другие варианты отображения элементов, но все они располагаются в базовом потоке документа.
В CSS есть свойства, с помощью которых элементы можно «вырвать» из основного потока документа и задать им другое положение вне базового потока элементов.
К этим свойствам относятся position
и float
.
CSS-свойство position
CSS свойство position
— это одно из свойств с помощью которого можно изменить базовое поведение элементов в потоке. Другими словами, данное свойство позволяет «выдернуть» любой элемент из потока документа и разместить его в другом месте относительно окна браузера или других элементов на веб-странице.
Свойство position
имеет 5 значений:
- static (статичное позиционирование);
- relative (относительное);
- absolute (абсолютное);
- fixed (фиксированное);
- sticky (липкое).
static
— это значение по умолчанию. Оно означает что элемент находится в базовом потоке.
Каждый элемент в потоке занимает определённую область. Но область элемента не всегда сохраняется за ним при его позиционировании.
Это, например, происходит при задании элементу position: absolute
или position: fixed
. В этом случае место не сохраняется за элементом. Другие элементы его «не видят» и располагаются, игнорируя его присутствие в коде.
Статичное позиционирование (static)
Свойство position
со значением static
элементам назначается по умолчанию. Это значение означает что элемент является не позиционированным, т.е. отображается как обычно (в потоке).
Явная установка элементу CSS-свойства position: static
может понадобиться только в том случае, когда нужно переопределить другое значение position
установленное элементу.
Установка CSS свойств для задания положения элемента left
, top
, right
и bottom
никакого влияния на него не оказывают, т.к. его местонахождение определяется потоком документа.
Пример выстраивания статично позиционированных элементов:
<body> <div style="width: 200px; height: 100px; border: 1px solid black; background: green;"></div> <div style="width: 300px; height: 150px; border: 1px solid black; background: red;"></div> </body>
Относительное позиционирование (relative)
Установка относительного позиционирования элементу осуществляется посредством задания ему CSS свойства position: relative
.
Относительно позиционированный элемент ведёт себя как элемент в потоке за исключением того, что его текущее положение можно при помощи определённых CSS свойств сместить. К этим CSS свойствам относятся left
, top
, right
и bottom
.
Например, для того чтобы элемент сдвинуть вверх или вниз относительного его исходного положения к нему нужно применить CSS свойство top
или bottom
:
position: relative; /* для сдвига элемента вверх на 10px */ top: -10px; /* или bottom: 10px; */ /* для сдвига элемента вниз на 10px */ top: 10px; /* или bottom: -10px; */
Если одновременно установить top
и bottom
, то будет применено значение top
, т.к. оно является более приоритетным, чем bottom
:
position: relative; /* элемент или элементы, к которым применяется эти стили будут сдвинуты на 15px вверх, а не на 10px как указано в bottom */ top: -15px; bottom: 10px;
Для сдвига элемента вправо или влево используется CSS свойство left
или right
:
position: relative; /* для сдвига элемента влево на 20px */ left: -20px; /* или right: 20px; */ /* для сдвига элемента вправо на 20px */ left: 20px; /* или right: -20px; */
Если одновременно установить left
и right
, то приоритетным будет значение, находящееся в left
:
position: relative; /* элемент или элементы, к которым применяется эти стили будут сдвинуты на 25px вправо, т.к. значение left более приоритетно чем right */ left: 25px; right: -20px;
Для сдвига по двум осям нужно использовать top
или bottom
, и left
или right
:
position: relative; /* стили для сдвига элементов вверх и влево на 5px */ top: -5px; left: -5px;
Пример, в котором 2 элементу установим относительное позиционирование и сместим его на 20px
вверх и влево относительно его исходного положения:
<div class="container"> <div class="element-1">FIRST ELEMENT</div> <!-- элемент имеет относительное позиционирование и смещён на 20px вверх и влево --> <div class="element-2" style="position: relative; top: -20px; left: -20px;">SECOND ELEMENT</div> <div class="element-3">THIRD ELEMENT</div> </div>
Если в некоторой области страницы оказываются несколько позиционированных элементов, то они перекрывают друг на друга в определённом порядке. При этом по умолчанию выше оказывается тот элемент, который ниже описан в коде. Но порядок перекрытия элементов (их положение перпендикулярное экрану, т.е. вдоль оси Z) можно изменить. Осуществляется в CSS это с помощью свойства z-index
. z-index
может принимать отрицательные и положительные целые число, auto
и 0
. Но, хорошей практикой является использование в качестве z-index
чисел из диапазона 0-9999
.
При этом чем больше у элемента значение z-index
, тем ближе он располагается к нам, и, следовательно, перекрывает все элементы в данной области, у которых значение z-index
меньше.
Абсолютное позиционирование (absolute)
Установка абсолютного позиционирования элементу осуществляется посредством задания ему position: absolute
.
Этот тип позиционирования позволяет разместить элемент именно там, где вы хотите.
Позиционирование выполняется относительно ближайшего позиционированного предка.
<div id="id-1" style="position: absolute"> <div id="id-2" style="position: relative"> <div id="id-3" style="position: absolute"> ... </div> </div> </div>
Под позиционированным элементом понимается элемент с position
, равным relative
, absolute
, fixed
или sticky
.
В этом примере позиционирование элемента #id-3
будет выполнять относительно #id-2
, т.к. он является позиционированным и является по отношению к нему более близким предком.
Если данный элемент не был бы позиционированным, то позиционирование #id-3
выполнялось бы относительно #id-1
:
<div id="id-1" style="position: absolute"> <div id="id-2"> <div id="id-3" style="position: absolute"> ... </div> </div> </div>
Если среди предков у элемента с position: absolute
нет позиционированного элемента, то в этом случае он будет позиционироваться относительно HTML страницы, т.е. элемента body
.
Когда элементу устанавливаем position: absolute
без указания CSS-свойств (top
, left
, right
и bottom
), определяющих его положение, он будет находиться в том месте, в котором он был бы расположен, если бы находился в потоке (при этом при вычислении его положения учитываются только элементы, расположенные до него в коде и находящиеся в потоке).
При этом другие элементы его видеть не будут, и, следовательно, они будут расположены на странице, не обращая никакого внимание на него.
<div class="container"> <div class="element-1">FIRST ELEMENT</div> <!-- элемент имеет абсолютное позиционирование и ему не установлены CSS-свойства top, bottom, left и right --> <div class="element-2" style="position: absolute;">SECOND ELEMENT</div> <div class="element-3">THIRD ELEMENT</div> </div>
CSS-свойства для управления положением абсолютно позиционированного элемента работают по-другому чем с position: relative
.
CSS-свойства top
, bottom
, left
и right
задают положение элемента относительно ближайшего позиционированного предка или body
, если такого предка нет.
Установить ширину (высоту) абсолютно позиционированному можно с помощью установки ему двух координат top
и bottom
(left
и right
).
Если элементу одновременно установить top
, bottom
и height
, то предпочтение будет отдано top
и height
.
Абсолютное позиционирование применяется очень часто совместно с относительным позиционированием в дизайнерских целях, когда необходимо разместить различные элементы относительного друг друга, так же может применяться для создания выпадающих меню, разметки сайта и т.д.
<body> <div style="width: 200px; height: 100px; border: 1px solid black; background: green;"></div> <div style="width: 300px; height: 200px; position: absolute; top: 50px; left: 100px; border: 1px solid black; background:red;"></div> </body>
Фиксированное позиционирование (fixed)
Задание элементу фиксированного позиционирования осуществляется посредством установки ему position: fixed
.
Фиксированное позиционирование похоже на абсолютное, но в отличии от него оно всегда привязывается к краям окна браузера (viewport), и остаётся в таком положении даже при скроллинге страницы.
Фиксированное позиционирование применяется для закрепления на странице навигационных меню, кнопки «вверх», панелей с социальными кнопками и многого другого.
<body> <div style="width: 200px; height: 2000px; border: 1px solid black; background: green;"></div> <div style="width: 600px; height: 200px; position: fixed; top: 100px; left: 100px; border: 1px solid black; background:red;"></div> </body>
Совместное использование относительного и абсолютного позиционирования
Относительное позиционирование очень часто используется вместе с абсолютным позиционированием.
Рассмотрим варианты:
- Если расположить блоки с абсолютным позиционированием в блок с относительным, то расстояния будут уже задаваться не от края окна браузера, а от границ относительного блока.
<body> <!-- Зелёный блок с относительным позиционированием --> <div style="width: 400px; height:400px; position:relative; top:50px; left:50px; border: 1px solid black; background:green;"> <!-- Красный блок с абсолютным позиционированием --> <div style="width: 100px; height:100px; position:absolute; top:50px; left:50px; border: 1px solid black; background:red;"></div> <!-- Синий блок с абсолютным позиционированием --> <div style="width: 100px; height:100px; position:absolute; bottom:50px; right:50px; border: 1px solid black; background:blue;"></div> </div> </body>
- Например: для создания фиксированных макетов состоящих из 3 блоков, выровненных по верхнему краю. Установим высоту «400px» относительному блоку для наглядности .
- Дополнительно к блокам можно применять свойство
z-index
, которое предназначено для позиционирования элементов по оси Z. Чем больше значение свойстваz-index
, тем ближе элемент расположен к нам, и наоборот, чем меньше значение, тем дальше расположен элемент от нас.<body> <div style="width: 300px; height:300px; position:relative; border: 1px solid black; background:green;"> <div style="width: 100px; height:100px; position: absolute; z-index: 1; left: 50px; top: 50px; border: 1px solid black; background: red;"></div> <div style="width: 100px; height: 100px; position: absolute; z-index: 2; left: 100px; top: 100px; border: 1px solid black; background: blue;"></div> <div style="width: 100px; height: 100px; position: absolute; z-index: 3; left: 150px; top: 150px; border: 1px solid black; background: yellow;"></div> </div> </body>
<body> <div style="width: 800px; height:400px; position:relative; border: 1px solid black; background:green;"> <div style="width: 200px; height:200px; position:absolute; left:0px; border: 1px solid black; background:red;">Левый блок</div> <div style="width: 400px; height:200px; position:absolute; left:200px; border: 1px solid black; background:blue;">Основной блок</div> <div style="width: 200px; height:200px; position:absolute; left:600px; border: 1px solid black; background:red;">Правый блок</div> </div> </body>
Позиционированием называется положение элемента в системе координат. Различают четыре типа позиционирования: нормальное, абсолютное, фиксированное и относительное. В зависимости от типа, который устанавливается через свойство position, изменяется и система координат.
Благодаря комбинации свойств position, left, top, right и bottom элемент можно накладывать один на другой, выводить в точке с определёнными координатами, фиксировать в указанном месте, определить положение одного элемента относительно другого и др. Подобно другим свойствам CSS управление позиционированием доступно через скрипты. Таким образом, можно динамически изменять положение элементов без перезагрузки страницы, создавая анимацию и различные эффекты.
Нормальное позиционирование
Если для элемента свойство position не задано или его значение static, элемент выводится в потоке документа как обычно. Иными словами, элементы отображаются на странице в том порядке, как они идут в исходном коде HTML.
Свойства left, top, right, bottom если определены, игнорируются.
Абсолютное позиционирование
При абсолютном позиционировании элемент не существует в потоке документа и его положение задаётся относительно краёв браузера. Задать этот тип можно через значение absolute свойства position. Координаты указываются относительно краёв окна браузера, называемого «видимой областью» (рис. 3.42).
Рис. 3.42. Значения свойств left, right, top и bottom при абсолютном позиционировании
Для режима характерны следующие особенности.
- Ширина слоя, если она не задана явно, равна ширине контента плюс значения полей, границ и отступов.
- Слой не меняет своё исходное положение, если у него нет свойств right, left, top и bottom.
- Свойства left и top имеют более высокий приоритет по сравнению с right и bottom. Если left и right противоречат друг другу, то значение right игнорируется. То же самое касается и bottom.
- Если left задать отрицательное значение, то слой уйдёт за левый край браузера, полосы прокрутки при этом не возникнет. Это один из способов спрятать элемент от просмотра. То же относится и к свойству top, только слой уйдёт за верхний край.
- Если left задать значение больше ширины видимой области или указать right с отрицательным значением, появится горизонтальная полоса прокрутки. Подобное правило работает и с top, только речь пойдёт о вертикальной полосе прокрутки.
- Одновременно указанные свойства left и right формируют ширину слоя, но только если width не указано. Стоит добавить свойство width и значение right будет проигнорировано. Аналогично произойдёт и с высотой слоя, только уже участвуют свойства top, bottom и height.
- Элемент с абсолютным позиционированием перемещается вместе с документом при его прокрутке.
Свойство position со значением absolute можно использовать для создания эффекта фреймов. Кроме абсолютного позиционирования для элементов необходимо назначить свойство overflow со значением auto. Тогда при превышении контентом высоты видимой области появится полоса прокрутки. Высота и ширина «фреймов» формируется автоматически путём одновременного использования свойств left, right для ширины и top, bottom для высоты (пример 3.31).
Пример 3.31. Создание аналога фреймов
XHTML 1.0CSS 2.1IECrOpSaFx
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Абсолютное позиционирование</title>
<style type="text/css">
body { margin: 0; }
#sidebar, #content { position: absolute; }
#sidebar, #content { overflow: auto; padding: 10px; }
#header {
height: 80px; /* Высота слоя */
background: #FEDFC0; border-bottom: 2px solid #7B5427;
}
#header h1 { padding: 20px; margin: 0; }
#sidebar {
width: 150px; background: #ECF5E4; border-right: 1px solid #231F20;
top: 82px; /* Расстояние от верхнего края */
bottom: 0; /* Расстояние снизу */
}
#content {
top: 82px; /* Расстояние от верхнего края */
left: 170px; /* Расстояние от левого края */
bottom: 0; right: 0;
}
</style>
</head>
<body>
<div id="header"><h1>Плов народов мира</h1></div>
<div id="sidebar">
<p>Плов по-фергански</p><p>Плов узбекский</p>
<p>Плов сибирский</p><p>Плов итальянский</p>
<p>Плов эстонский</p><p>Плов по-американски</p>
<p>Плов по-индейски</p>
</div>
<div id="content">
<h2>Плов по-фергански</h2>
<p>Положить в казан нарезанное кусочками мясо и поджарить его до
образования корочки. Нашинкованный кольцами лук жарить вместе
с мясом до красноватого цвета, затем добавить морковь, нарезанную
соломкой. Положить половину соли, всё перемешать и жарить, пока
морковь не приобретёт золотисто-коричневый цвет. После этого налить
половину необходимого количества воды и дать закипеть.</p>
<p>Засыпать ровным слоем рис, усилить огонь и тотчас налить воду,
чтобы она накрыла рис на 1–1,5 см. Как только вода выпарится, плов
при помощи шумовки собрать к середине горкой, проколоть палочкой в
нескольких местах так, чтобы вода, находящаяся на поверхности,
прошла на дно. Затем накрыть плов и дать ему упреть 20–25 мин.</p>
<p>Тщательно перемешайте готовый плов, переложите в большое блюдо,
сверху разложите мясо.</p>
</div>
</body>
</html>
Результат данного примера показан на рис. 3.43. Слой header выводится в потоке как обычно, а для слоёв sidebar и content установлено абсолютное позиционирование.
Рис. 3.43. Применение абсолютного позиционирования
В браузере IE6 для абсолютно позиционированных элементов нельзя одновременно задать свойства left, right и top, bottom.
Абсолютное позиционирование также применяется для создания различных эффектов, например, всплывающей подсказки к фотографиям. В отличие от атрибута title тега <img> который также выводит текст подсказки, через стили можно управлять видом текста выводимого с помощью скрипта.
Для начала создадим пустой слой с идентификатором floatTip и определим его стиль. Обязательными должны быть три стилевых свойства — position со значением absolute, display со значением none скрывает слой и width задаёт ширину слоя с подсказкой. Остальные свойства используются по желанию разработчика и предназначены для изменения оформления слоя (пример 3.32).
Пример 3.32. Стиль для всплывающей подсказки
#floatTip {
position: absolute; /* Абсолютное позиционирование */
width: 250px; /* Ширина блока */
display: none; /* Прячем от показа */
border: 1px solid #000; /* Параметры рамки */
padding: 5px; /* Поля вокруг текста */
font-family: sans-serif; /* Рубленый шрифт */
font-size: 9pt; /* Размер шрифта */
color: #333; /* Цвет текста */
background: #ECF5E4; /* Цвет фона */
}
Сам скрипт состоит из двух функций — moveTip() отслеживает движение мыши и в соответствии с координатами курсора меняет положение слоя, и toolTip() управляет видимостью слоя и выводит в нём желаемый текст (пример 3.33).
Пример 3.33. Скрипт для вывода слоя
document.onmousemove = moveTip;
function moveTip(e) {
floatTipStyle = document.getElementById("floatTip").style;
w = 250; // Ширина слоя
// Для браузера IE
if (document.all) {
x = event.x + document.body.scrollLeft;
y = event.y + document.body.scrollTop;
// Для остальных браузеров
} else {
x = e.pageX; // Координата X курсора
y = e.pageY; // Координата Y курсора
}
// Показывать слой справа от курсора
if ((x + w + 10) < document.body.clientWidth) {
floatTipStyle.left = x + 'px';
// Показывать слой слева от курсора
} else {
floatTipStyle.left = x - w + 'px';
}
// Положение от верхнего края окна браузера
floatTipStyle.top = y + 20 + 'px';
}
function toolTip(msg) {
floatTipStyle = document.getElementById("floatTip").style;
if (msg) {
// Выводим текст подсказки
document.getElementById("floatTip").innerHTML = msg;
floatTipStyle.display = "block"; // Показываем слой
} else {
floatTipStyle.display = "none"; // Прячем слой
}
}
Для удобства и универсальности скрипт следует вынести в отдельный файл и подключать его через атрибут src тега <script>. Окончательный код показан в примере 3.34.
Пример 3.34. Создание всплывающей подсказки
XHTML 1.0CSS 2.1CSS 3IE 7+IE 9+CrOpSaFx
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Всплывающая подсказка</title>
<style type="text/css">
#floatTip {
position: absolute; width: 250px; display: none;
border: 1px solid #000; padding: 5px;
font-family: sans-serif; font-size: 9pt;
color: #333; background: #ECF5E4;
opacity: 0.85; /* Прозрачность слоя */
}
</style>
<script type="text/javascript" src="scripts/tooltip.js"></script>
</head>
<body>
<p><img src="images/odel2.jpg" alt="Фотография" width="300" height="450"
onmouseover="toolTip('Фотоаппарат: Canon EOS 350D<br />' +
'Объектив: Canon EF 24-105 f/4L IS USM<br />' +
'Вспышка: Canon Speedlite 580 EX<br />' +
'Выдержка: 1/125<br />Диафрагма: 5.6')" onmouseout="toolTip()" /></p>
<div id="floatTip"></div>
</body>
</html>
Результат данного примера показан на рис. 3.44. Обратите внимание, что переносы текста при вызове функции toolTip() сделаны для удобства восприятия и имеют синтаксис JavaScript. В Safari скрипт иногда не работает при переносе текста, в этом случае текст следует записать в одну строку. К стилям добавлено свойство CSS3 opacity, которое добавляет для слоя небольшую прозрачность. В IE до версии 9.0 это свойство не поддерживается.
Рис. 3.44. Всплывающая подсказка, выводимая с помощью JavaScript
Фиксированное положение
Фиксированное положение слоя задаётся значением fixed свойства position и по своему действию похоже на абсолютное позиционирование. Но в отличие от него привязывается к указанной свойствами left, top, right и bottom точке на экране и не меняет своего положения при прокрутке веб-страницы. Ещё одна разница от absolute заключается в том, что при выходе фиксированного слоя за пределы видимой области справа или снизу от неё, не возникает полос прокрутки.
Применяется такой тип позиционирования для создания меню, вкладок, заголовков, в общем, любых элементов, которые должны быть закреплены на странице и всегда видны посетителю. В примере 3.35 показано добавление подвала, который остаётся на одном месте независимо от объёма информации на сайте.
Пример 3.35. Фиксированный подвал
XHTML 1.0CSS 2.1IECrOpSaFx
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Фиксированный подвал</title>
<style type="text/css">
BODY { margin-bottom: 50px; }
#footer {
position: fixed; /* Фиксированное положение */
left: 0; bottom: 0; /* Левый нижний угол */
padding: 10px; /* Поля вокруг текста */
background: #39b54a; /* Цвет фона */
color: #fff; /* Цвет текста */
width: 100%; /* Ширина слоя */
}
</style>
</head>
<body>
<div id="content">
Все перечисленные на сайте методы ловли льва являются теоретическими
и базируются на вычислительных методах. Автор не гарантируют
вашей безопасности при их использовании и снимает с себя всякую
ответственность за результат.
Помните, лев это хищник и опасное животное!
</div>
<div id="footer">© Влад Мержевич</div>
</body>
</html>
Результат примера показан на рис. 3.45. Поскольку фиксированный подвал накладывается на текст и скрывает его, добавлен отступ снизу для селектора BODY. Браузер IE6 не поддерживает значение fixed, поэтому в нём данный пример будет работать некорректно.
Рис. 3.45. Подвал внизу страницы
Относительное позиционирование
Если задать значение relative свойства position, то положение элемента устанавливается относительно его исходного места. Добавление свойств left, top, right и bottom изменяет позицию элемента и сдвигает его в ту или иную сторону от первоначального расположения. Положительное значение left определяет сдвиг вправо от левой границы элемента, отрицательное — сдвиг влево. Положительное значение top задаёт сдвиг элемента вниз (рис. 3.46), отрицательное — сдвиг вверх.
Рис. 3.46. Значения свойств left и top при относительном позиционировании
Свойства bottom и right производят обратный эффект. При положительном значении right сдвигает элемент влево от его правого края, при отрицательном — сдвигает вправо (рис. 3.47). При положительном значении bottom элемент поднимается вверх, при отрицательном опускается вниз.
Рис. 3.47. Значения свойств right и bottom при относительном позиционировании
Для относительного позиционирования характерны следующие особенности.
- Этот тип позиционирования не применим к элементам таблицы вроде ячеек, строк, колонок и др.
- При смещении элемента относительно исходного положения, место, которое занимал элемент, остаётся пустым и не заполняется ниже или вышележащими элементами.
В примере 3.36 показан сдвиг текста заголовка вниз для придания ему особого стиля написания.
Пример 3.36. Заголовок текста
XHTML 1.0CSS 2.1IECrOpSaFx
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Заголовок</title>
<style type="text/css">
H1 {
font: bold 2em Arial, Tahome, sans-serif; /* Параметры шрифта */
color: #fff; background: #375D4C;
padding: 0 10px;
}
H1 SPAN {
position: relative; /* Относительное позиционирование */
top: 0.3em; /* Сдвигаем вниз */
}
</style>
</head>
<body>
<h1><span>Аз и буки шрифтовой науки</span></h1>
<p>Шрифт это средство выражения дизайна, а не какого-то
банального чтения.</p>
</body>
</html>
Результат данного примера показан на рис. 3.48.
Рис. 3.48. Сдвиг текста относительно исходного положения
Вложенные слои
Обычно относительное позиционирование само по себе применяется не часто, поскольку есть ряд свойств выполняющих фактически ту же роль, к примеру, тот же margin. Но сочетание разных типов позиционирования для вложенных слоёв является одним из удобных и практичных приёмов вёрстки. Если для родительского элемента задать relative, а для дочернего absolute, то произойдёт смена системы координат и положение дочернего элемента при этом указывается относительно его родителя (рис. 3.49).
Рис. 3.49. Значения свойств left, right, top и bottom во вложенных слоях
Отсчёт координат ведётся от внутреннего края границы, значения полей не учитываются. В следующем примере текст располагается в правом нижнем углу слоя возле границы, игнорируя свойство padding.
<div style="position: relative; padding: 10px; border: 1px solid #000; background: #fc0; height: 500px;">
<div style="position: absolute; right: 0; bottom: 0">
Текст
</div
</div>
Благодаря использованию четырёх свойств left, right, top, bottom для управления положением внутреннего слоя, размеры родительского слоя знать не обязательно. Это расширяет сферу применения позиционирования, поэтому position довольно активно применяется при вёрстке различных элементов. В качестве примера возьмём наложение на фотографию разной информации: количество комментариев к ней, ссылки «Добавить комментарий», «Информация об авторе» и «Добавить в избранное». В целом, результат должен быть примерно таким, как на рис. 3.50.
Рис. 3.50. Фотография с наложенными элементами
Сам код приведён в примере 3.37. Для слоя photo установлено относительное позиционирование, а для внутренних слоёв img (вывод фотографии), comment (число комментариев) и tool (ссылки внизу фотографии) задано абсолютное позиционирование.
Пример 3.37. Позиционирование слоёв
XHTML 1.0CSS 2.1CSS 3IE 7+IE 9+CrOpSaFx
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Позиционирование слоёв</title>
<style type="text/css">
.photo { width: 300px; height: 407px; position: relative; }
.img, .comment, .tool { position: absolute; }
.comment {
background: url(images/comment_num.png) no-repeat;
width: 51px; height: 31px; /* Размеры слоя */
text-align: center; /* Выравнивание по центру */
right: 10px; top: 15px; /* Положение от правого верхнего угла */
}
.tool {
background: #000; /* Для IE */
background-color: rgba(0,0,0,0.6); /* Чёрный полупрозрачный фон */
padding: 3px 0 0;
bottom: 0; /* Положение от нижнего края */
width: 100%; /* Ширина слоя */
}
.tool img { margin-left: 5px; }
</style>
</head>
<body>
<div class="photo">
<div class="img"><img src="images/dog.jpg" alt="Щенок" /></div>
<div class="comment" title="Количество комментариев">134</div>
<div class="tool">
<img src="images/comment_add.png" alt="Добавить комментарий" />
<img src="images/photo_author.png" alt="Информация об авторе" />
<img src="images/photo_star.png" alt="Добавить в избранное" />
</div>
</div>
</body>
</html>
ul {
list-style-image: url(/images/bg/list.png);
}
li {
padding: 12px;
font-size: 16px;
}
<ul>
<li>Lorem Ipsum is simply dummy text of the printing and typesettin Lorem Ipsum is simply dummy text of the printing and typesettin</li>
<li>Lorem Ipsum is simply dummy text of the printing and typesettin</li>
<li>Lorem Ipsum is simply dummy text of the printing and typesettin</li>
<li>Lorem Ipsum is simply dummy text of the printing and typesettin</li>
<li>Lorem Ipsum is simply dummy text of the printing and typesettin</li>
<li>Lorem Ipsum is simply dummy text of the printing and typesettin</li>
</ul>
добавил свою иконку к тегу ul через list-style-image: и смотрится оно так словно они не на одной линии как можно опустить немного иконки?
Air
14.3k6 золотых знаков32 серебряных знака66 бронзовых знаков
задан 21 мар 2018 в 18:53
2
У меня такой вариант. ul точки скрываем и уменьшаем отступ. Картинки вставляем на фон li сдвигаем их вниз no-repeat 0px 3px;
, а сам текст сдвигаем вправо.
.ul1 {
list-style-type:none;
padding-left:18px;
}
.ul1 li {
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="20px" y="20px" viewBox="0 0 20 20" enable-background="new 0 0 20 20" xml:space="preserve" height="20px" width="20px"><g><circle fill="red" r="10" id="sun" cx="10" cy="10" /></g></svg>') no-repeat 0px 3px;
padding: 5px;
font-size: 16px;
padding-left: 1.5em;
}
<ul class="ul1">
<li><div>123</div></li>
<li><div>123 ffffffffffff fggggggggggggggggggf ffffffffffffffffffff fffffffffffffffffff ffffffffffffffffffffff ffffffffffffffffffff ffffffffffffffffff</div></li>
</ul>
<ul>
<li><div>123</div></li>
<li><div>123 ffffffffffff fggggggggggggggggggf ffffffffffffffffffff fffffffffffffffffff ffffffffffffffffffffff ffffffffffffffffffff ffffffffffffffffff</div></li>
</ul>
ответ дан 21 мар 2018 в 21:59
coder675coder675
2,1471 золотой знак7 серебряных знаков8 бронзовых знаков
Лучше вместо маркера сделайте иконку фоновым изображением или псевдоэлементом :before
для <li>
. Тогда проще будет манипулировать ее положением.
ответ дан 21 мар 2018 в 20:05
ИнквизиторИнквизитор
5,7791 золотой знак5 серебряных знаков20 бронзовых знаков
Here is a hacky possibility to position specifically text-elements purely by CSS, by abusing the attributes ‘letter-spacing’ for the x-coordinate and ‘baseline-shift’ for the y-coordinate:
<defs>
<font><font-face font-family="cssPosAnchor" />
<glyph unicode="." horiz-adv-x="0" />
</font>
<style type="text/css"><![CDATA[
#cssPos {
font-family:cssPosAnchor;
letter-spacing:10px; /* x-coordinate */
}
#cssPos>tspan {
font-family:serif;
letter-spacing:normal;
baseline-shift:-30px; /* negative y-coordinate */
}
]]>
</style>
</defs>
<text id="cssPos">.<tspan>CSS-Positioned Text!</tspan></text>
‘baseline-shift’ is only applicable on ‘tspan’ Elements, thus making the inner <tspan>
necessary in the presented code. Positive values for baseline-shift move the text upwards, opposite of the normal direction in the svg.
‘letter-spacing’ needs an initial letter to have an effect, thus making the .
necessary. To eliminate the width of this first letter, we use the special made font cssPosAnchor
, where the dot has no width and no shape. The following <tspan>
additionally restores font and letter-spacing.
Scope
Should work in every conforming SVG implementation.
There is one indefinite limitation though for negative x-coordinates. The specification for the ‘letter-spacing’ attribute says: “Values may be negative, but there may be implementation-specific limits.”
Compatibility
Text ‘direction’ change should work just fine, when imposed on the inner <tspan>
.
A non-standard ‘writing-mode’ must be imposed on the outer <text>
. There will most certainly be problems with that.
The probably more important ‘text-anchor’ values middle and end can be made possible like this:
<defs>
<font><font-face font-family="cssPosAnchor" />
<glyph unicode="." horiz-adv-x="0" />
<glyph unicode=" " horiz-adv-x="0" />
</font>
<style type="text/css"><![CDATA[
#cssPos {
font-family:cssPosAnchor;
letter-spacing:100px; /* x-coordinate */
word-spacing:-200px; /* negative double x-coordinate */
}
#cssPos>tspan {
font-family:serif;
word-spacing:normal;
letter-spacing:normal;
baseline-shift:-30px; /* negative y-coordinate */
}
#cssPos {
text-anchor=middle;
}
]]>
</style>
</defs>
<text id="cssPos">.<tspan>CSS-Positioned Text!</tspan> .</text>
The ‹space›.
before the closing <text>
tag produces spacing equal to minus x-coordinate. So the inner <tspan>
is moved around but preserves it’s space in the <text>
as if it was still there.
Since there may be implementation-specific limits on negative values for the spacing attributes, this is not guaranteed to work on all clients!
Here is a hacky possibility to position specifically text-elements purely by CSS, by abusing the attributes ‘letter-spacing’ for the x-coordinate and ‘baseline-shift’ for the y-coordinate:
<defs>
<font><font-face font-family="cssPosAnchor" />
<glyph unicode="." horiz-adv-x="0" />
</font>
<style type="text/css"><![CDATA[
#cssPos {
font-family:cssPosAnchor;
letter-spacing:10px; /* x-coordinate */
}
#cssPos>tspan {
font-family:serif;
letter-spacing:normal;
baseline-shift:-30px; /* negative y-coordinate */
}
]]>
</style>
</defs>
<text id="cssPos">.<tspan>CSS-Positioned Text!</tspan></text>
‘baseline-shift’ is only applicable on ‘tspan’ Elements, thus making the inner <tspan>
necessary in the presented code. Positive values for baseline-shift move the text upwards, opposite of the normal direction in the svg.
‘letter-spacing’ needs an initial letter to have an effect, thus making the .
necessary. To eliminate the width of this first letter, we use the special made font cssPosAnchor
, where the dot has no width and no shape. The following <tspan>
additionally restores font and letter-spacing.
Scope
Should work in every conforming SVG implementation.
There is one indefinite limitation though for negative x-coordinates. The specification for the ‘letter-spacing’ attribute says: “Values may be negative, but there may be implementation-specific limits.”
Compatibility
Text ‘direction’ change should work just fine, when imposed on the inner <tspan>
.
A non-standard ‘writing-mode’ must be imposed on the outer <text>
. There will most certainly be problems with that.
The probably more important ‘text-anchor’ values middle and end can be made possible like this:
<defs>
<font><font-face font-family="cssPosAnchor" />
<glyph unicode="." horiz-adv-x="0" />
<glyph unicode=" " horiz-adv-x="0" />
</font>
<style type="text/css"><![CDATA[
#cssPos {
font-family:cssPosAnchor;
letter-spacing:100px; /* x-coordinate */
word-spacing:-200px; /* negative double x-coordinate */
}
#cssPos>tspan {
font-family:serif;
word-spacing:normal;
letter-spacing:normal;
baseline-shift:-30px; /* negative y-coordinate */
}
#cssPos {
text-anchor=middle;
}
]]>
</style>
</defs>
<text id="cssPos">.<tspan>CSS-Positioned Text!</tspan> .</text>
The ‹space›.
before the closing <text>
tag produces spacing equal to minus x-coordinate. So the inner <tspan>
is moved around but preserves it’s space in the <text>
as if it was still there.
Since there may be implementation-specific limits on negative values for the spacing attributes, this is not guaranteed to work on all clients!
Позиционирование
- Назад
- Обзор: CSS layout
- Далее
Позиционирование позволяет вам изымать элементы из нормального потока макета документа и заставить их вести себя по-другому; например, располагаться друг на друге или всегда оставаться на одном и том же месте внутри окна просмотра браузера. Эта статья объясняет разные значения position
и как их использовать.
Необходимые знания: | Основы HTML (изучите Введение в HTML), идея о том как работает CSS (изучите Введение в CSS.) |
---|---|
Задача: | Изучить как работает CSS позиционирование. |
Нам бы хотелось чтобы вы следовали за нами с упражнениями на вашем локальном ПК, если возможно возьмите копию 0_basic-flow.html
из нашего GitHub репозитория (исходный код здесь) и используйте его как отправную точку.
Введение в позиционирование
Вся идея позиционирования заключается в том, чтобы позволить нам переопределять поведение базового потока документа, описанного выше, для того чтобы производить интересные эффекты. Что если вам захочется слегка изменить позицию каких-либо блоков внутри макета относительно их позиции в потоке макета по умолчанию? Ваш инструмент — позиционирование. Или если вы хотите создать элемент пользовательского интерфейса, который плавает над другими частями страницы и/или всегда располагается на одном и том же месте в окне браузера не зависимо от того сколько прокручивалась страница? Позиционирование делает возможным работу таких макетов.
Существует несколько разных типов позиционирования, которые вы можете применить к элементам HTML. Для активации специфического типа позиционирования у элемента, мы используем свойство position
.
Статическое позиционирование
Статическое позиционирование — это умолчание, которое получает каждый элемент, что всего лишь значит «поставить элемент в его нормальное положение в потоке макета документа — ничего особенного для рассмотрения».
Чтобы продемонстрировать это и настроить ваш образец для будущих разделов, сначала добавьте class
positioned
ко второму <p>
в HTML:
<p class="positioned"> ... </p>
А теперь добавьте следующее правило в конец вашего CSS:
.positioned {
position: static;
background: yellow;
}
И если вы сейчас сохраните и обновите, то вы не увидите никаких изменений, не считая обновлённого цвета фона 2-го параграфа. Это нормально, как мы и говорили ранее, статическое позиционирование является поведением по умолчанию!
Относительное позиционирование
Относительное позиционирование первый тип позиции, который мы рассмотрим. Оно очень похоже на статическое позиционирование, за исключением того что вы можете модифицировать окончательное положение позиционируемого объекта занявшего своё место в макете нормального потока, в том числе заставлять его перекрывать другие элементы на странице. Двигайтесь далее и обновите объявление position
в вашем коде:
Если вы сохраните и обновите на данном этапе, в результате вы совсем не увидите изменений. Так как же вам модифицировать положение? Вам необходимо использовать свойства top
, bottom
, left
(en-US), и right
которые мы объясним в следующем разделе.
Введение в top, bottom, left, и right
top
, bottom
, left
(en-US), и right
используются вместе с position
чтобы указать куда именно перемещать позиционируемый элемент. Для того чтобы попробовать, добавьте следующее объявление к правилу .positioned
в вашем CSS:
Примечание: значения этих свойств могут принимать любые единицы которые вы ожидаете по логике: пиксели, мм, rems, %, и т.д.
Если вы сейчас сохраните и обновите, вы получите примерно такой результат:
<h1>Relative positioning</h1>
<p>I am a basic block level element. My adjacent block level elements sit on new lines below me.</p>
<p class="positioned">By default we span 100% of the width of our parent element, and we are as tall as our child content. Our total width and height is our content + padding + border width/height.</p>
<p>We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.</p>
<p>inline elements <span>like this one</span> and <span>this one</span> sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements <span>wrap onto a new line if possible — like this one containing text</span>, or just go on to a new line if not, much like this image will do: <img src="long.jpg"></p>
body {
width: 500px;
margin: 0 auto;
}
p {
background: aqua;
border: 3px solid blue;
padding: 10px;
margin: 10px;
}
span {
background: red;
border: 1px solid black;
}
.positioned {
position: relative;
background: yellow;
top: 30px;
left: 30px;
}
Круто, правда? Хорошо, вероятно это не то, чего вы ожидали — почему он переместился вниз и вправо, когда мы указали вверх и влево? Как бы нелогично это ни звучало это всего лишь способ того как работает позиционирование — вам надо думать о невидимой силе толкающей указанную сторону позиционируемого блока, перемещая его в противоположную сторону. Так, например, если вы указали top: 30px;
, сила толкает блок, заставляя его перемещаться вниз на 30px.
Абсолютное позиционирование
Абсолютное позиционирование даёт совершенно другие результаты. Давайте попробуем изменить объявление позиции в вашем коде как показано ниже:
Если вы сохраните и обновите, то вы должны увидеть нечто подобное:
<h1>Absolute positioning</h1>
<p>I am a basic block level element. My adjacent block level elements sit on new lines below me.</p>
<p class="positioned">By default we span 100% of the width of our parent element, and we are as tall as our child content. Our total width and height is our content + padding + border width/height.</p>
<p>We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.</p>
<p>inline elements <span>like this one</span> and <span>this one</span> sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements <span>wrap onto a new line if possible — like this one containing text</span>, or just go on to a new line if not, much like this image will do: <img src="long.jpg"></p>
body {
width: 500px;
margin: 0 auto;
}
p {
background: aqua;
border: 3px solid blue;
padding: 10px;
margin: 10px;
}
span {
background: red;
border: 1px solid black;
}
.positioned {
position: absolute;
background: yellow;
top: 30px;
left: 30px;
}
В первую очередь обратите внимание на то, что интервал там, где должен быть позиционируемый элемент в потоке документа теперь отсутствует — первый и третий элементы сблизились так будто, он больше не существует! Ну, в каком-то смысле это правда. Абсолютно позиционированный элемент больше не существует в нормальном потоке макета документа. Вместо этого он располагается на своём собственном слое отдельно от всего остального. Это очень полезно: это значит, что мы можем создавать изолированные функции пользовательского интерфейса, которые не влияют на макет других элементов страницы. Например, всплывающие информационные блоки и меню управления; опрокидывающиеся панели; функции пользовательского интерфейса, которые можно перетаскивать в любом месте страницы; и так далее…
Во-вторых, обратите внимание, что позиция элемента изменилась — это потому, что top
, bottom
, left
(en-US), и right
ведут себя по-другому с абсолютным позиционированием. Вместо того, чтобы позиционировать элемент на основе его относительного положения в обычном потоке макета документа, они определяют расстояние, на котором элемент должен находиться от каждой из сторон содержащего элемента. Поэтому в этом случае мы говорим, что абсолютно позиционированный элемент должен располагаться в 30px от верха «содержащего элемента» и 30px от левого края (В этом случае «содержащий элемент» является исходным содержащим блоком. См. раздел ниже для дополнительной информации).
Примечание: вы можете использовать top
, bottom
, left
(en-US), и right
для изменения размера элемента если вам надо. Попробуйте установить top: 0; bottom: 0; left: 0; right: 0;
и margin: 0;
для вашего позиционируемого элемента и посмотрите, что произойдёт! Потом снова все верните…
Примечание: Да, margin-ы все ещё влияют на позиционируемый элемент. Однако, схлопывания margin не происходит.
Контекст позиционирования
Какой элемент является «содержащим» относительно абсолютно позиционируемого элемента? Это очень сильно зависит от свойства позиции предка позиционируемого элемента (см. Определение содержащего блока).
Если никакие из элементов предков не имеют конкретно заданного свойства позиции, то по умолчанию все элементы предков будут иметь статическую позицию. В результате этого абсолютно позиционируемый элемент будет содержаться в исходным содержащем блоке. Исходный содержащий блок имеет размеры области просмотра, а также является блоком, содержащим элемент <html>
. Проще говоря, абсолютно позиционируемый элемент будет отображаться за пределами элемента <html>
и будет расположен относительно исходного окна просмотра.
Позиционируемый элемент вложен в <body>
в исходном HTML, но в конечном макете он расположен на 30px от верхнего и левого края страницы. Мы можем изменить контекст позиционирования — относительно какого элемента позиционируется позиционируемый элемент. Это делается путём установки позиционирования на одном из предков элемента — на один из элементов, внутри которого он вложен (вы не можете позиционировать его относительно элемента, внутри которого он НЕ вложен). Чтобы продемонстрировать это, добавьте следующее объявление в правило вашего body
:
Это должно дать следующий результат:
<h1>Positioning context</h1>
<p>I am a basic block level element. My adjacent block level elements sit on new lines below me.</p>
<p class="positioned">Now I'm absolutely positioned relative to the <code><body></code> element, not the <code><html></code> element!</p>
<p>We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.</p>
<p>inline elements <span>like this one</span> and <span>this one</span> sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements <span>wrap onto a new line if possible — like this one containing text</span>, or just go on to a new line if not, much like this image will do: <img src="long.jpg"></p>
body {
width: 500px;
margin: 0 auto;
position: relative;
}
p {
background: aqua;
border: 3px solid blue;
padding: 10px;
margin: 10px;
}
span {
background: red;
border: 1px solid black;
}
.positioned {
position: absolute;
background: yellow;
top: 30px;
left: 30px;
}
Позиционируемый элемент теперь располагается относительно элемента <body>
.
Введение в z-index
Все это абсолютное позиционирование — хорошее развлечение, но кое-что чего мы ещё не рассмотрели — когда элементы начинают перекрываться, что определяет который из элементов будет появляться поверх другого элемента? В примере, который мы видели все это время, у нас имеется только один позиционируемый элемент в контексте позиционирования, и он появляется сверху поскольку позиционируемые элементы «побеждают» не позиционированные элементы. Что же насчёт того, когда мы имеем более одного?
Попробуйте добавить следующий CSS, чтобы сделать первый параграф так же абсолютно позиционированным:
p:nth-of-type(1) {
position: absolute;
background: lime;
top: 10px;
right: 30px;
}
На этом этапе вы увидите, что первый параграф окрашенный в лаймовый изъят из потока документа и помещён чуточку выше того места, где он был исходно. А также он расположен под оригинальным параграфом .positioned
, где они оба перекрываются. Это потому что параграф .positioned
является вторым параграфом по порядку в источнике и позже позиционируемые элементы в порядке источника выигрывают над ранее позиционируемыми элементами в порядке источника.
Можете ли вы изменить порядок наложения? Да, можете, используя свойство z-index
. «z-index» это ссылка к z-оси. Вы можете вспомнить из предыдущих этапов в этом курсе, где мы обсуждали использование горизонтальных (x-ось) и вертикальных (y-оси) координат веб-страницами для определения позиции для таких вещей, как фоновые изображения и смещение теней. (0,0) находится наверху слева страницы (или элемента) и оси x- и y- направляются направо и вниз страницы (во всяком случае, для языков, направленных слева на право).
У веб-страниц также имеется z-ось: воображаемая линия, которая направляется от поверхности вашего экрана к вашему лицу (или что ещё вам нравится иметь перед экраном). Значения z-index
влияют на то где позиционируемый элемент располагается на этой оси; положительные значения перемещают их выше по наложению, а отрицательные значения перемещают их ниже по наложению. По умолчанию все позиционируемые элементы имеют z-index
auto
, что фактически равно 0.
Для того чтобы изменить порядок наложения, попробуйте объявить для вашего p:nth-of-type(1)
правила:
Теперь вы должны видеть законченный пример, с параграфом лаймового цвета сверху:
<h1>z-index</h1>
<p>I am a basic block level element. My adjacent block level elements sit on new lines below me.</p>
<p class="positioned">Now I'm absolutely positioned relative to the <code><body></code> element, not the <code><html></code> element!</p>
<p>We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.</p>
<p>inline elements <span>like this one</span> and <span>this one</span> sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements <span>wrap onto a new line if possible — like this one containing text</span>, or just go on to a new line if not, much like this image will do: <img src="long.jpg"></p>
body {
width: 500px;
margin: 0 auto;
position: relative;
}
p {
background: aqua;
border: 3px solid blue;
padding: 10px;
margin: 10px;
}
span {
background: red;
border: 1px solid black;
}
.positioned {
position: absolute;
background: yellow;
top: 30px;
left: 30px;
}
p:nth-of-type(1) {
position: absolute;
background: lime;
top: 10px;
right: 30px;
z-index: 1;
}
Обратите внимание что z-index
принимает значения индекса только без единиц измерения; вы не можете задавать значения, что хотите, чтобы какой-то элемент был на 23 пикселя выше по z-оси — это так не работает. Более высокие значения будут располагаться над меньшими значениями и от вас зависит какие значения вы используете. Используя 2 и 3, вы получите тот же эффект что и 300 и 40000.
Фиксированное позиционированиее
А теперь давайте посмотрим на фиксированное позиционирование. Оно работает точно также как и абсолютное позиционирование, одним ключевым отличием: в то время как абсолютное позиционирование фиксирует элемент в месте относительно его ближайшего позиционированного предка (исходный содержащий блок если нет иного), фиксированное позиционирование обычно фиксирует элемент в месте относительно видимой части области просмотра, кроме случаев, когда один из его потомков является фиксированным блоком из-за того, что его свойству transform отличается от none. Это значит, что вы можете создать элементы пользовательского интерфейса, которые зафиксированы на месте, как постоянные меню навигации, которые всегда видимы вне зависимости от того сколько прокручивается страница.
Давайте составим простой пример, чтобы показать, что мы имеем в виду. Во-первых, удалите существующие правила p:nth-of-type(1)
и .positioned
из вашего CSS.
А теперь, обновите правило body
удалив объявление position: relative;
и добавьте фиксированную высоту как тут:
body {
width: 500px;
height: 1400px;
margin: 0 auto;
}
Теперь мы собираемся дать элементу <h1>
(en-US) position: fixed;
, а также заставить его располагаться на верху окна просмотра. Добавьте следующее правило в ваш CSS:
h1 {
position: fixed;
top: 0;
width: 500px;
margin-top: 0;
background: white;
padding: 10px;
}
top: 0;
необходим чтобы приклеить его к верху экрана. мы дали заголовку ту же ширину что и колонкам с контентом и затем даём ему белый фон и немного padding и margin, чтобы контент не был видимым под ним.
Если вы сохраните и обновите сейчас, вы увидите маленький забавный эффект, при котором заголовок останется неизменным, а содержимое будет прокручиваться вверх и исчезать под ним. Но мы можем улучшить это — в данный момент некоторый контент начинается под заголовком. Это из-за того, что позиционируемый заголовок больше не появляется в потоке документа, поэтому остальное содержимое поднимается наверх. Нам надо сдвинуть все это немного вниз; мы можем сделать это установив немного верхнего margin к первому параграфу. Добавьте его сейчас:
p:nth-of-type(1) {
margin-top: 60px;
}
Теперь вы должны видеть законченный пример:
<h1>Fixed positioning</h1>
<p>I am a basic block level element. My adjacent block level elements sit on new lines below me.</p>
<p class="positioned">I'm not positioned any more...</p>
<p>We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.</p>
<p>inline elements <span>like this one</span> and <span>this one</span> sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements <span>wrap onto a new line if possible — like this one containing text</span>, or just go on to a new line if not, much like this image will do: <img src="long.jpg"></p>
body {
width: 500px;
height: 1400px;
margin: 0 auto;
}
p {
background: aqua;
border: 3px solid blue;
padding: 10px;
margin: 10px;
}
span {
background: red;
border: 1px solid black;
}
h1 {
position: fixed;
top: 0px;
width: 500px;
background: white;
padding: 10px;
}
p:nth-of-type(1) {
margin-top: 60px;
}
position: sticky
Доступно другое значение позиции называемое position: sticky
, которое несколько новее чем другие. По сути, это гибрид относительной и фиксированной позиции, который позволяет позиционируемому элементу вести себя как будто он относительно позиционирован, до тех пор пока он не будет прокручен до определённой пороговой точки (например, 10px от вершины окна просмотра), после чего он становится фиксированным. Это можно использовать, например, чтобы заставить панель навигации прокручиваться вместе со страницей до определённой точки, а затем задерживать в верхней части страницы.
<h1>Sticky positioning</h1>
<p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci vel, viverra egestas ligula. Curabitur vehicula tellus neque, ac ornare ex malesuada et. In vitae convallis lacus. Aliquam erat volutpat. Suspendisse ac imperdiet turpis. Aenean finibus sollicitudin eros pharetra congue. Duis ornare egestas augue ut luctus. Proin blandit quam nec lacus varius commodo et a urna. Ut id ornare felis, eget fermentum sapien.</p>
<div class="positioned">Sticky</div>
<p>Nam vulputate diam nec tempor bibendum. Donec luctus augue eget malesuada ultrices. Phasellus turpis est, posuere sit amet dapibus ut, facilisis sed est. Nam id risus quis ante semper consectetur eget aliquam lorem. Vivamus tristique elit dolor, sed pretium metus suscipit vel. Mauris ultricies lectus sed lobortis finibus. Vivamus eu urna eget velit cursus viverra quis vestibulum sem. Aliquam tincidunt eget purus in interdum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
<p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci vel, viverra egestas ligula. Curabitur vehicula tellus neque, ac ornare ex malesuada et. In vitae convallis lacus. Aliquam erat volutpat. Suspendisse ac imperdiet turpis. Aenean finibus sollicitudin eros pharetra congue. Duis ornare egestas augue ut luctus. Proin blandit quam nec lacus varius commodo et a urna. Ut id ornare felis, eget fermentum sapien.</p>
body {
width: 500px;
margin: 0 auto;
}
.positioned {
background: rgba(255,84,104,.3);
border: 2px solid rgb(255,84,104);
padding: 10px;
margin: 10px;
border-radius: 5px;
}
.positioned {
position: sticky;
top: 30px;
left: 30px;
}
Интересное и общее использование position: sticky
заключается в создании индексных страниц с прокруткой, где разные заголовки липнут к верху страницы, когда они достигают его. Разметка такого примера может выглядеть так:
<h1>Sticky positioning</h1>
<dl>
<dt>A</dt>
<dd>Apple</dd>
<dd>Ant</dd>
<dd>Altimeter</dd>
<dd>Airplane</dd>
<dt>B</dt>
<dd>Bird</dd>
<dd>Buzzard</dd>
<dd>Bee</dd>
<dd>Banana</dd>
<dd>Beanstalk</dd>
<dt>C</dt>
<dd>Calculator</dd>
<dd>Cane</dd>
<dd>Camera</dd>
<dd>Camel</dd>
<dt>D</dt>
<dd>Duck</dd>
<dd>Dime</dd>
<dd>Dipstick</dd>
<dd>Drone</dd>
<dt>E</dt>
<dd>Egg</dd>
<dd>Elephant</dd>
<dd>Egret</dd>
</dl>
CSS может выглядеть как показано ниже. В нормальном потоке элементы <dt>
будут прокручиваться вместе с контентом. Когда мы добавляем position: sticky
к элементу <dt>
, вместе со значением top
0, поддерживающие браузеры будут приклеивать заголовки к вершине окна просмотра когда они будут достигать той позиции. каждый последующий заголовок будет затем заменять предыдущий при его прокрутке вверх к той позиции.
dt {
background-color: black;
color: white;
padding: 10px;
position: sticky;
top: 0;
left: 0;
margin: 1em 0;
}
body {
width: 500px;
height: 1400px;
margin: 0 auto;
}
dt {
background-color: black;
color: white;
padding: 10px;
position: sticky;
top: 0;
left: 0;
margin: 1em 0;
}
<h1>Sticky positioning</h1>
<dl>
<dt>A</dt>
<dd>Apple</dd>
<dd>Ant</dd>
<dd>Altimeter</dd>
<dd>Airplane</dd>
<dt>B</dt>
<dd>Bird</dd>
<dd>Buzzard</dd>
<dd>Bee</dd>
<dd>Banana</dd>
<dd>Beanstalk</dd>
<dt>C</dt>
<dd>Calculator</dd>
<dd>Cane</dd>
<dd>Camera</dd>
<dd>Camel</dd>
<dt>D</dt>
<dd>Duck</dd>
<dd>Dime</dd>
<dd>Dipstick</dd>
<dd>Drone</dd>
<dt>E</dt>
<dd>Egg</dd>
<dd>Elephant</dd>
<dd>Egret</dd>
</dl>
Липкие элементы являются «липкими» относительно ближайшего предка с «прокручивающимся механизмом», который определяется свойством позиции его предка.
Проверь свои навыки!
Вы достигли конца этой статьи, но помните ли вы самую важную информацию? Вы можете найти дальнейшую проверку что вы усвоили эту информацию прежде чем, отправитесь дальше — см. Проверьте свои навыки: Позиционирование.
Заключение
Я уверен, что вы повеселились с основами позиционирования; хотя это не является методом, который вы бы использовали для целого макета, всё же как вы видите, существует много задач, подходящих для него.
- Назад
- Обзор: CSS layout
- Далее
Смотрите также
- Справка свойства
position
. - Примеры практического позиционирования, для дополнительных полезных идей
В этом модуле
От автора: приветствую вас. Позиционирование css элементов является очень важной темой в сайтостроении. В этой статье я предлагаю рассмотреть его подробнее, все способы перемещения блоков по веб-странице.
Какие бывают виды
Если говорить о позиционировании блочных элементов, то оно задается с помощью свойства position. У него есть четыре значения и каждое заслуживает отдельного рассмотрения.
Абсолютное позиционирование
Это первый из известных видов. Задается так: position: absolute. После этого блок теряет свои привычные свойства и полностью выпадает из нормального потока. Что представляет собой этот поток? Попробуйте поставить в разметке несколько блочных элементов подряд. Как они станут? Друг за другом, и ни как иначе.
Это нормальное поведение блоков по умолчанию. А что же происходит с блоком, которому определено абсолютное позиционирование? Он полностью выпадает из нормального потока, другие блоки просто перестают замечать его, словно его никогда не было, но при этом элемент остается на странице. Абсолютное позиционирование в css часто применяется для точной расстановки декоративных элементов, иконок и прочего оформительского добра.
Теперь его можно перемещать с помощью свойств left, right, top и bottom. По умолчанию перемещение происходит относительно краев окна браузера, но если у родительского элемента задано position: relative, то смещение происходит относительно родительского блока.
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Узнать подробнее
.block{ position: absolute; bottom: 0; right: 0; } |
Элемент будет сдвинут в нижний правый угол. Я замечаю, что часто так делают кнопку наверх – просто размещают ее абсолютно в самый угол. А вот другой пример, в котором я покажу сначала возможную разметку:
<div id = «wrapper»> <div class = «block»></div> </div> |
А теперь css-стили для этого фрагмента:
#wrapper{ position: relative; } .block{ position: absolute; top: 0; right: 10px; } |
В этом примере мы сначала родительскому контейнеру записали относительное позиционирование (relative – о нем дальше в статье), а потом для того же элемента .block задали абсолютное. В результате отсчет координат будет происходить не от самого окна браузера, а от краев элемента родителя, то есть блока wrapper.
Относительное позиционирование css-элементов
Это следующий вид и он записывается так – position: relative. Координаты задаются такими же свойствами, как и при абсолютном положении. Единственное существенное отличие заключается в том, что элемент формально не выпадает из потока – под него остается место.
Работу этого значения можно сравнить с visibility: hidden, когда элемент скрывается со страницы, но место под него остается нетронутым. Такое же происходит и при относительном размещении – блок можно двигать куда угодно, но место под него остается пустым и его не займут другие части.
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Узнать подробнее
Еще важно знать, что смещение происходит не от краев окна веб-обозревателя, а от того места, где изначально стоял блок. То есть:
.block{ position: relative; top: 10px; right: 50px; } |
Блок подвинется на 50 пикселей вправо и на 10 влево.
Фиксация
Наверняка в интернете вы не раз видели на сайтах, когда при прокрутке какой-нибудь баннер не исчезал, а продолжал находиться в вашей зоне видимости, словно приклеиваясь к одному месту. В основном это реализуется с помощью фиксированного позиционирования. Для этого нужно записать:
.block{ position: fixed; } |
Во всем остальном фиксированное смещение полностью схоже с абсолютным – элемент выпадает из нормального потока, его место освобождается и другие элементы вообще его не замечают. С помощью такого приема можно очень легко сделать верхние, нижние, боковые панели на своем сайте с различными кнопками и меню в них, которые не будут исчезать при прокрутке и всегда находиться на глазах.
Position:static или обычное статическое положение
Последний вид – статический, это обычное поведение блочный элементов. Его не нужно прописывать, потому что оно стоит по умолчанию, но все-таки знать о четвертом значении нужно. Иногда с position: static записывают, чтобы отменить другой вид позиционирования при определенных событиях на веб-странице.
Как сделать позиционирование блоков в css правильно?
Значения то мы с вами рассмотрели, но этого мало, для того чтобы закрыть для себя эту тему. Собственно, нужно понять, где и какие виды позиционирования нужно применять. С фиксированным я вам уже привел пример – его можно использовать для создания прилипающих боковых колонок, шапок или подвалов.
Относительное позиционирование поможет, когда нужно немного сместить блок относительно его положения и при этом сохранить ему место в потоке. Также его задают блокам-родителям, чтобы использовать абсолютное перемещение для дочерних элементов.
Другие приемы: центровка, плавающие блоки
Свойство position не решает всех проблем с расстановкой блочных элементов. Как бы вы, например, создали сетку сайта с его помощью? У меня нет хороших идей. Тут на помощь приходят другие свойства.
С помощью float в css часто делают сетки. Свойство позволяет прижать блок к левому или правому краю родителя (float: left, float: right), давая возможность нескольким блочным элементам стать в одну линию, что встречается сплошь и рядом на любых сайтах.
Центровка делается так: блоку нужно записать определенную ширину, после чего задать свойство margin: 0 auto. Именно значение auto выровняет его по горизонтали точно по центру. Естественно, для этого он должен быть единственным в своей строке, иначе ничего не получится.
Все перечисленные в этой статьи виды позиционирования могут пригодиться веб-разработчику. Где-то иконку нужно вставить (position: absolute), где-то, чуть-чуть подправить положение блока, оставив за ним место (position: relative), а где и виджет зафиксировать (position: fixed). В общем, знание этого свойства точно лишним не будет.
Ну а чтобы узнавать еще больше из мира сайтостроения, обязательно подписывайтесь на наш блог и получайте новые обучающие материалы. А еще я советую вам глянуть наши премиум-уроки, где тоже поднимается подобная тема. (позиционирование элементов)
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Узнать подробнее
Верстка. Быстрый старт
Практический курс по верстке адаптивного сайта с нуля!
Смотреть
Оглавление
- Нормальный поток документа
- Относительное позиционирование (position:relative)
- Совмещаем relative и absolute
Один из важных и сложных для новичков вопросов при изучении CSS, это как позиционировать элементы на странице. Давайте разберёмся как это происходит по умолчанию и как мы можем на это влиять.
Нормальный поток документа
Рассмотрим простой пример.
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container">
<h1>Тестовый пример</h1>
<div class="item">Блок 1</div>
<div class="item">Блок 2</div>
<div class="item">Блок 3</div>
</div>
</body>
</html>
И его css пока не влияющий на позиции, но разукрашивающий блоки для наглядности.
@font-face {
font-family: 'Open Sans Condensed';
src: url('../fonts/OpenSansCondensed-Light.ttf');
font-style: normal;
font-weight: normal;
}
body {
background-color: #D9D9D9;
padding-top: 100px;
}
h1 {
font-family: 'Open Sans Condensed', sans-serif;
color: #FFF;
font-size: 40px;
}
.container {
width: 70%;
margin: 0 auto;
}
.container {
border: 2px dashed #FFF;
padding: 20px;
}
.container .item {
font-family: 'Open Sans Condensed', sans-serif;
background-color: #B47BD7;
color: #FFF;
border: 2px solid #FFF;
font-size: 30px;
line-height: 1.5;
margin: 15px 0px;
padding: 50px;
text-align: center;
border-radius: 10px;
}
Когда вы никак не влияете на позиционирование элементов, браузер выводит их по порядку.
Это называется нормальным потоком документа. Более подробно про DOM и поток документа можно почитать в этой статье. И так, одним из способов повлиять на поток, это использование CSS свойства position.
Свойство position
Что же позволяет свойство position? Данное свойство даёт нам возможность извлечь элемент из нормального потока документа и разместить его в другом месте веб страницы, например относительно окна браузера или родительского элемента.
Свойство position имеет 5 значений:
- static (статичное позиционирование);
- relative (относительное);
- absolute (абсолютное);
- fixed (фиксированное);
- sticky (липкое).
Значение static
— является значением по умолчанию. Оно означает что элемент находится в нормальном потоке документа. Стоит также отметить, что каждый элемент страницы занимает определённую область (имеет ширину и высоту) относительно других элементов. Если мы начинаем изменять значение свойства position
, занимаемая элементом область может за ним не сохраниться. К пример postion: absolut;
или position:fixed;
напрочь выдёргивают элемент из потока, при этом соседние элементы перестают его видеть, несмотря на то что в html коде страницы он есть и занимают эту область.
Статичное позиционирование (position: static)
Как уже говорилось выше, статическое позиционирование присуще всем элементам страницы по умолчанию. Вам не нужно явно указывать это свойство в CSS.
.container .item {
position: static;
}
Пунктирная линия в данном скриншоте обозначает границы родительского элемента с классом container
. Элементы внутри родителя располагаются один за другим как и описаны в коде.
Относительное позиционирование (position:relative)
При использовании position:relative; для блока начинаю работать такие css свойства как:
- top;
- bottom;
- left;
- right.
Они позволяют задать расположение элемента, относительно того места, где он находился в нормальном потоке. Добавим такой стиль блокам item из примера:
.container .item {
position: relative;
top: 80px;
left: 50px;
}
Как видите блоки сместились на 80 и 50 пикселей относительно нормального расположения.
Абсолютное позиционирование (position: absolute)
Давайте применим абсолютное позиционирование для третьего блока, а заодно изменим ему цвет. Стили будут вот такими:
.container .item:nth-last-child(2) {
background-color: #F1B217;
position: absolute;
bottom: 10%;
left: 13%;
}
В результате элемент «выпадет» из нормального потока, а его место займёт соседний элемент, т.е. блок номер 3.
В данном случае величина отступа bottom: 10%;
и left:13%;
рассчитываются от края окна браузера.
Фиксированное позиционирование (position: fixed)
Если изменить позиционирование элемента на fixed, мы закрепим его в определённом месте окна браузера так, что он будет находится там даже при прокрутке страницы. Элемент при этом так же выпадает из нормального потока документа. Давайте добавим ещё несколько блоков в наш html чтобы стала доступна вертикальная прокрутка документа:
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container">
<h1>Тестовый пример</h1>
<div class="item">Блок 1</div>
<div class="item">Блок 2</div>
<div class="item">Блок 3</div>
<div class="item">Блок 4</div>
<div class="item">Блок 5</div>
<div class="item">Блок 6</div>
<div class="item">Блок 7</div>
<div class="item">Блок 8</div>
<div class="item">Блок 9</div>
<div class="item">Блок 20</div>
<div class="item">Блок 11</div>
</div>
</body>
</html>
И поправим CSS стили подопытного блока.
.container .item:nth-last-child(2) {
background-color: #F1B217;
position: fixed;
bottom: 10%;
left: 13%;
z-index: 10000;
}
Здесь я добавил ещё одно свойство z-index: 10000;
которое гарантирует что этот элемент будет отображаться поверх всех остальных. Что мы получаем в итоге:
Блок 20 «закреплён» при помощи position: fixed;
, а его местоположение относительно краёв окна браузера заданы свойствами bottom: 10%; left: 13%;
Совмещаем relative и absolute
По умолчанию когда мы используем position: absolute;
местоположение элемента вычисляется относительно границ окна браузера. Однако, мы можем изменить это поведение задав родительскому блоку position: relative;
Вернём тестовому блоку абсолютное позиционирование:
.container .item:nth-last-child(2) {
background-color: #F1B217;
position: absolute;
bottom: 10%;
left: 13%;
z-index: 10000;
}
А его родителю, т.е. container
зададим относительное позиционирование.
.container {
border: 2px dashed #FFF;
padding: 20px;
position: relative;
}
Теперь наш тестовый элемент выпадет из потока, но будет позиционироваться относительно родителя, а не краёв окна браузера:
Таким образом мы можем более гибко управлять положением html элементов на странице при помощи css. Конкретно такая комбинация позволяет к примеру расположить иконки пунктов меню напротив текста, где иконки позиционируются абсолютно, но «внутри» пункта, которому задано относительное позиционирование.
Обязательно протестируйте примеры из статьи, попробуйте добавить больше родительских и дочерних блоков, меняйте свойство position
, это достаточно важная тема которая позволит вам научится профессионально верстать. Другие приёмы управления расположением элементов на странице, я рассмотрю позже в последующих статьях касающихся потока документа. Желаю удачи!