Как изменить положение div css

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

Базовый поток документа

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

Что это значит? Во-первых, вывод элементов на страницу браузер осуществляет в том порядке, в котором они следуют в HTML коде.

<body>
  <div>1</div>
  <div>2</div>
  <div>3</div>
</body>

Вывод элементов на страницу браузер осуществляет в том порядке, в котором они следуют в HTML коде

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

<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>

Пример, в котором показано как в CSS задать элементу относительное позиционирование

Если в некоторой области страницы оказываются несколько позиционированных элементов, то они перекрывают друг на друга в определённом порядке. При этом по умолчанию выше оказывается тот элемент, который ниже описан в коде. Но порядок перекрытия элементов (их положение перпендикулярное экрану, т.е. вдоль оси 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 задать элементу абсолютное позиционирование

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>

Блок с фиксированным позиционированием

Совместное использование относительного и абсолютного позиционирования

Относительное позиционирование очень часто используется вместе с абсолютным позиционированием.

Рассмотрим варианты:

  1. Если расположить блоки с абсолютным позиционированием в блок с относительным, то расстояния будут уже задаваться не от края окна браузера, а от границ относительного блока.
    <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>
    

    Расположение блоков с абсолютным позиционированием в относительном блоке

  2. Например: для создания фиксированных макетов состоящих из 3 блоков, выровненных по верхнему краю. Установим высоту «400px» относительному блоку для наглядности .
  3. <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>
    

    Макет, состоящий из 3 блок с абсолютным позиционированием

  4. Дополнительно к блокам можно применять свойство 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>
    

    Расположение блоков с абсолютным позиционированием, к которым применено свойство z-index

Позиционирование

  • Назад
  • Обзор: 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>&lt;body&gt;</code> element, not the <code>&lt;html&gt;</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>&lt;body&gt;</code> element, not the <code>&lt;html&gt;</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.
  • Примеры практического позиционирования, для дополнительных полезных идей

В этом модуле

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

Благодаря комбинации свойств position, left, top, right и bottom элемент можно накладывать один на другой, выводить в точке с определёнными координатами, фиксировать в указанном месте, определить положение одного элемента относительно другого и др. Подобно другим свойствам CSS управление позиционированием доступно через скрипты. Таким образом, можно динамически изменять положение элементов без перезагрузки страницы, создавая анимацию и различные эффекты.

Нормальное позиционирование

Если для элемента свойство position не задано или его значение static, элемент выводится в потоке документа как обычно. Иными словами, элементы отображаются на странице в том порядке, как они идут в исходном коде HTML.

Свойства left, top, right, bottom если определены, игнорируются.

Абсолютное позиционирование

При абсолютном позиционировании элемент не существует в потоке документа и его положение задаётся относительно краёв браузера. Задать этот тип можно через значение absolute свойства position. Координаты указываются относительно краёв окна браузера, называемого «видимой областью» (рис. 3.42).

Значения свойств left, right, top и bottom при абсолютном позиционировании

Рис. 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 это свойство не поддерживается.

Всплывающая подсказка, выводимая с помощью JavaScript

Рис. 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">&copy; Влад Мержевич</div>
 </body>
</html>

Результат примера показан на рис. 3.45. Поскольку фиксированный подвал накладывается на текст и скрывает его, добавлен отступ снизу для селектора BODY. Браузер IE6 не поддерживает значение fixed, поэтому в нём данный пример будет работать некорректно.

Подвал внизу страницы

Рис. 3.45. Подвал внизу страницы

Относительное позиционирование

Если задать значение relative свойства position, то положение элемента устанавливается относительно его исходного места. Добавление свойств left, top, right и bottom изменяет позицию элемента и сдвигает его в ту или иную сторону от первоначального расположения. Положительное значение left определяет сдвиг вправо от левой границы элемента, отрицательное — сдвиг влево. Положительное значение top задаёт сдвиг элемента вниз  (рис. 3.46), отрицательное — сдвиг вверх.

Значения свойств left и top при относительном позиционировании

Рис. 3.46. Значения свойств left и top при относительном позиционировании

Свойства bottom и right производят обратный эффект. При положительном значении right сдвигает элемент влево от его правого края, при отрицательном — сдвигает вправо (рис. 3.47). При положительном значении bottom элемент поднимается вверх, при отрицательном опускается вниз.

Значения свойств right и 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).

Значения свойств left, right, top и bottom во вложенных слоях

Рис. 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>

CSS Refresher

Это большая коллекция практических советов и заметок по вёрстке. Своеобразная памятка для тех, кто каждодневно использует CSS. Освещаются самые разные темы, от деталей поведения плавающих элементов до использования SVG и спрайтов. Проект постоянно обновляется, активное сообщество github также принимает в нем участие, там добавляются интересные замечания, о которых, возможно, вы и не слышали.

От переводчика

Приветствую всех, меня зовут Максим Иванов, и сегодня я подготовил для вас перевод заметок разработчика из Сан-Франциско Васанта Кришнамурти (Vasanth Krishnamoorthy) «CSS Refresher». Web-программирование одна из самых быстро развивающихся отраслей в наше время. Казалось бы, возьми какой-нибудь видеокурс на tuts+ и освой html-верстку, однако, как говорил разработчик Opera Software Вадим Макеев, выступая на конференции CodeFest, они все равно это делают плохо. Но давайте посмотрим, может мы итак все это знаем.

Содержание

  1. Позиционирование (position)
  2. Отображение элемента в документе (display)
  3. Плавающие элементы (float)
  4. CSS селекторы
  5. Эффективные селекторы
  6. Переотрисовка и перерасчет
  7. CSS3 свойства
  8. CSS3 медиа-запросы
  9. Адаптивный web-дизайн
  10. CSS3 переходы
  11. CSS3 анимации
  12. Масштабируемая векторная графика (SVG)
  13. CSS спрайты
  14. Вертикальное выравнивание
  15. Известные проблемы

1. Позиционирование

CSS предоставляет нам до 5 различных значений свойства position. Но по существу, только 4 из них обычно используются.

div {
  position: static; /* по умолчанию */
  position: relative;
  position: absolute;
  position: fixed;
  position: inherit; /* не используется */
}

Статическое (static, по умолчанию):

  • Единственная причина, по которой вы будете устанавливать это свойство элементу, задавая его статическим, это для того, чтобы специально очистить некоторое позиционирование, которое было применено к этому элементу за пределами вашего контроля. Такая ситуация довольно редкая, так как позиционирование не наследуется каскадом.
Относительное (relative):

  • Мы можем смещать внутренние элементы в разных направлениях, сдвигать от верхней, правой, нижней и левой границы относительно нашего родительского контейнера. Это свойство является отправной точкой для внутренних элементов данного блока, это очень важное свойство.
  • При установке в положение relative элементы занимают один и тот же объем пространства на странице, точно также, если бы мы установили их в положение static.
  • Теперь мы имеем возможность использовать Z-индексы, благодаря которым элементы на веб-странице могут накладываться друг на друга в определенном порядке, и действительно Z-индексы на самом деле не умеют работать со статическими элементами. Даже если вы не установите значение Z-индекса, этот элемент все равно будет отображаться поверх других статически-позиционированных элементов.
  • Это ограничивает сферу абсолютного позиционирования дочерних элементов. Любой элемент, который является дочерним относительно позиционируемого элемента, может быть абсолютно позиционирован внутри этого блока.
Абсолютное (absolute):

  • Когда вы применяете абсолютное позиционирование, элемент прорисовывается в новом потоке документа. Это означает, что он больше не занимает никакого пространства среди всех элементов, которые его окружали, когда он был в статическом или относительном состоянии. Просто мы указываем элементу, где ему быть и он прилипнет.
  • Для элемента с положением absolute, вы можете указать позиционирование сверху, слева, снизу и справа, чтобы установить местоположение, в конце концов. Помните, что эти значения будут относительно ближайшего родительского элемента с относительным (или абсолютным) позиционированием. Если нет такого родителя, он будет размещаться относительно самой страницы.
  • Компромисс, и наиболее важная вещь, которую нужно помнить про абсолютное позиционирование заключается в том, что эти элементы удаляются из основного потока элементов страницы. Элемент с этим типом позиционирования не зависит от других элементов и не влияют на другие элементы.
Фиксированное (fixed):

  • Подобно абсолютному позиционированию, элемент, который мы выбрали, удаляется из основного потока и создается в новом потоке документа. Однако, в этом случае, элемент позиционируется относительно самого окна браузера.
  • Основное различие от абсолютного позиционирования в том, что элемент всегда берет свое положение относительно окна браузера.
  • В отличие абсолютного позиционирования, фиксированный элемент прикрепляется к точке на экране и не меняет своего положения при прокрутке веб-страницы.
Наследованное (inherit):

  • Это свойство работает, исходя из своего названия. Элемент наследует значение родительского элемента. Как правило, элементу присваивается статическое значение, если у родителя нет никакого значения позиции.
В итоге:

  • Относительное позиционирование позволяет вам настроить положение дочернего элемента относительно себя.
  • Абсолютное позиционирование позволяет вам настроить положение вашего элемента относительно первого не статического родителя.
  • Как относительные, так и и абсолютно-позиционированные элементы не влияют на статические элементы, которые находятся рядом с ними в документе (абсолютно-позиционированные элементы удаляются из основного потока, относительно позиционированные элементы занимают исходное положение и остаются в прежнем потоке).
Подводные камни:

  • Вы не можете использовать свойство position и float одновременно. Если элемент имеет оба этих свойства (float и position:absolute или fixed), в этом случае, float не будет использован.
  • Внешние отступы (margin) не создают проблем абсолютно-позиционированным элементам. Допустим у вас есть обычный параграф (p элемент) с нижним отступом в 20px (пикселей). Ниже него изображение с верхним отступом в 30px. Пространство между параграфом и изображение не будет 50px (20px + 30px), а скорее 30px (30px > 20 пикселей). Это момент называется схлопывающиеся отступы. Два отступа комбинируют (или сворачиваются) для того, чтобы объединиться в один. Абсолютно-позиционированные элементы не отслеживают отступы других элементов, тем самым перед вами не возникает неочевидный казус.
К прочтению:

Absolute, Relative, Fixed Positioning: How Do They Differ?
CSS Positioning 101
Learn CSS Positioning in Ten Steps

2. Отображение элементов в документе

Каждый элемент на веб-странице представляет собой прямоугольный блок. Свойства display определяет как должен вести себя этот прямоугольный блок, каким он должен быть.

div {
    display: inline;
    display: inline-block;
    display: block;
    display: run-in;
    display: flex;
    display: grid;
    display: none;
}

По умолчанию, все элементы являются строчными (inline), кроме тех, кто заведомо браузером указан как блочный (block). В лучшем случае, при помощи своих пользовательский стилей, вы можете сбросить строчный элемент, задав ему значение «block».

Строчный (inline):

  • Строчные элементы, имеющие «inline» по умолчанию. Такие как span, b, em и тд.
  • CSS свойства верхнего и нижнего margin/padding отступов будет игнорироваться, но будут применимы левый и правые margin/padding отступы. То есть в этом случае, у нас есть движется по горизонтали, но не по вертикали.
  • Для таких элементов игнорируются свойства ширины и высоты.
  • Если элемент является обтекаемым (имеет float), в этом случае, он по умолчанию принимает значение «block» и становится блочным.
Блочно-строчный (inline-block):

  • Блочный элемент, который обтекается другими элементами подобно строчному.
  • Такому элементу можно задавать ширину и высоту, внешние и внутренние отступы (движение по вертикали и горизонтали).
  • Сначала такой элемент отрисовывается подобно элементу со значением «block» (словно вы встраиваете изображение, img), однако затем отображается браузером как строчный элемент.
  • Существует проблема, которая возникает с внешними отступами.
Блочный (block):

  • Например, существует ряд элементов, которые по умолчанию имеют значение «block». Такие как div, section, ul и тд.
  • Блочные элементы не идут друг за другом, как строчные, они переносятся на новую строку. Если, например, ширина не задана, блок будет расширен до ширины родителя и заполнит его.
  • Игнорируется vertical-align.
Контекстный (run-in):

  • Устанавливает элемент как блочный или встроенный в зависимости от контекста.
  • Не поддерживается в Firefox + спецификация не очень хорошо определена.
  • Если после элемента с display в значении run-in следует блок, то он становится в одну строку с ним и является его частью. Иначе элемент вызывает разрыв строки.
Скрытый (none):

  • Полностью удаляет элемент со страницы.
  • В то время как элемент находится в DOM структуре документа, он удаляется визуально и, в любой другой момент, вы можете изменить это состояние.
Табличный (table):

  • Существует целый набор значений, которые позволяют изменить состояние элементов, не являющихся таблицей, превращая такие элементы в табличное представление.
  • Такое применяется довольно редко, иногда все это может носить больше смысловую нагрузки в вашем коде, если вы используете уникальные позиционирования таблиц.
div {
  display: table;
  display: inline-table; /* как таблица, но в стиле inline-block */
  display: table-cell;
  display: table-column;
  display: table-colgroup;
  display: table-header-group;
  display: table-row-group;
  display: table-footer-group;
  display: table-row;
  display: table-caption;
}

Чтобы использовать, просто имитируйте нормальную структуру таблицы. Пример:

<div style="display: table;">
  <div style="display: table-row;">
    <div style="display: table-cell;">
      Противно, но иногда полезно.
    </div>
  </div>
</div>
Адаптируемый (flex):

  • Направлена на предоставление более эффективного способа выравнивания и распределения места между элементами в контейнере (родительском блоке), даже если их размер неизвестен или динамический.
  • Основная идея flex-блоков, обладать способностью изменять свою ширина/высота (и другое), чтобы наилучшим образом заполнять свободное место (в основном, для поддержки адаптивности на всех видах устройств и размеров экрана).
  • В основном элементы будут распределяться либо вдоль главной оси, либо вдоль поперечной оси контейнера.
  • Flex-блоки лучше всего подходят для составных частей приложения и мелкомасштабных компонентов на странице, в то время как grid-блоки больше используется для компонентов на странице большого масштаба.
  • Также как существует inline-block, inline-table, существует и inline-flex.
Сеточный (grid):

  • Значение grid позволяет нам создавать макет сетки. Она направлена на решении проблем со старыми методами компоновки блоков, имеющих float и inline-block, которые в свою очередь имеют недостатки, и действительно не предназначались для макета страницы.
  • Основная идея grid-концепции, управлять содержимым, обеспечивая механизм распределения имеющегося пространство блоков в столбцы и строки, с помощью набора заранее установленных размеров.
  • Вместе с этим фактом мы можем устранить проблемы, которые появляются при разработке, опираясь на старую технику разработки сайтов, теперь вы тратите меньше усилий.
  • Не поддерживается. Только в IE10+.
  • Также как существует inline-block, inline-table, inline-flex, существует и inline-grid
К прочтению:

Flexbox Froggy
CSS Almanac: Display
The Difference Between “Block” and “Inline”
Learn CSS Layout: The «display» property

3. Плавающие элементы

div {
  float: none; /* по умолчанию */
  float: left;
  float: right;
  float: inherit;
}

  • Float определяет, по какой стороне будет выравниваться элемент, при этом остальные элементы будут обтекать его с других сторон. Плавающие (обтекающие) элементы сначала выстраиваются в нормальном потоке, затем образуется новый поток, и они сдвигаются либо вправо, либо влево (в зависимости от выбранного значения) в родительском контейнере. Иными словами, они идут по порядку друг за другом. Учитывая, что в родительском контейнере есть достаточно свободного места, эти плавающие элементы не подстраиваются и не выравниваются для распределения пространства между этими самыми элементами.
  • Как правило, плавающий элемент обязательно должен иметь фиксированную ширину. Это гарантирует, что float ведет себя так как и ожидалось, избегая проблем в некоторых браузерах.
  • Используя свойство clear, вы можете указать пять значений: left, right, both, inherit, и none. Это свойство определяет, по какой стороне будет выравниваться элемент, при этом остальные элементы будут обтекать его с других сторон. Например, если вы укажите «left», элемент задействует отмену обтекания с левого края плавающего элемента. При этом все другие элементы на этой стороне будут опущены вниз, и располагаться под текущим элементом.
  • Правило, которое я обнаружил для себя, прекрасно работает для моих float-макетов.В своем HTML коде, я почти всегда сначала создаю плавающие элементы во время разметки, прежде чем добавлять простые элементы, которые могут взаимодействовать с ними. Вы экономите большую часть времени, и это дает желаемый результат.
  • Но и тут бывают проблемы, когда вы помещаете в родительский блок плавающие элементы, родительский контейнер не может определить динамически высоту своих дочерних элементов, поэтому родительский контейнер будет иметь высоту равную нулю. Это может поломать вашу верстку. Существует метод, который позволяет родительскому элементу, определить свое пространство с учетом каких-либо плавающих элементов внутри. Можно использовать CSS свойство overflow (переполнение) со значением hidden (скрыть). Обратите внимание, что значение свойства overflow не предназначено для такого рода использования, и может вызывать некоторые проблемы, такие как скрытие нужного контента в данный момент или появление нежелательных полос прокрутки.

Хак: для очистки плавающих элементов лучше применять ‘overflow:auto’ к родительскому элементу.

Обратите внимание, что данный трюк не очищает плавающие элементы — он просто растягивает родительский контейнер. Вы можете принудительно очистить float, если вы добавите очищающий элемент после последнего плавающего элемента, или вы можете добавить в любом нужном вам месте, создав тем самым новый поток. Родительский элемент не умеет очищать дочерние плавающие элементы.

9 правил:

1. Плавающие элементы прижимаются к границам своих контейнеров, но не дальше.

2. Любой плавающий элемент будет находится либо рядом, либо ниже предыдущего элемента. Если элементы прижаты влево, второй элемент появится точно справа от первого. Если они прижаты вправо, второй элемент появится слева от первого (reverse).

3. Элемент с левым обтеканием, не может быть правее, чем элемент с правым обтеканием.

4. Плавающие элементы не могут подняться выше верхнего края родительского контейнера (однако становится еще сложнее, когда задействованы отступы).

5. Плавающий элемент не может быть выше своего соседа плавающего элемента.

6. Плавающий элемент не может быть выше своего соседа строчного элемента.

7. Плавающий элемент совместно со своим таким же соседом элементом, не могут выходить за края родительского контейнера.

8. Плавающий элемент должен быть помещен как можно выше.

9. Элемент с левым обтеканием должен быть помещен как можно дальше влево, как это возможно, элемент с правым обтеканием должен быть помещен как можно дальше вправо, как это возможно.

Подводные камни:

<img src="http://lorempixum.com/200/200/">
<p>Lorem ipsum...</p>
img {
  float: right;
  margin: 20px;
}

Внешние отступы, которые мы добавляем к абзацу применяется вдали справа от изображения. Это происходит потому, что изображение — блок! Вот почему он не увеличивает пространство между изображением и абзацем.

К прочтению:

Clearing floats
Everything You Never Knew About CSS Floats
CSS Floats 101

4. CSS селекторы

div#container > ul {
  border: 1px solid black;
}

Разница между выборкой X Y и X > Y в том, что в последнем будут выбрать только прямые потомки.

ul ~ p {
   color: red;
}

Этот селектор похож на Х + Y, но он менее строгий. В то время как смежный селектор (ul + p) выберет только первый элемент, который непосредственно предшествовало после p, в нашем же случае, это более обобщенная выборка. В нашем случае он отберет все элементы p, следующие за элементом ul.

a[href*="google"] {
  color: #1f6053;
}

Звезда означает, что указанное значение должно появиться где-то в значение атрибута.

a[href^="http"] {
   background: url(path/to/external/icon.png) no-repeat;
   padding-left: 10px;
}

Если мы хотим выбрать все ссылки, которые имеют атрибута href, начинающийся с http, то мы можем использовать данный селектор, показанный выше.

a[href$=".jpg"] {
   color: red;
}

И снова, мы используем регулярные выражение символ — $, который ищет с конца строки. В этом случае мы ищем все ссылки на изображения, заканчивающиеся на формат JPG.

a[data-info~="image"] {
   border: 1px solid black;
}

Тильда (~), символ позволяющий искать атрибут, в котором имеется значения разделенные пробелом.

div:not(#container) {
   color: blue;
}

Выбирает все элементы div, за исключением одного, элемент, который имеет идентификатор контейнера.

p::first-line {
   font-weight: bold;
   font-size: 1.2em;
}

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

li:nth-child(3) {
   color: red;
}

nth-child псевдо-классы ориентирован на конкретные элементы в стеке (набор одинаковых по типу элементов). Она принимает целое число в качестве параметра, тем не менее, отсчет начинается не с нуля. Если вы хотите вытащить второй элемент списка, используйте li:nth-child(2). Мы даже можете использовать вытаскивать чередующиеся элементы в стеке, чтобы выбрать переменный набор нам необходимо в качестве параметра передать переменную (инкремент). Например, мы можем вытащить каждый четвертый элемент списка таким образом li:nth-child(4n).

li:nth-last-child(2) {
   color: red;
}

Что если у вас огромный список элементов в UL, и нам нужен только предпоследний элемент? Пусть у нас список из 10 элементов, мы могли сделать так li:nth-child(9), но а если мы не знаем количество элементов, в этом случае, лучше использовать вариант, показанный выше.

li:first-child {
    border-top: none;
}

li:last-child {
   border-bottom: none;
}

Это особенно полезно при задании рамок и отступов для списков и таблиц.

К прочтению:

The 30 CSS Selectors you Must Memorize

5. Эффективные селекторы

Ниже приведен список селекторов в порядке эффективности (c учетом скорости поиска элемента и производительности). Идентификаторы являются наиболее эффективными, а псевдо-классы и псевдо-элементы являются наименее эффективными.

id (#myid)
class (.myclass)
tag (div, h1, p)
adjacent sibling (h1 + p)
child (ul > li)
descendant (li a)
universal (*)
attribute (a[rel=”external”])
pseudo-class and pseudo-element (a:hover, li:first-*, li:last-*)
К прочтению:

CSS Selectors: Should You Optimize Them To Perform Better?

6. Переотрисовка и перерасчет

Переотрисовка (repaint):

Также известное, как redraw — это событие, которое происходит всякий раз, когда что-то делается видимым на странице, если ранее оно было скрыто (visibility:hidden, overflow:hidden, display:none, и др), или наоборот (visibility:visible, overflow:auto, display:static, и др), когда происходят какие-то изменения в макете. Примером может быть что угодно: добавление к элементу рамки, изменение цвета фона, изменение видимости стилей — все это приводит к переотрисовке страницы. Тем самым данное событие может дорого вам обойтись в плане производительности, так как нагружает браузерный движок поиском, проходами по всем элементам, чтобы определить, что является видимым уже, а что должно отобразиться.

Перерасчет (reflow):

Перерасчет (или перекомпоновка) носит более значительный характер. Это событие будет происходить всякий раз, когда происходят манипуляции с DOM-деревом HTML документа, или когда стиль, который влияет на расположение, изменяется у элемента, это событие будет происходит всякий раз, когда атрибут class у элемента изменяется, или всякий раз, когда изменяется размер окна браузера. Цель перерасчета в том, чтобы определить, где различные части сайты теперь должны отображаться. Если вы измените родительские свойства, тогда его потомки также будут пересчитаны. Элементы, которые появляются после того, как DOM было сформировано, будут сформированы заново. Если изменяется дочерний элемент, тогда будет пересчитан и родительский элемент, чтобы учесть изменения своих потомков. Затем, происходит переотрисовка.

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

Минимальный перерасчет (minimal reflow):

Долгий перерасчет может повлиять на весь документ, всю веб-страницу. Чем больше документ, тем дольше перерасчет. Меньше HTML-кода лучше производительность. Элементы с абсолютным позиционирование или фиксированным, не влияют на структуру главного документа, так как они находятся в отдельном потоке, если в них произошли изменения, только они будут подвержены перерасчету. Конечно, документ, в котором произойдут изменения, все равно будут полностью переотрисованы, но эта проблема имеет слабый характер, чем перерасчет всего DOM-дерева.

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

Что вызывает перерасчет:

— Изменение размера окна
— Изменение шрифта
— Добавлении или удалении стилей
— Динамическое изменение, пользователь вводит текст в поле ввода
— Активация CSS псевдо-классов, к примеру, событие :hover
— Манипулирования с атрибутом class
— Сценарии манипулирования с DOM-деревом
— Расчет значений offsetWidth и offsetHeight
— Задание свойств в атрибут style

Полный список, составленный Полом Айришом (Paul Irish), того, что приводит к перерасчету DOM можно ознакомится тут.

Как свести к минимуму влияние перерасчета на производительность:

— Изменение атрибутов класса у элементов, делайте как можно реже (минимум манипуляций в DOM-дереве).
— Избегайте установки нескольких встроенных стилей.
— Применяйте анимацию к элементам, которые имеют фиксированное или абсолютное позиционирование.
— Избегайте табличной разметки.
Даже незначительные изменения в ячейке таблицы вызовут перерасчет на всех остальных узлах таблицы.
— Не используйте «CSS expressions» (также известное, как «IE expressions»)

Примечание:

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

Чрезмерные неиспользуемые стили, скорее всего, они будут бить по производительность, чем любые селекторы, которые вы добавили в свой документ. Следует прибираться в своих css-стилях. 3000 строк неиспользуемых или избыточных на странице стилей, в наше время, это не редкость. Если разные стили используются на разных страницах вашего сайта, разбейте ваш один и единственный styles.css на несколько дополнительных, это будет лучшим вариантом.

К прочтению:

Reflows & Repaints: CSS performance making your JavaScript slow?
Writing efficient CSS selectors
Why do browsers match CSS selectors from right to left?
CSS performance revisited: selectors, bloat and expensive styles

7. CSS3 свойства

border-radius:

-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;

Создает закругленные края у элементов. Можно также использовать для создания окружностей.

Помните, поскольку не во всех браузерах реализованы формальные CSS3 правила, вам может понадобиться использовать специальные браузерные префиксы (-webkit-, -moz-, -ms-, -o-) при инициализации css-правил, либо вы можете использовать css-препроцессоры для облегчения написания css-кода.

box-shadow:

-webkit-box-shadow: 1px 1px 3px #292929;
-moz-box-shadow: 1px 1px 3px #292929;
box-shadow: 1px 1px 3px #292929;

Свойство позволяет нам легко реализовывать множественные тени (наружный или внутренний) у блочного элемента, определяя значения для цвета, размера, размытия и смещения.

Так как все остальные браузеры давно поддерживают css3 свойства, мы с вами далее будем упоминать только IE.
Поддержка: IE9+

box-shadow принимает четыре параметра: x-смещение, y-смещение, размытие, цвет тени.

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

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

Если мы указываем третье значение, мы определяет расстояние размытия тени. Допустимы только положительные значения, и чем больше значение, тем больше будут размыты края.

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

-webkit-box-shadow: 0 0 20px #333 inset;
-moz-box-shadow: 0 0 20px #333 inset;
box-shadow: 0 0 20px #333 inset;

Необязательный ключевое слово ‘insert’ можно поставить, после значений размера и цвета тени. Если оно присутствует, тогда тень будет нарисована внутри элемента.

Поддержка: IE9+

text-shadow:
color: #fff;
text-shadow: 0 0 50px #333;

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

Параметры тени для текста такие же, как для box-shadow за исключением того, что отсутствует вставка текста при помощи ключевого слова.

Как с box-shadow, можно иметь несколько текстовых теней просто разделяя их запятыми. Вот пример, создающий эффект пылающего текста:

text-shadow: 0 0 4px #ccc,
             0 -5px 4px #ff3,
             2px -10px 6px #fd3,
             -2px -15px 11px #f80,
             2px -18px 18px #f20;

Поддержка: IE10+

Градиенты:

Можно объявить фон элемента сплошным цветом, либо вы можете также задать его градиентом. Используя градиенты, объявленные в CSS, лучше использовать файловые изображения, так лучше для контроля и производительности.

Градиент — это, как правило, один цвет, которые плавно переходит в другой, но в CSS вы можете контролировать каждый аспект того, как это все будет происходить, от направления до цветового насыщения.

.gradient {
  /* как запасной вариант */
  background-color: red;

  /* будет верхней позицией, если браузер поддерживает его */
  background-image: linear-gradient(red, orange);

  /* эти свойства сбросят другие свойства, как фон-позиция, браузер поймет, что вы хотите от него */
  background: red;
  background: linear-gradient(red, orange);
}

Поддержка: IE10+

Линейные градиенты:

Пожалуй, самый распространенный и полезный вид градиента. По оси реализация градиента может идти слева-направо, сверху-вниз, или под любым углом, который вы выберите. Если вы не объявляете угол, тогда по умолчанию будет задана ось сверху-вниз. Чтобы задать ось слева-направо, вы должны указать дополнительный параметр в начале линейного градиента, функцию, начинающуюся со слова «to right», указывающий направление, «направо». Слово «to» лишь синтаксическая вставка для определения также углов. Вы не ограничиваете себя только двумя цветами. На самом деле вы можете использовать цветовую палитру. Вы можете также объявить, где вы хотите отобразить тот или иной цвет. Все это называется «color-stops».

.gradient {
  height: 100px;
  background-image:
    linear-gradient(
      to right,
      red,
      yellow 10%
    );
}
Подводные камни:

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

Существуют три различных синтаксиса, которые браузеры поддерживают:
— Старый: оригинальный движок WebKit и его единственный способ, используем from() и color-stop()
— Редко используемый: старая система углов, например, ключевое слово «to left»
— Современный: новая система углов, например, ключевое слово «to right»

Кстати старая система градусов работает и сейчас, хотя новый синтаксис немного отличается. По старому способу мы определяем 0deg и слева направо и идет вращение против часовой стрелки, в новой системе (обычно без префикса) способ определяет 0deg как снизу вверх и по часовой стрелке.

Формула: OLD (or TWEENER) = (450 — new) % 360
Или даже проще: NEW = 90 — OLD, OLD = 90 — NEW
Старый синтаксис: linear-gradient(135deg, red, blue)
Новый синтаксис: linear-gradient(315deg, red, blue)

Радиальные градиенты:

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

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

Возможными значениями являются: ближайший-угловой, ближайшая сторона, самый дальний уголок, самый дальняя-боковая сторона. Вы можете размышлять так: «я хочу, чтобы этот радиальный градиент запускался из центральной точки до такой то точки, и пускай везде заполняется цветом». Все просто, вы можете указать определенные точки с помощью «at ______» первого параметра.

Подводные камни:

Есть опять три различных синтаксиса, которые поддерживают браузеры:
— Старый: оригинальный движок WebKit и его единственный способ, используем from() и color-stop()
— Редко используемый: ваши значения, которые вы указываете из центра, они могут сломаться в браузерах, которые поддерживают как раз новый синтаксис (с префиксами) и новую систему углов, поэтому нужно отслеживать этот момент.
— Современный: используйте связку, «circle closest-corner at top right»

Рекомендуется использовать autoprefixer как в postcss для обработки префиксов, чтобы не мучится с различными браузерами.

Повторяющиеся градиенты:

Размер градиента определяет окончательный цвет и размер. Если вы указали 20 пикселей, размер градиента (который затем повторяется) будет является 20 от 20px площади.

.repeat {
  background-image:
    repeating-linear-gradient(
      45deg,
      yellow,
      yellow 10px,
      red 10px,
      red 20px /* определяет размер */
    );
}

Они могут быть использованы вместе с линейным и радиальным вариациями.

К прочтению:

Box-shadow, one of CSS3’s best new features
CSS Almanac: box-shadow
CSS Gradients

8. CSS3 медиа-запросы

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

Существует три способа вызова медиа-запросов (зависимые стили):
— Во-первых, таблицы стилей в HTML или XHTML:

<link rel="stylesheet" type="text/css" media="all and (color)" href="/style.css">

— Во-вторых, в XML:

<?xml-stylesheet media="all and (color)" rel="stylesheet" href="/style.css" ?>

— И наконец, в css-стилях, с помощью правила import:

@import url("/style.css") all and (color);

— Или с помощью правила media:

@media all and (color) { /* css-код */ }

В настоящее время, существует 13 мультимедийных возможностей контролировать стили, исходя из событий браузера: вы можете отслеживать ширину, высота устройства, ориентацию устройства, изменение размера окна браузера, цвет, цветовой индекс, монохромность, разрешение экрана, развертку и сетки. Все, кроме ориентации, сканирования, и сетки может принимать min — и max — префиксы.

9. Адаптивный web-дизайн

Настройка области просмотра (viewport):

<meta name="viewport" content="width=device-width, initial-scale=1.0">

Область просмотра дает браузеру инструкции о том, как контролировать размеры страницы и масштабирование.

Ширина = часть ширины устройства — ширина контента (width=device-width), так мы устанавливает ширину страницы, чтобы использовать всю ширину экрана устройства (которое будет меняться в зависимости от устройства).

Изначальный масштаб равен 1.0, это набор начального уровня масштабирования, когда страница загружается браузером.

Подводные камни:

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

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

Используйте media-запросы, чтобы применять различные стили для малых и больших экранов. Установка большой ширины для элементов страницы, заставит окно просмотра уменьшить масштаб. Вместо этого, рассмотрите возможность использования относительной ширины значений, например, «width: 100%». Также, будьте осторожны с использованием больших абсолютных значений относительных смещений позиционирования. Ваш элемент может уйти за пределы окна просмотра устройства.

Сетка сайта:

В теории, отзывчивая сетка имеет 12 столбцов, и общую ширину 100%, она будет сжиматься и расширяться при изменении размеров окна браузера.

Сначала убедитесь, что все HTML-элементы имеют box-sizing свойство установленное в border-box. Это гарантирует, что padding и border входят в общую ширину и высоту элементов.

Добавьте следующий код в ваш CSS:

* {
    box-sizing: border-box;
}
Адаптивные изображения:

Изображения будут отзывчивыми и масштабируемыми, если свойство width равняется — 100%. Однако, лучшим вариантом будет набор max-свойств ширины (width) в 100%, поскольку изображение будет масштабироваться (увеличиваться), нам необходимо делать размер больше, а не изменять его масштаб.

Фоновые изображения могут также реагировать на изменение размеров и масштабирования устройства.

Если background-size имеет значение «contain», фоновое изображение будет масштабироваться, и пробовать вписаться в область содержимого. Однако изображение сохранит свои пропорции.

Если значение background-size задано со значением «100% 100%», фоновое изображение будет растягиваться, чтобы покрыть всю область содержимого.

Если background-size имеет значение «cover», фоновое изображение будет масштабироваться, чтобы покрыть всю область содержимого. Значение «cover» сохраняет соотношение сторон, и определяет какую часть фона изображения ему обрезать.

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

Вы можете использовать медиа-запрос min-device-width, вместо min-width, который проверяет ширину устройства, а не ширину окна браузера. Тогда изображение не будет меняться при изменении размера окна браузера:

/* Для устройств меньше, чем 400px: */
body {
    background-image: url('img_smallflower.jpg');
}

/* Для устройств 400px и больше: */
@media only screen and (min-device-width: 400px) {
    body {
        background-image: url('img_flowers.jpg');
    }
}

В HTML5 введен новый элемент, который позволяет определять более чем одно изображение
(нет поддержки в IE, только Edge 13+).

Элемент работает аналогично, как простой элемент img. Вы настраиваете различные источники, первый источник, является значением по умолчанию, потом в случае, изменении экрана браузера, изменяется и источник отображения:

<picture>
  <source srcset="img_smallflower.jpg" media="(max-width: 400px)">
  <source srcset="img_flowers.jpg">
  <img src="img_flowers.jpg" alt="Flowers">
</picture>

Атрибут srcset является обязательным и определяет источник изображения. Атрибут media является необязательным и принимает медиа-запросы, в качестве условия. Вы должны также определить img-элемент для браузеров, не поддерживающих picture (хороший запасной вариант).

Адаптивное видео:

Если свойство width равно 100%, видеоплеер будет реагировать и масштабироваться. Однако, он может быть развернут в полноэкранный режим. Лучшим решением во многих случаях будет использование параметра max-width свойства, вместо простого width.

video {
    max-width: 100%;
    height: auto;
}
К прочтению:

w3schools — Responsive Web Design
9 basic principles of responsive web design

10. CSS3 переходы

CSS переходы позволяют делать плавное изменение любого свойства элемента в течение установленного времени.

— transition-property: свойство, которое будет изменяемым (в примере, изменяем фоновое свойство)
— transition-duration: сколько времени должен длится переход (0.3 секунды)
— transition-timing-function: как быстро ведет себя переход с течением времени (ease, один из типов)

transition-timing-function — позволяет нам изменять скорость перехода, определяя ее значение один из шести возможных: ease, linear, ease-in, ease-out, ease-in-out, и cubic-bezier (которые позволяют определить свою собственную кривую времени).

Устанавливает эффект перехода между двумя состояниями элемента, они могут быть определены с помощью псевдоэлемента :hover или :active. Вместо того, чтобы добавлять переходы для каждого из состояний элемента, вам достаточно объявить инструкцию перехода всего один раз, когда он находится в нормальном состоянии.

a.foo {
  padding: 5px 10px;
  background: #9c3; /* нормальное состояние */
  -webkit-transition: background .3s ease,
    color 0.2s linear;
  -moz-transition: background .3s ease,
    color 0.2s linear;
  -o-transition: background .3s ease, color 0.2s linear;
  
  /* плавный переход в новое состояние, при срабатывании какого либо события, которое вызывает изменения */
  transition: background .3s ease, color 0.2s linear;
}
a.foo:hover,
a.foo:focus {
  color: #030;
  background: #690;
}

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

Другое основное использование изменяющихся состояний, является изменение фона поля ввода во время его фокуса.

input.ourInputBox:focus{
 -webkit-transition:background-color 0.5s linear;
 background:#CCC;
}

В этом случае, мы указываем переход во время события, поэтому мы не добавления дополнительных ненужных классов в CSS. Мы применяем перехода, когда поле ввода получает фокус.

К прочтению:

Understanding CSS3 Transitions
CSS Fundamentals: CSS3 Transitions
CSS animated properties

11. CSS3 анимации

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

— keyframes: используется для определения стилей элемента в моменты времени.
— animation properties: используется для назначения набора ключевых кадров конкретному элементу и назначению того, как будет изменяться (анимироваться) этот элемент.

Ключевые кадры (keyframes):

Ключевые кадры — это основа анимации. Они определяют то, как будет выглядеть анимация на каждом этапе временной шкалы. Каждый набор ключевых кадров ( @keyframes) состоит из:

— название анимации: имя, которое описывает анимацию, например, bounceIn
— этапы анимации: каждый этап анимации представлен в процентах, где 0% представляет начальное состояние анимации, 100% — конечное. Вы можете создавать свои промежуточные состояния.
— css свойства: определенные для каждой стадии анимации временной шкалы

Давайте посмотрим на простую реализацию @keyframes, которую назовем “bounceIn”. Этот @keyframes состоит из трех этапов. На первом этапе (0%), этот элемент имеет непрозрачность (opacity), установленную в ноль, и плавный переход масштаба, установленный в 10% от первоначального базового масштаба. На втором этапе (60%), наш элемент появляется (непрозрачность устанавливаем в значение единица) и увеличивается до 120% от своего размера по умолчанию. На заключительном этапе (100%), он возвращается к своему исходному размеру.

@keyframes добавляется в ваш основной CSS-файл.

@keyframes bounceIn {
  0% {
    transform: scale(0.1);
    opacity: 0;
  }
  60% {
    transform: scale(1.2);
    opacity: 1;
  }
  100% {
    transform: scale(1);
  }
}
Свойства анимации (animation properties):

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

Свойства анимации делают две вещи:
— мы назначаем @keyframes элементу, который хотим анимировать
— определяем, как должна вести себя анимация

Мы добавляем свойства анимации нашему CSS-селектору (или элементу), который хотим анимировать, необходимо добавить следующие два свойства для того, чтобы анимация вступила в силу:
— animation-name: имя анимации, определенное в @keyframes
— animation-duration: продолжительность анимации в секундах (например, 0.5s) или миллисекундах (например, 200ms).

Продолжая наш разговор о bounceIn, мы добавляем animation-name и animation-duration, например, к нашим div-элементам, которые хотим анимировать.

div {
  animation-duration: 2s;
  animation-name: bounceIn;
}

Сокращенная запись:

div {
  animation: bounceIn 2s;
}

Оперирую с @keyframes (набор ключевых кадров) и animation properties (свойствами анимации), мы имеем простую анимацию.

В дополнение к обязательным свойствам animation-duration и animation-name, можно дополнительно настраивать и создавать сложную анимацию, используя следующие свойства:
— animation-timing-function: задает скорость кривой анимации
— animation-delay: определяет задержку для запуска анимации
— animation-iteration-count: указывает, сколько раз анимация должна запускаться заново
— animation-direction: указывает, должна ли анимации идти в обратном направлении или чередоваться циклом
— animation-fill-mode: задает стиль элементу, если анимация не воспроизводится. Например, когда она закончилась или когда имеет задержку
— animation-play-state: определяет, будет ли анимация работать или будет приостановлена

Сокращенный синтаксис:
animation: [animation-name] [animation-duration] [animation-timing-function] [animation-delay] [animation-iteration-count] [animation-direction] [animation-fill-mode] [animation-play-state];

Чтобы добавить несколько анимации элементу, вы можете просто разделить значения запятыми. Вот пример:

.div {
  animation: slideIn 2s, rotate 1.75s;
}
К прочтению:

An Introduction to CSS Transitions & Animations
CSS Animation for Beginners
Simple CSS3 Transitions, Transforms, & Animations Compilation
Learn to Code Advanced HTML & CSS

12. Масштабируемая векторная графика (SVG)

SVG — масштабируемая векторная графика. Этот формат основан на XML, который поддерживает анимацию и интерактивность. Иными словами, SVG — это технология, которая позволяет нам создавать графику с помощью написания кода. Кроме того, она является масштабируемой. А не векторной графикой таких форматов, как PNG и JPEG, которые имеют фиксированные размеры и не могут быть масштабированы без потери качества, SVG может быть, теоретически, масштабирована до любого размера.

Мы можем использовать «.svg» файл в нашем коде, установив его в качестве источника изображения, как это делается с обычными html-изображениями, в этом случае, мы пишем «<img src=’say_hello.svg’>». Но это не так интересно. Одна из величайших особенностей формата SVG является то, что это на самом деле текстовый файл в формате XML. Так что мы можем открыть, прочитать и взаимодействовать с ним — изменять свойства элементов, такие как позиция, цвет фона или шрифты, и все это делать с помощью JavaScript и CSS. Кроме того, каждый элемент SVG может быть анимирован. И это действительно классно.

Так что, в принципе, мы всегда должны использовать SVG вместо PNG или JPEG, когда мы говорим о базовых геометрических фигурах, логотипах и векторной графики, в целом.

Вот простой красный круг в формате SVG:

<svg width="100" height="100">
    <circle cx="50" cy="50" r="40" fill="red" />
</svg>
Основные параметры:

Обычные координаты точек (х, у = 0). В SVG начальная точка находится в верхнем левом углу.
Каждое SVG-элемент имеет несколько основных параметров:
— Х: координата x верхнего левого угла элемента
— Y: координата y верхнего левого угла элемента
— fill: цвет фона элемента
— fill-opacity: прозрачность фона элемента
— stroke: цвет рамки
— stroke-width: ширина рамки

Плюсы:

— Зависит от разрешения: масштабируем без изменения качества изображения. Он широко используется для устройств с экранами Retina и теми, кто им близок.
— Маленький размер. Элементы в формате SVG, SVG-изображения занимают гораздо меньше места, чем их близнецы, созданные в растровом формате.
— Гибкость. С помощью CSS, вы можете быстро изменить и настроить графику на сайте, цвет фона, положение логотипа на странице. Чтобы сделать это, достаточно отредактировать файл в любом текстовом редакторе.
— Можно просмотреть содержимое SVG-файл в любом браузере (IE, Chrome, Opera, FireFox, Safari).
— Никаких лишних http-запросов, кроме использования тега img
— SEO-ориентированный: специальные текстовые метки, описания к изображению, могут быть анализированы поисковыми системами.
— Мы имеем полное управления через JavaScript для настройки интерактивности и анимации.

Минусы:

— Размер файла растет очень быстро, если объект состоит из большого количества мелких элементов.
— Невозможно прочитать часть графического объекта (svg-элемента), это замедляет чтение кода, а значит и время вашей работы.

Поддержка: IE9+

К прочтению:

Introduction to SVG
An introduction to SVG
The Simple Intro to SVG Animation
Icon fonts vs SVG — which is the best option?

Видео:

Using SVG — Intro
SVG Tutorials — Playlist
Working with SVG, A Primer — Sara Soueidan
You Don’t Know SVG — Dmitry Baranovskiy
SVG is for Everybody — Chris Coyier
Building Better Interfaces With SVG — Sara Soueidan
SVG Lessons I Learned The Hard Way — Sara Soueidan

13. CSS спрайты

CSS спрайт — это техника оптимизации производительности, которая сочетает в себе несколько изображений в одном изображении, называемом спрайт-лист (sprite sheet) или набор плиток (tile set). Спрайты уменьшают нагрузку на сеть за счет сокращения количества загрузок с сервера, необходимых для отображения веб-страницы.

Комбинируя несколько изображений в одном, все изображения загружаются одним http-запросом. Браузеры ограничивают количество одновременных запросов на сайте может, так как http-запрос должен убедиться в подтверждении связи. Таким образом, спрайты важны по тем же причинам, по которым мы делаем также конкатенацию, минимизацию, минификацию CSS и JavaScript файлов.

Использование спрайтов в CSS:

Вы задайте одно и тоже фоновое изображение нескольким элементам, в виде css класса, но при этом каждому из классов вы индивидуально указываете свою позицию и размеры от одной части спрайта.

.flags-canada, .flags-mexico, .flags-usa {
  background-image: url('../images/flags.png');
  background-repeat: no-repeat;
}

.flags-canada {
  height: 128px;
  background-position: -5px -5px;
}

.flags-usa {
  height: 135px;
  background-position: -5px -143px;
}

.flags-mexico {
  height: 147px;
  background-position: -5px -288px;
}
Преимущества:

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

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

К прочтению:

CSS Sprites: What They Are, Why They’re Cool, and How To Use Them
What are CSS Sprites
w3schools — Image Sprites

14. Вертикальное выравнивание

Вертикальное выравнивание — это одна из главных причин, по которой некоторые люди думают, что css это чепуха. Вы удивляетесь, наверное, почему так сложно выровнять содержимое по вертикали с помощью CSS? Почему нельзя создать свойство, которое делает это автоматически? Почему вертикальное выравнивание не работает у меня?!

Отвечая на вопрос о вертикальном выравнивании (vertical-align): это свойство применимо только для строчных элементов (inline) и табличных ячеек (table-cell), надеюсь это убьет ваши сомнения.

Это конечно, очень жестоко, но даже приняв эту истину, остаются некоторые затруднения, и сейчас вы должны ответить сами себе перед тем как что-то выравнивать по вертикали:
— ваш элемент является блочным или строчным?
— ваш текст однострочный или многострочный?
— всегда ли вы знаете высоту содержимого?
— можете ли использовать CSS3?

Метод межстрочного интервала (line-height):

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

Допустим, у вас есть следующий HTML:

  <div class="parent">
    <span class="child">Hello!</span>
  </div>

Вам необходимо выровнять элемент .child по вертикали:

  .parent {
    height: 150px;
  }

  .child {
    line-height: 150px;
  }

Но если содержание элемента .child находится непосредственно внутри родительского элемента .parent:

 <div class="parent">
    Hello!
  </div>

В этом случае, вы можете установить межстрочный интервал таким образом:

  .parent {
    height: 150px;
    line-height: 150px;
  }

Если вместо span-элемента у вас img-элемент:

  <div class="parent">
    <img src="image.jpg" class="child-image"/>
  </div>

Тогда вам нужно изменить таким образом:

 .parent {
    height: 150px;
    line-height: 150px;
  }

  .child-image {
    vertical-align: middle; /* О чудо, мы используем это свойство :) */
  }
Метод css таблиц (css table):

Этот метод заключается в имитировании таблицы с помощью CSS. Допустим, у вас есть соответствующий HTML-код:

<div class="parent">
    <div class="child">
      Hello, CSS table method!
    </div>
  </div>

Мы выравниваем .child таким образом:

  .parent {
    display: table;
  }

  .child {
    display: table-cell;
    vertical-align: middle; /* Да, оно и тут работает! */
  }

В этом случае, нам неважно какая высота у родителя, дочерний элемент всегда будет выровнен по вертикали. К сожалению, этот метод не работает в старых версиях IE.

Метод абсолютного позиционирования (absolute position):

Этот метод имеет два способа реализации:

1 — Если вы знаете высоту элемента, который хотите выровнять по вертикали
2 — Если вы не знаете этой высоты (работает только, если вы можете использовать технологии CSS3)

Допустим, у вас есть следующий HTML:

  <div class="parent">
    <div class="child">
      Hello, absolute position method!
    </div>
  </div>

В первом случае, мы можем выровнять .child таким образом:

  .parent {
    position: relative;
    height: 300px; /* Важно, чтобы родитель имел высоту отличную от "авто" */
  }

  .child {
    position: absolute;
    top: 50%;
    height: 50px;
    margin-top: -25px; /* половина высоты дочернего элемента */
  }

Во втором случае:

.parent {
    position: relative;
    height: 300px;  /* Важно, чтобы родитель имел высоту отличную от "авто" */
  }

  .child {
    position: absolute;
    top: 50%;
    transform: translateY(-50%); /* нам не важно знать высоту нашего элемента  */
  }

На самом деле, это только основные способы, при помощи который вы можете выполнить вертикальное выравнивание, однако это можно также сделать с помощью flexbox, padding, stretching и др.

К прочтению:

Centering in CSS: A Complete Guide
6 Methods For Vertical Centering With CSS
Vertical align anything with just 3 lines of CSS
How to center in CSS

15. Известные проблемы

Дополнительные внешние отступы в строчно-блочных элементах:

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

Код может быть такой, что-то вроде этого:

<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>
li {
  display: inline-block;
  background: red;
}

Затем, вы смотрите в браузере. Да, вам кажется, что все работает правильно, за исключением дополнительных отступов между элементами. Вы, не спрашивая никого, обнуляете отступы (margin: 0) в коде, однако, проблема по-прежнему остается.

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

Итак, давайте попробуем решить эту проблему.

Без пробелов в HTML:

Так что, если пробелы и есть наша проблема, давайте удалим их.

<ul>
    <li>Item 1</li><li>Item 2</li><li>Item 3</li>
  </ul>
Комментарии в HTML:
<ul>
   <li>Item content</li><!--
--><li>Item content</li><!--
--><li>Item content</li>
</ul>

Это работает точно так же, как и предыдущий метод, просто пробелы вы заменяете комментариями.

Нулевой размер шрифта в родительском контейнере:

Вы просто добавляете обнуляете размер шрифта (font-size: 0), в родительском селекторе, тем самым, размер пробелов сводится к нулю, но тогда вам придется указывать нужный размер шрифта у дочерних элементах.

 ul {
   font-size: 0;
 }

 li {
   display: inline-block;
   background: red;
   font-size: 14px;
 }
Отрицательный внешний отступ у строчно-блочного элемента:

Довольно очевидно, оказывается внешний отступ (margin) у строчно-блочных (inline-block) элементов имеет 4px, поэтому, давайте отрицательный отступ в 4px и все это будет нормально работать.

li {
  display: inline-block;
  margin: 0 -4px;
}
К прочтению:

Fighting the Space Between Inline Block Elements
Remove Whitespace Between Inline-Block Elements
CSS display inline-block Extra Margin/Space

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

5 Steps to Drastically Improve Your CSS Knowledge in 24 Hours
CSS3 Mastery
Getting to Work with CSS3 Power Tools
CSS pro tips

verstka logo

Хочешь знать больше про веб?

Подпишись на наш телеграм-канал TechRocks WEB-разработка?

Подписаться

×

Перевод статьи «A painless guide to understanding CSS positioning».

Если вы хотите действительно хорошо овладеть CSS, очень важно разобраться в свойстве position. Но стоит учесть, что для начинающих эта тема может быть довольно сложной.

Создавая свое портфолио, я обнаружил, что у меня нет понимания свойства position. Я просто случайным образом применял различные комбинации значений, пока не достигал приемлемого для себя эффекта. Но по большей части все, что я писал, приходилось стирать.

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

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

Поточная раскладка

То, как элементы отображаются на странице, называется нормальным потоком или поточной раскладкой. Это расположение элементов по умолчанию. Поток — это все элементы вашей страницы, «работающие» вместе и знающие о наличии остальных элементов.

CSS трактует каждый HTML-элемент как отдельный блок (возможно, вы слышали о понятии «блочная модель»). Элементы блочного уровня (заголовки, абзацы или блоки div) по умолчанию начинаются как бы с новой строки. А строчные (inline) элементы (например, изображения и элементы span), отображаются в строке вместе с другим контентом. Такое отображение элементов принято по умолчанию и называется нормальным потоком документа. Но CSS дает нам мощный инструмент для перезаписи нормального потока — свойство position.

Давайте рассмотрим, что оно делает.

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

Свойство position имеет пять возможных значений:

  1. static (статическое позиционирование)
  2. relative (относительное)
  3. absolute (абсолютное)
  4. fixed (фиксированное)
  5. sticky (липкое)

Мы разберем все 5 значений, но сначала обратим внимание на свойства расположения.

Свойства расположения

Само по себе свойство position не слишком-то много и может. Чтобы указать, где именно в документе нужно расположить элемент, мы используем свойства расположения (это не официальное название, это я их так называю). Этих свойств четыре:

  • top (верх)
  • left (слева)
  • right (справа)
  • bottom (низ)

Значения этих свойств определяют, насколько позиция элемента должна сместиться и в каком направлении (вверх, вниз, влево, вправо). Чуть позже мы все это разберем на примерах.

Значения свойства position

Статическое позиционирование

static — это дефолтное значение свойства position. Оно предполагает, что элементы на странице отображаются в нормальном потоке. Свойства top, left, bottom и right не влияют на элемент, имеющий position: static.

Несмотря на то, что это дефолтное значение, оно может задаваться явно. Например, когда вам нужно перезаписать значение position, установленное где-то еще (и унаследованное вашим элементом).

Давайте рассмотрим пример. На нем мы увидим, что указание position: static никак не влияет на отображение элемента.

<div class="parent-box">
  <div class="box-original">
    <div class="box-1"> </div>
  </div>

  <div class="box-original">
    <div class="box-2"> </div>
  </div>

  <div class="box-original">
    <div class="box-3"> </div>
  </div>
</div>

Здесь у нас три блока div, каждый из которых находится в родительском контейнере с классом box-original.

Давайте добавим position: static для div с классом box-2 и зададим также значения для свойств top и left.

.box-2 {
  position: static;
  top: 10px;
  left: 10px;
  border: 1px solid black;
  background-color: mediumpurple;
  width: 100px;
  height: 100px;
  text-align: center;
  display: inline-block;
  align-self: center;
  margin-left: -1px;
  margin-top: -1px;
}

Результат изменений:

See the Pen
Static Positioning by Peter (@pin0s)
on CodePen.

Как видите, несмотря на то, что мы задали свойства top и left, блок располагается в нормальном потоке.

Теперь вы знаете, что значение static является дефолтным для свойства position, а указание свойств расположения не сдвигает элементы, для которых указано position: static.

Относительное позиционирование

Относительное позиционирование означает, что элемент позиционируется относительно своей исходной позиции в нормальном потоке. Если просто задать элементу position: relative, ничего не произойдет. Для изменения позиции нужно задать свойства расположения.

В общем, если вы просто задаете элементу position: relative, он остается в нормальном потоке. Но при помощи свойств расположения вы можете его сдвинуть. Давайте рассмотрим пример.

Возьмем код из прошлого примера и заменим position: static на position: relative.

.box-2 {
  position: relative;
  top: 10px;
  left: 10px;
  border: 1px solid red;
  background-color: mediumpurple;
  width: 100px;
  height: 100px;
  text-align: center;
  align-self: center;
  margin-left: -1px;
  margin-top: -1px;
}

Результат:

See the Pen
Relative Positioning by Peter (@pin0s)
on CodePen.

Фиолетовый квадрат сдвинулся со своей нормальной позиции (обозначена серым квадратом). В этом примере задано смещение на 10px от верха и от левого края этого же элемента в дефолтном положении (т. е. смещение вниз и вправо).

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

Абсолютное позиционирование

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

Когда элементу задано позиционирование position: absolute, все остальные элементы ведут себя так, будто этого элемента вообще больше нет в документе. Поэтому для этого элемента не резервируется место поточной раскладке. Абсолютное позиционирование — мощный инструмент в деле перемещения элементов.

Когда я изучал это свойство, от меня кое-что ускользало, так что я считаю необходимым заострить ваше внимание. Элемент со свойством position: absolute позиционируется относительно своего ближайшего позиционированного предка. Это означает, что для того, чтобы абсолютное позиционирование сработало, родительский элемент должен иметь заданное значение свойства position, причем не static.

Это очень важный момент. Если ближайший родительский элемент не имеет указанного свойства position, элемент с абсолютным позиционированием будет позиционироваться относительно следующего в иерархии родительского элемента, имеющего это свойство. Если у элемента вообще не будет позиционированных предков, он будет позиционироваться относительно элемента html или viewport. Не зная этого, можно долго ломать голову, почему все работает не так, как задумано.

Элемент с абсолютным позиционированием можно перемещать как угодно. При помощи свойств top, left, bottom и right вы можете определить, где должен находиться этот элемент относительно его позиционированного предка (первого в иерархии среди имеющих значение position, отличное от static).

Вернемся к нашему примеру. Изменим свойство position второго блочного элемента на position: absolute. Прежде чем рассматривать результат, вернитесь к предыдущему пену и обратите внимание на позиционирование элемента parent-box.

.box-2 {
  position: absolute;
  top: 30px;
  left: 150px;
  border: 1px solid red;
  background-color: mediumpurple;
  width: 100px;
  height: 100px;
  text-align: center;
  align-self: center;
  margin-left: -1px;
  margin-top: -1px;
}

Результат изменений:

See the Pen
Absolute Positioning by Peter (@pin0s)
on CodePen.

Вы видите, что в документе не создалось пустого места для нашего элемента. Фактически это место схлопнулось, и другие элементы ведут себя так, будто на этом месте вообще ничего никогда не было. Так происходит потому, что наш элемент теперь позиционируется относительно элемента parent-box.

Фиксированное позиционирование

Фиксированное позиционирование работает подобно абсолютному. Оно удаляет элемент из нормального потока документа, причем под этот элемент в раскладке больше не отводится никакого места.

Элементы с фиксированным позиционированием позиционируются относительно viewport. (Viewport — это видимая пользователю область веб-страницы, то, что может увидеть пользователь, не прибегая к прокрутке, — MDN).

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

Давайте изменим позиционирование box-2 с position: absolute на position: fixed. Также мы изменим значение свойства top на 0 и удалим значение свойства left. Еще мы добавим несколько дополнительных блоков, чтобы увидеть эффект при прокрутке.

.box-2 {
  position: fixed;
  top: 0px;
  border: 1px solid red;
  background-color: mediumpurple;
  width: 100px;
  height: 100px;
  text-align: center;
  align-self: center;
  margin-left: -1px;
  margin-top: -1px;
}

Результат:

See the Pen
Fixed Positioning by Peter (@pin0s)
on CodePen.

Как видите, фиолетовый блок теперь зафиксирован вверху страницы. Мы добились такого эффекта, установив для него position: fixed и top: 0px.

При использовании position: fixed важно помнить, что элемент будет постоянно занимать какое-то место в зоне просмотра. Это может негативно сказаться на пользовательском опыте, особенно на мобильных устройствах, где пространство ограничено. Так что обдумывайте, как все будет выглядеть на разных устройствах.

Липкое позиционирование

Липкое позиционирование — это позиционирование согласно нормального потока документа, но также это смесь относительного и фиксированного позиционирования. Я имею в виду, что элемент ведет себя как относительно позиционированный, пока страница при прокрутке не достигает заданной точки — и тогда элемент начинает вести себя, как элемент с фиксированной позицией.

Давайте рассмотрим новый пример. Мы зададим dt свойство position: sticky и top: 3px (т. е. смещение на 3px от верха страницы).

dt {
  background: #007FFF;
  border-bottom: 1px solid yellow;
  border-top: 1px solid yellow;
  color: yellow;
  margin: 0;
  padding: 2px 0 0 12px;
  position: sticky;
  top: 3px;
}

Попробуйте прокрутить страницу, и увидите, как работает липкое позиционирование.

See the Pen
Sticky Positioning by Peter (@pin0s)
on CodePen.

Вы видите, что элементы dt (голубые строки) прилипают к верху страницы до тех пор, пока мы не прокрутим контент до следующего элемента dt. При достижении этой точки липким элементом становится следующий dt. Таким образом, элементы dt позиционированы в нормальном потоке страницы, но когда они достигают определенного места при прокрутке, их позиционирование меняется на фиксированное. Они закрепляются на этой позиции, пока вы не прокрутите до следующего элемента dt, который приобретет фиксированное позиционирование.

Работать с липким позиционированием надо осторожно, потому что не все браузеры его поддерживают (по крайней мере, на момент написания статьи). Проверить поддержку можно при помощи caniuse.com.

Где во всем этом место Z-индекса?

z-index — это CSS-свойство, позволяющее задавать порядок позиционированных элементов по оси z. Любой элемент, которому вы задали свойство position, отличное от static, может позиционироваться и по оси z.

Оси координат

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

Элементы с большим значением z-index отображаются перед элементами с меньшими значениями.

Рассмотрим пример. Я покажу, что при использовании z-index порядок элементов в html-разметке не имеет значения, мы можем сменить их позицию с передней на заднюю.

<div class="parent-box">

    <div class="box box-1">z-index:4</div>
    <div class="box box-2">z-index:1</div>
    <div class="box box-3">z-index:2</div>
    <div class="box box-4">z-index:5</div>
    <div class="box box-5">z-index:3</div>

</div>

Мы зададим каждому классу box позицию fixed, что позволит нам изменить z-index каждого из box-элементов.

Результат:

See the Pen
Z-index by Peter (@pin0s)
on CodePen.

Как видите, элементы с более высоким значением z-index идут на переднем плане, а с более низким — на заднем.

Заключение

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

Мы можем применять пять значений свойства position:

  • static
  • relative
  • absolute
  • fixed
  • sticky

Положение элемента задается при помощи свойств top, left, bottom и right. Значения этих свойств указывают, насколько должен сместиться элемент от указанной точки.

Если элемент позиционирован, причем значение position — не static, можно задавать положение этого элемента по оси z. Это делается при помощи свойства z-index. Чем выше значение этого свойства, тем ближе к переднему плану выводится элемент. Элементы с более низкими значениями z-index выводятся на заднем плане.

Самый лучший способ разобраться в CSS-свойстве position — поиграться с ним. Возьмите пены, приведенные здесь в качестве примеров, попробуйте поменять в них какие-нибудь значения и посмотрите, к чему это приведет.

1. Introduction

This section is not normative.

The CSS layout algorithms, by default,
size and position boxes in relation to each other
so that nothing overlaps.

This specification defines several ways to violate these assumptions when needed,
moving elements around in ways that can make them overlap other content:

  • Relative positioning, which visually shifts a box relative to its laid-out location.

  • Sticky positioning, which visually shifts a box relative to its laid-out location
    in order to keep it visible when a scrollable ancestor
    would otherwise scroll it out of sight.

  • Absolute positioning, which ignores normal layout entirely,
    pulling the element out of flow and
    positioning it relative to its containing block with no regard for other content.

  • Fixed positioning, which absolutely positions the box
    and affixes it to the viewport or page frame
    so that it is always visible.

These positioning schemes,
controlled by the position property and the inset properties,
are powerful
but easy to misuse.
With appropriate care,
they allow many interesting and useful layouts
that couldn’t otherwise be achieved with standard layout rules;
without, they allow a page to be laid out in an unusable overlapping jumble of content.

1.1. Module Interactions

This module replaces and extends the positioning scheme features
defined in [CSS2] sections:

  • 9.1.2 Containing blocks
  • 9.3 Positioning schemes
  • 9.4.3 Relative positioning
  • 9.6 Absolute positioning
  • 9.7 Relationships between display, position, and float
  • 9.8 Comparison of normal flow, floats, and absolute positioning
  • 10.1 Definition of «containing block»
  • 10.3.7 Absolutely positioned, non-replaced elements
  • 10.3.8 Absolutely positioned, replaced elements
  • 10.6.4 Absolutely positioned, non-replaced elements
  • 10.6.5 Absolutely positioned replaced elements

It also replaces and supersedes the inset* property definitions in [CSS-LOGICAL-1] (CSS Logical Properties 1 § 4.3 Flow-relative Offsets: the inset-block-start, inset-block-end, inset-inline-start, inset-inline-end properties and inset-block, inset-inline, and inset shorthands).

1.2. Value Definitions

This specification follows the CSS property definition conventions from [CSS2] using the value definition syntax from [CSS-VALUES-3].
Value types not defined in this specification are defined in CSS Values & Units [CSS-VALUES-3].
Combination with other CSS modules may expand the definitions of these value types.

In addition to the property-specific values listed in their definitions,
all properties defined in this specification
also accept the CSS-wide keywords as their property value.
For readability they have not been repeated explicitly.

2. Choosing A Positioning Scheme: position property

Name: position
Value: static | relative | absolute | sticky | fixed
Initial: static
Applies to: all elements except table-column-group and table-column
Inherited: no
Percentages: N/A
Computed value: specified keyword
Canonical order: per grammar
Animatable: no
Animation type: discrete

The position property determines which of the positioning schemes is used to calculate the position of a box.
Values other than static make the box a positioned box,
and cause it to establish an absolute positioning containing block for its descendants.
Values have the following meanings:

static
The box is not a positioned box,
and is laid out according to the rules of its parent formatting context.
The inset properties do not apply.
relative
The box is laid out as for static,
then offset from the resulting position.
This offsetting is a purely visual effect,
and does not affect the size or position of any other box,
except insofar as it increases the scrollable overflow area of its ancestors.
This positioning scheme is called relative positioning.
sticky
Identical to relative,
except that its offsets are automatically adjusted
in reference to the nearest ancestor scroll container’s scrollport (as modified by the inset properties)
in whichever axes the inset properties are not both auto,
to try to keep the box in view within its containing block as the user scrolls.
This positioning scheme is called sticky positioning.
absolute
The box is taken out of flow such that it has no impact on the size or position of its siblings and ancestors,
and does not participate in its parent’s formatting context.

Instead, the box is positioned and sized solely in reference to
its absolute positioning containing block,
as modified by the box’s inset properties,
see § 4 Absolute Positioning Layout Model.
It can overlap in-flow content
or other absolutely positioned elements,
and is included in the scrollable overflow area of the box that generates is containing block.
This positioning scheme is called absolute positioning.

fixed
Same as absolute,
except the box is positioned and sized relative to a fixed positioning containing block (usually the viewport in continuous media, or the page area in paged media).
The box’s position is fixed with respect to this reference rectangle:
when attached to the viewport it does not move when the document is scrolled,
and when attached to the page area is replicated on every page when the document is paginated.
This positioning scheme is called fixed positioning and is considered a subset of absolute positioning.

Authors may wish to specify fixed in a media-dependent way.
For instance, an author may want a box to remain at the top of the viewport on the screen,
but not at the top of each printed page.
The two specifications may be separated by using an ‘@media’ rule, as in:

@media screen {
    h1#first { position: fixed }
}
@media print {
    h1#first { position: static }
}

A position value of absolute or fixed blockifies the box,
causes float to compute to none,
and forces the box to establish an independent formatting context.

2.1. Containing Blocks of Positioned Boxes

The containing block of a static, relative, or sticky box is as defined by its formatting context.
For fixed and absolute boxes,
it is defined as follows:

If the box has position: absolute:
The containing block is established
by the nearest ancestor box that establishes an absolute positioning containing block,
in the following way:

If the ancestor is not an inline box,
the containing block is formed by the padding edge of the ancestor,
unless otherwise specified
(for example, see CSS Grid Layout 1 § 9.1 With a Grid Container as Containing Block).
If the ancestor is an inline box,
the containing block is formed by
the block-start and inline-start content edges of the first box fragment of the ancestor,
and the block-end and inline-end content edges of the last box fragment of the ancestor.

Note: If the ancestor breaks across a line,
the “start” position might more end-ward than the “end” position.

If no ancestor establishes one,
the absolute positioning containing block is
the initial containing block.

Note: Properties that can cause a box to establish
an absolute positioning containing block include position, transform, will-change, contain…

If the box has position: fixed:
The containing block is established
by the nearest ancestor box that establishes an fixed positioning containing block,
with the bounds of the containing block determined identically to the absolute positioning containing block.

Note: Properties that can cause a box to establish
a fixed positioning containing block include transform, will-change, contain…

If no ancestor establishes one,
the fixed positioning containing block is:

  • in continuous media,
    the viewport;
    as a result, fixed boxes do not move when the document is scrolled.

    Note: In this respect, they are similar to fixed background images (background-attachment: fixed).

  • in paged media,
    the page area of each page; fixed positioned boxes are thus replicated on every page.
    (They are fixed with respect to the page box only,
    and are not affected by being seen through a viewport;
    as in the case of print preview, for example.)

Note: As a result, parts of fixed-positioned boxes that extend outside the initial containing block/page area cannot be scrolled to
and will not print.

With no positioning, the containing blocks (C.B.) in the following document:

<!DOCTYPE html>
<html>
    <head>
        <title>Illustration of containing blocks</title>
    </head>
    <body id="body">
        <div id="div1">
        <p id="p1">This is text in the first paragraph...</p>
        <p id="p2">This is text <em id="em1"> in the
        <strong id="strong1">second</strong> paragraph.</em></p>
        </div>
    </body>
</html>

are established as follows:

For box generated by C.B. is established by
html initial C.B. (UA-dependent)
body html
div1 body
p1 div1
p2 div1
em1 p2
strong1 p2

If we position «div1»:

#div1 { position: absolute; left: 50px; top: 50px }

its containing block is no longer «body»; it becomes the initial containing block (since there are no other positioned ancestor boxes).

If we position «em1» as well:

#div1 { position: absolute; left: 50px; top: 50px }
#em1  { position: absolute; left: 100px; top: 100px }

the table of containing blocks becomes:

For box generated by C.B. is established by
html initial C.B. (UA-dependent)
body html
div1 initial C.B.
p1 div1
p2 div1
em1 div1
strong1 em1

By positioning «em1», its containing block becomes the nearest positioned ancestor box
(i.e., that generated by «div1»).

3. Positioning Coordinates

The precise location of a positioned box is controlled by
the inset properties:
the physical inset properties top, right, bottom, left;
the flow-relative inset properties inset-block-start, inset-inline-start, inset-block-end, and inset-inline-end;
and their shorthands, inset-block, inset-inline, and inset.

The interpretation of these inset properties varies by positioning scheme:

  • for absolute positioning, they represent
    insets from the containing block.

  • for relative positioning, they represent
    insets from the box’s original margin edge.

  • for sticky positioning, they represent
    insets from the scrollport edge.

3.1. Box Insets: the top, right, bottom, left, inset-block-start, inset-inline-start, inset-block-end, and inset-inline-end properties

Name: top, right, bottom, left, inset-block-start, inset-inline-start, inset-block-end, inset-inline-end
Value: auto | <length-percentage>
Initial: auto
Applies to: positioned elements
Inherited: no
Percentages: refer to size of containing block; see prose
Computed value: the keyword auto or a computed <length-percentage> value
Canonical order: per grammar
Animation type: by computed value type

These inset properties represent an inward “inset”
on the corresponding side of the box
(with respect to the box’s own writing mode;
see CSS Writing Modes 3 § 6 Abstract Box Terminology).
For example, top represents a downward inset of the top edge.
The physical and flow-relative properties
interact as defined in [CSS-LOGICAL-1].
Values have the following meanings:

<length>
The inset is a fixed distance from the reference edge.
Negative values are allowed.
<percentage>
The inset is a percentage
relative to the containing block’s size
in the corresponding axis
(e.g. width for left or right, height for top and bottom).
For sticky positioned boxes,
the inset is instead
relative to the relevant scrollport’s size.
Negative values are allowed.
auto
Represents an unconstrained inset;
the exact meaning depends on the positioning scheme.

Note: For fixed positioned elements,
using large values or negative values
can easily move elements outside the viewport and make the contents unreachable through scrolling or other means.

3.2. Box Insets Shorthands: the inset-block, inset-inline, and inset properties

Name: inset-block, inset-inline
Value: <top>{1,2}
Initial: auto
Applies to: positioned elements
Inherited: no
Percentages: see individual properties
Computed value: see individual properties
Canonical order: per grammar
Animation type: by computed value type

The inset-block and inset-inline properties are shorthand properties for setting inset-block-start + inset-block-end or inset-inline-start + inset-inline-end,
respectively,
in a single declaration.
The first component value sets the start side,
the second sets the end;
if omitted, the second value defaults to the first.

Name: inset
Value: <top>{1,4}
Initial: auto
Applies to: positioned elements
Inherited: no
Percentages: see individual properties
Computed value: see individual properties
Canonical order: per grammar
Animation type: by computed value type

The inset property is a shorthand property that sets all of the inset properties in a single declaration,
assigning values to the longhands representing each side
exactly as the margin property does for its longhands.

By default, the inset property values
are assigned to the corresponding physical longhand properties—top, right, bottom, and left—which for historical reasons do not have an inset- prefix.
This matches the behavior of other «4 values assigned to sides» properties,
such as margin.

Allowing properties such as this to resolve to the flow-relative longhands is under discussion in [CSS-LOGICAL-1].

Yes, we understand it’s a little confusing
that inset doesn’t expand to any inset-* properties.

3.3. Relative Positioning

For a relatively positioned box,
the inset properties move the box inward
from the respective edge,
without changing its size. left moves the box to the right, right moves it to the left, etc.
Since boxes are not split or stretched as a result of relative positioning opposing used values in a given axis must be negations of each other:

  • If opposing inset properties in an axis both compute to auto (their initial values),
    their used values are zero
    (i.e., the boxes stay in their original position in that axis).
  • If only one is auto,
    its used value becomes the negation of the other,
    and the box is shifted by the specified amount.
  • If neither is auto,
    the position is over-constrained;
    (with respect to the writing mode of its containing block)
    the computed end side value is ignored,
    and its used value becomes the negation of the start side.

The following three rules are equivalent,
and shift the box 1em to the left:

div.a8 { position: relative; direction: ltr; left: -1em; right: auto }
div.a8 { position: relative; direction: ltr; left: auto; right: 1em }
div.a8 { position: relative; direction: ltr; left: -1em; right: 5em }

If specified on
a table-row-group, table-header-group, table-footer-group, or table-row box the shift affects all the contents of the box,
including all table cells that originate in the affected row,
but not those that don’t.

Note: Since position does not apply to table-column-group or table-column boxes,
they are not affected by relative positioning.

3.4. Sticky positioning

Sticky positioning is similar to relative positioning except the offsets are automatically calculated
in reference to the nearest scrollport.

For a sticky positioned box,
the inset properties represent insets from the respective edges of the nearest scrollport,
defining the sticky view rectangle used to constrain the box’s position.
(For this purpose an auto value represents a zero inset.)
If this results in a sticky view rectangle size in any axis
less than the size of the border box of the sticky box in that axis,
then the effective end-edge inset in the affected axis is reduced
(possibly becoming negative)
to bring the sticky view rectangle’s size up to
the size of the border box in that axis
(where end is interpreted relative to the writing mode of the containing block).

For example,
if the nearest scrollport is 300px tall,
the sticky box’s border box is 200px tall,
and it has top: 20px,
then the top-edge inset of the nearest scrollport is 20px,
and the bottom-edge inset is 0px,
yielding a sticky view rectangle that is 280px tall.

But if the nearest scrollport were only 100px tall,
then the effective bottom-edge inset becomes -120px,
resulting in a sticky view rectangle that’s 200px tall,
enough to fully contain the margin box of the sticky box.

For each side of the box,
if the corresponding inset property is not auto,
and the corresponding border edge of the box would be outside
the corresponding edge of the sticky view rectangle,
then the box must be visually shifted
(as for relative positioning)
to be inward of that sticky view rectangle edge,
insofar as it can while its position box remains contained within its containing block.
The position box is its margin box,
except that for any side for which the distance between its margin edge and the corresponding edge of its containing block is less than its corresponding margin,
that distance is used in place of that margin.

Note: A sticky positioned element with
a non-auto top value and an auto bottom value
will only ever be pushed down by sticky positioning;
it will never be offset upwards.

Note: Multiple sticky positioned boxes in the same container
are offset independently,
and therefore might overlap.

3.4.1. Scroll Position of Sticky-Positioned Boxes

For the purposes of any operation targeting the scroll position
of a sticky positioned element (or one of its descendants),
the sticky positioned element must be considered to be positioned
at its initial (non-offsetted) position.

For example, if a user clicks a link targeting a sticky-positioned element,
even if the element’s nearest scrollport is currently scrolled
such that the sticky positioned element is offset from its initial position,
the scrollport will be scrolled back
so that the element’s initial position is visible.

3.5. Absolute (and Fixed) Positioning

For an absolutely positioned box,
the inset properties effectively reduce the containing block into which it is sized and positioned
by the specified amounts.

If only one inset property in a given axis is auto,
it is set to zero.
If both inset properties in a given axis are auto, then,
depending on the box’s self-alignment property in the relevant axis
(treating normal as start and any distributed, baseline, or stretch alignment value as its fallback alignment):

for self-start alignment or its equivalent
Set its start-edge inset property to the static position,
and its end-edge inset property to zero.
for self-end alignment or its equivalent
Set its end-edge inset property to the static position,
and its start-edge inset property to zero.
for center alignment
Let start distance be the distance from
the center of its static-position rectangle to the start edge of its containing block,
and end distance be the distance from
the center of its static-position rectangle to the end edge of its containing block.
If start distance is less than or equal to end distance,
then set the start-edge inset property to zero,
and set the end-edge inset property to
(containing block size — 2 × |start distance|);
otherwise,
set the end-edge inset property to zero
and the start-edge inset property to
(containing block size — 2 × |end distance|).

If these adjustments result in
an effective containing block size in any axis less than zero,
then the weaker inset in the affected axis
is reduced (possibly becoming negative)
to bring that size up to zero.
In the case that only one inset is auto,
that is the weaker inset;
otherwise the weaker inset is the inset of the end edge
(where end is interpreted relative to the writing mode of the containing block).

Note: Sizing and positioning of the absolutely positioned box into this inset-modified containing block is as described in § 4 Absolute Positioning Layout Model.

If its self-alignment property in an axis is normal,
then the resolved value of its weaker inset in that axis
is the value necessary to match that edge of its inset-modified containing block to the corresponding edge of its margin box after layout.
(Otherwise the resolved value is the used value described above.)

3.5.1. Resolving Automatic Insets: the “Static Position Rectangle”

When both inset properties in a given axis are auto,
they are resolved into a static position by aligning the box into its static-position rectangle,
an alignment container derived
from the formatting context the box would have participated in
if it were position: static (independent of its actual containing block).
The static position represents
an approximation of the position the box would have had
if it were position: static.

Block Layout
The static positions of a block-level box are defined in [CSS2] Chapter 10.
The static-position rectangle is a zero-thickness rectangle spanning between
the inline-axis sides of the box’s static-position containing block (see CSS2§10.3.7);
and positioned at its block-start static position (see CSS2§10.6.4).

Note: In block layout the static-position rectangle corresponds to the position of the “hypothetical box”
described in CSS2.1§10.3.7.
Since it has no alignment properties,
CSS2.1 always uses a block-start inline-start alignment
of the absolutely-positioned box within the static-position rectangle.

Inline Layout
The static positions of an inline-level box are defined in [CSS2] Chapter 10.
The static-position rectangle is a zero-thickness rectangle spanning between
the line-over/line-under sides of the line box that would have contained its “hypothetical box”
(see CSS2§10.3.7);
and positioned at its inline-start static position.
Flex Layout
The static-position rectangle of the child of a flex container corresponds to the content edges of the flex container.
See static position of a grid container child in [CSS-FLEXBOX-1].
Grid Layout
By default, the static-position rectangle of the child of a grid container corresponds to the content edges of the grid container.
However, if that grid container also establishes
the box’s actual containing block,
then the grid area specified by the grid-placement properties establishes its static-position rectangle instead.
See the static position of a grid container child in [CSS-GRID-1].

Finding the static position and the static position rectangle assumes that both float and clear have their initial values,
and can require assuming a different hypothetical value
for display as well.
Additionally, the containing block of fixed positioned elements
is assumed to be the initial containing block instead of the viewport,
and all scroll containers should be assumed
to be scrolled to their initial scroll position.
Lastly, all auto margins on the box itself
are treated as zero.

3.5.2. Fragmenting Absolutely-positioned Elements

In a fragmented flow, an absolutely positioned box is positioned relative to its containing block ignoring any fragmentation breaks (as if the flow were continuous).
The box may subsequently be broken over several fragmentation containers.

For absolutely positioned content in paged media that resolves to a position on a page
other than the page being laid out (the current page),
or resolves to a position on the current page
that has already been rendered for printing,
printers may place the content:

  • on the current page,
  • on a subsequent page, or
  • may omit it altogether.

Note: A block-level element that is split over several pages
can have a different width on each page,
and there may be device-specific limits.

User agents must not paginate the content of fixed-positioned boxes.

Note: User agents might print invisible content in other ways.
See CSS Paged Media 3 § 3.2 Content outside the page box.

4. Absolute Positioning Layout Model

Absolute positioning not only takes a box out of flow,
but also lays it out in its containing block (after the final size of the containing block has been determined)
according to the absolute positioning layout model:

  1. First, its inset-modified containing block is calculated,
    defining its available space.
    (See § 3.5 Absolute (and Fixed) Positioning.)
    Because an absolutely positioned box can have no effect on the size of its containing block,
    its available space is always definite.
  2. Next, its width and height are resolved against this definite available space,
    as its preferred size capped by its maximum size (if any), floored by its minimum size.
    See § 4.1 Automatic Sizes of Absolutely-Positioned Boxes.
    Percentages, however,
    are resolved against the original containing block size.
  3. Then, the value of any auto margins are calculated,
    see § 4.2 Auto Margins of Absolutely-Positioned Boxes.
  4. Lastly, its margin box is aligned within the inset-modified containing block as defined by its self-alignment properties.

4.1. Automatic Sizes of Absolutely-Positioned Boxes

The automatic size of an absolutely positioned box is resolved against its inset-modified containing block as follows
(treating auto margins as zero):

If its self-alignment property in the relevant axis is stretch
Or if it is normal and the box is non-replaced,
not a table wrapper box,
and has no auto inset in the relevant axis

Its automatic size is its stretch-fit size.

Otherwise

Its automatic size is its fit-content size.

However, if the box has an aspect-ratio,
then an automatic size in the ratio-dependent axis is instead resolved as a max-content size.
When both axes have an automatic size,
if only one axis has an auto inset then that axis is the ratio-dependent axis,
else the block axis is the ratio-dependent axis.
An automatic size in the ratio-determining axis is determined as above.

The automatic minimum size of an absolutely-positioned box is always zero.

4.2. Auto Margins of Absolutely-Positioned Boxes

If either inset property in the relevant axis is auto,
then any auto margins resolve to zero.

Otherwise, the remaining space is calculated
as the size of its inset-modified containing block in the relevant axis
minus the box’s used size in the relevant axis,
and this remaining space is divided among
any auto margins in the relevant axis.
However,
(all with respect to the writing mode of the containing block),
if in the inline axis the remaining space is negative
and both margins are auto,
the start margin resolves to zero
and the end margin receives the remaining space.

5. Old Absolute Positioning Layout Model

This section is being replaced with the new § 4 Absolute Positioning Layout Model section.
It is preserved here for comparison:
both models should yield the same result
in horizontal writing modes when the box’s self-alignment is normal.

5.1. The Width of Absolutely-Positioned, Non-Replaced Elements

The constraint that determines the used values for these elements is:

left + margin-left + border-left-width + padding-left + width + padding-right + border-right-width + margin-right + right = width of containing block

If all three of left, width, and right are auto:
First set any auto values for margin-left and margin-right to 0.
Then, if the direction property of
the element establishing the static-position containing block is ltr set left to the static position
and apply rule number three below;
otherwise, set right to the static-position
and apply rule number one below.

If none of the three is auto:
If both margin-left and margin-right are auto,
solve the equation under the extra constraint that
the two margins get equal values,
unless this would make them negative,
in which case when direction of the containing block is ltr (rtl),
set margin-left (margin-right) to 0 and solve for margin-right (margin-left).
If one of margin-left or margin-right is auto,
solve the equation for that value.
If the values are over-constrained,
ignore the value for left (in case the direction property of the containing block is rtl)
or right (in case direction is ltr) and solve for that value.

Otherwise,
set auto values for margin-left and margin-right to 0,
and pick one of the following six rules that apply.

  1. If left and width are auto and right is not auto,
    then the width is shrink-to-fit.
    Then solve for left.
  2. If left and right are auto and width is not auto,
    then if the direction property of
    the element establishing the static-position containing block is ltr set left to the static-position,
    otherwise set right to the static-position.
    Then solve for left (if direction is rtl)
    or right (if direction is ltr).
  3. If width and right are auto and left is not auto,
    then the width is shrink-to-fit.
    Then solve for right.
  4. If left is auto, width and right are not auto,
    then solve for left.
  5. If width is auto, left and right are not auto,
    then solve for width.
  6. If right is auto, left and width are not auto,
    then solve for right.
Summary of rules for dir=ltr in horizontal writing modes

Is auto? Result
left width right margin-left margin-right
any
  • auto margins → zero
  • left → static pos
  • width → shrink-to-fit
  • right → solve
auto margin → free space
  • margins split positive free space
  • right margin gets negative free space
treat right as auto
any
  • auto margins → zero
  • left → static pos
  • width → as specified
  • right → solve
any
  • auto margins → zero
  • left → solve
  • width → shrink-to-fit
  • right → as specified
any
  • auto margins → zero
  • left → as specified
  • width → shrink-to-fit
  • right → solve
any
  • auto margins → zero
  • solve for auto

5.2. The width of absolute or fixed positioned, replaced elements

If height and width both have computed values of auto and the element also has an intrinsic width,
then that intrinsic width is the used value of width.

If height and width both have computed values of auto and the element has no intrinsic width,
but does have an intrinsic height and intrinsic ratio;
or if width has a computed value of auto, height has some other computed value,
and the element does have an intrinsic ratio;
then the used value of width is:

(used height) * (intrinsic ratio)

If height and width both have computed values of auto,
the element has an intrinsic ratio but no intrinsic height or width,
and the containing block’s width
does not itself depend on the replaced element’s width,
then the used value of width is calculated
from the constraint equation used for block-level, non-replaced elements in normal flow.

Otherwise, if width has a computed value of auto,
and the element has an intrinsic width,
then that intrinsic width is the used value of width.

Otherwise, if width has a computed value of auto,
but none of the conditions above are met,
and then the used value of width becomes 300px.
If 300px is too wide to fit the device,
user agents should use the width of the largest rectangle
that has a 2:1 ratio and fits the device instead.

After establishing the width,
in order to position the replaced element,
apply the following rules as appropriate.

  1. If both left and right have the value auto,
    and if the direction property of
    the element establishing the static-position containing block is ltr,
    set left to the static position and solve for right;
    else if direction is rtl,
    set right to the static position and solve for left.
  2. If left is auto and right is not auto,
    replace any auto on margin-left or margin-right with 0,
    then solve for left.
  3. If right is auto and left is not auto,
    replace any auto on margin-left or margin-right with 0,
    then solve for right.
  4. If at this point both margin-left and margin-right are still auto,
    solve the equation under the extra constraint
    that the two margins must get equal values,
    unless this would make them negative,
    in which case when the direction of the containing block is ltr (rtl),
    set margin-left (margin-right) to 0 and solve for margin-right (margin-left).
  5. If at this point there is an auto remaining,
    solve the equation for that value.
  6. If at this point the values are over-constrained,
    ignore the value for either left (in case the direction property of the containing block is rtl)
    or right (in case direction is ltr)
    and solve for that value.

5.3. The Height Of Absolutely Positioned, Non-Replaced Elements

For absolutely positioned elements,
the used values of the vertical dimensions
must satisfy this constraint:

top + margin-top + border-top-width + padding-top + height + padding-bottom + border-bottom-width + margin-bottom + bottom = height of containing block

If all three of top, height, and bottom are auto:
First set any auto values for margin-top and margin-bottom to 0,
then set top to the static position,
and finally apply rule number three below.

If none of the three are auto:
If both margin-top and margin-bottom are auto,
solve the equation under the extra constraint that the two margins get equal values.
If one of margin-top or margin-bottom is auto,
solve the equation for that value.
If the values are over-constrained,
ignore the value for bottom and solve for that value.

Otherwise,
set auto values for margin-top and margin-bottom to 0,
and pick one of the following six rules that apply.

  1. If top and height are auto and bottom is not auto,
    then the height is based on the Auto heights for block formatting context roots,
    and solve for top.

  2. If top and bottom are auto and height is not auto,
    then set top to the static position,
    then solve for bottom.

  3. If height and bottom are auto and top is not auto,
    then the height is based on the Auto heights for block formatting context roots,
    and solve for bottom.

  4. If top is auto, height and bottom are not auto,
    then solve for top.

  5. If height is auto, top and bottom are not auto,
    then solve for height.

  6. If bottom is auto, top and height are not auto,
    then solve for bottom.

5.4. The Height Of Absolutely Positioned, Replaced Elements

If height and width both have computed values of auto and the element also has an intrinsic height,
then that intrinsic height is the used value of height.

Otherwise, if height has a computed value of auto and the element has an intrinsic ratio
then the used value of height is:

(used width) / (intrinsic ratio)

Otherwise, if height has a computed value of auto and the element has an intrinsic height,
then that intrinsic height is the used value of height.

Otherwise, if height has a computed value of auto,
but none of the conditions above are met,
then the used value of height must be set to
the height of the largest rectangle that has a 2:1 ratio,
has a height not greater than 150px,
and has a width not greater than the device width.

After establishing the height,
in order to position the replaced element,
apply the following rules as appropriate.

  1. If both top and bottom have the value auto,
    replace top with the element’s static position.

  2. If bottom is auto,
    replace any auto on margin-top or margin-bottom with 0.

  3. If at this point both margin-top and margin-bottom are still auto,
    solve the equation under the extra constraint
    that the two margins must get equal values.

  4. If at this point there is only one auto remaining,
    solve the equation for that value.

  5. If at this point the values are over-constrained,
    ignore the value for bottom and solve for that value.

6. Informative Comparison of Normal Flow, Floats, and Positioning

This section is not normative.

To illustrate the differences between normal flow, relative positioning, floats, and absolute positioning,
we provide a series of examples based on the following HTML:

<!DOCTYPE html>
<html>
    <head>
        <title>Comparison of positioning schemes</title>
        <style>
          body { display: block; font-size:12px; line-height: 200%;
                  width: 400px; height: 400px }
          p    { display: block }
          span { display: inline }
        </style>
    </head>
    <body>
    <p>
        Beginning of p contents.
        <span id="outer"> Start of outer contents.
        <span id="inner"> Inner contents.</span>
        End of outer contents.</span>
        End of p contents.
    </p>
    </body>
</html>

The final positions of boxes generated by the outer and inner elements vary in each example. In each illustration, the numbers to the left of
the illustration indicate the normal flow position of the
double-spaced (for clarity) lines.

Note: The diagrams in this section are illustrative and not to scale. They are
meant to highlight the differences between the various positioning
schemes, and are not intended to be reference renderings of the
examples given.

6.1. Normal Flow Example

Consider the following CSS declarations for outer and inner that do not alter the normal flow of boxes:

#outer { color: red }
#inner { color: blue }

The P element contains all inline content: anonymous inline text and
two SPAN elements. Therefore, all of the content will be laid out in an inline
formatting context, within a containing block established by the P element, producing
something like:

Image illustrating the normal flow of text between parent and sibling boxes.

All of the text within the P’s containing block flows together as continuous text,
even though it’s located in separated nested elements.

6.2. Relative Positioning Example

To see the effect of relative positioning,
we specify:

#outer { position: relative; top: -12px; color: red }
#inner { position: relative; top: 12px; color: blue }

Text flows normally up to the outer element. The outer text is
then flowed into its normal flow position and dimensions at the end of line 1. Then,
the inline boxes containing the text (distributed over three lines) are shifted as a
unit by -12px (upwards).

The contents of inner, as a child of outer, would normally flow
immediately after the words «of outer contents» (on line 1.5). However, the inner contents are themselves offset relative to the outer contents by 12px (downwards), back to their original position on line 2.

Note that the content following outer is not affected by the relative
positioning of outer.

The result is identical to normal flow,
except that the «outer» text is shifted 12px upward,
without affecting the flow of the «body» or «inner» text.

Note also that had the offset of outer been -24px, the text of outer and the body text would have overlapped.

6.3. Floating Example

Now consider the effect of floating the inner element’s text to the right by means of the
following rules:

#outer { color: red }
#inner { float: right; width: 130px; color: blue }

Text flows normally up to the inner box, which is pulled out of the flow
and floated to the right margin (its width has been
assigned explicitly). Line boxes to the left of the float are shortened, and the
document’s remaining text flows into them.

Image illustrating the effects of floating a box.

The «inner» text lays out in an independent box on the right,
causing the remaining «body» and «outer» text to flow around it.

To show the effect of the clear property, we add a sibling element to the
example:

<!DOCTYPE html>
<html>
    <head>
        <title>Comparison of positioning schemes II</title>
        <style>
          #inner { float: right; width: 130px; color: blue }
          #sibling { color: red }
        </style>
    </head>
    <body>
    <p>
        Beginning of p contents.
        <span id="outer"> Start of outer contents.
        <span id="inner"> Inner contents.</span>
        <span id="sibling"> Sibling contents.</span>
        End of outer contents.</span>
        End of p contents.
    </p>
    </body>
</html>

These styles cause the inner box to float to the right, as before,
and the document’s remaining text to flow into the vacated space:

Image illustrating the effects of floating a box without setting the clear property to control the flow of text around the box.

Identical to the previous example,
save that there is now «sibling» text
flowing with the «body» and «outer» text.

However, if the clear property on the sibling element is set to right (i.e., the generated sibling box will not accept a position next to floating boxes to its right), the sibling content begins to flow below the
float:

#inner { float: right; width: 130px; color: blue }
#sibling { clear: right; color: red }

Image illustrating the effects of floating an element with setting the clear property to control the flow of text around the element.

Now the «sibling» text moves down to below the «inner» text’s box,
leaving blank space behind.
The text following the «sibling» text flows after it as normal.

6.4. Absolute Positioning Example

Next, we consider the effect of absolute positioning. Consider the following CSS
declarations for outer and inner:

#outer {
    position: absolute;
    top: 200px; left: 200px;
    width: 200px;
    color: red;
}
#inner { color: blue }

which cause the top of the outer box to be positioned with respect to its containing block. The containing block for a positioned box is established by the
nearest positioned ancestor (or, if none exists, the initial containing block, as in
our example). The top side of the outer box is 200px below the top of the containing block and the left side is 200px from the left side. The child box of outer is flowed normally with respect to its parent.

Image illustrating the effects of absolutely positioning a box.

All of the text within #outer (the «outer» and «inner» text)
moves down to an independent box in the lower right corner.
The two halves of «body» text flow together.

The following example shows an absolutely positioned box that is a child of a relatively
positioned box. Although the parent outer box is not actually offset, setting
its position property to relative means that its box may serve as the containing
block for positioned descendants. Since the outer box is an inline box that is
split across several lines, the first inline box’s top and left edges (depicted by thick
dashed lines in the illustration below) serve as references for top and left offsets.

#outer {
    position: relative;
    color: red
}
#inner {
    position: absolute;
    top: 200px; left: -100px;
    height: 130px; width: 130px;
    color: blue;
}

This results in something like the following:

Image illustrating the effects of absolutely positioning a box with respect to a containing block.

The «inner» text is positioned in an independent box,
relative to the top-left corner of the start of the «outer» text.

If we do not position the outer box:

#outer { color: red }
#inner {
    position: absolute;
    top: 200px; left: -100px;
    height: 130px; width: 130px;
    color: blue;
}

the containing block for inner becomes the initial
containing block
(in our example). The following illustration shows where
the inner box would end up in this case.

Image illustrating the effects of absolutely positioning a box with respect to a containing block established by a normally positioned parent.

Same as before,
except now the «inner text» is positioned relative to the top-left corner of the page itself.

Relative and absolute positioning may be used to implement change bars, as shown
in the following example. The following fragment:

<p style="position: relative; margin-right: 10px; left: 10px;">
  I used two red hyphens to serve as a change bar. They
  will "float" to the left of the line containing THIS
  <span style="position: absolute; top: auto; left: -1em; color: red;">--</span>
  word.
</p>

might result in something like:

Image illustrating the use of floats to create a changebar effect.

The two red hyphens, indicating a change,
sit in the left margin of the page
on the line containing the word «THIS»,
regardless of what line that ends up being.

First, the paragraph (whose containing block sides are shown in the
illustration) is flowed normally. Then it is offset 10px from the left edge
of the containing block (thus, a right margin of 10px has been
reserved in anticipation of the offset). The two hyphens acting as change bars
are taken out of the flow and positioned at the current line (due to ‘top: auto’), -1em from the left edge of its containing block (established by the P in
its final position). The result is that the change bars seem to «float» to the
left of the current line.

7. Acknowledgments

This module would not have been possible without input and support from many
helpful people. Thanks to
Rossen Atanassov,
Bert Bos,
Oriol Brufau,
Tantek Çelik,
Arron Eicholz
Sylvain Galineau,
John Jansen,
Chris Jones,
Ian Kilpatrick,
Anton Prowse.

Changes

The following significant changes were made since the 16 Decemer 2021 Working Draft:

  • Fixed conceptual definitions of static position and static position rectangle to be consistent with their actual usage.
  • Explicitly defined that absolute positioning forces the box
    to establish an independent formatting context (as previously noted in [CSS-DISPLAY-3]).
    (Issue 7124)

The following significant changes were made since the 19 May 2020 Working Draft:

  • Defined automatic sizing of non-replaced absolutely-positioned boxes with an aspect ratio.
    (Issue 5151

    However, if the box has an aspect-ratio,
    then an automatic size in the ratio-dependent axis is instead resolved as a max-content size.
    When both axes have an automatic size,
    if only one axis has an auto inset
    then that axis is the ratio-dependent axis,
    else the block axis is the ratio-dependent axis.
    An automatic size in the ratio-determining axis is determined as above.

  • Aligned resolution of auto margins and automatic sizes of positioned boxes with [CSS2].
    (Issue 5374, Issue 5077, Issue 5327)

    If this results in a sticky view rectangle size in any axis
    less than the size of the border box of the sticky box in that axis,
    then the effective end-edge inset in the affected axis is reduced
    (possibly becoming negative)
    to bring the sticky view rectangle’s size up to
    the size of the border box in that axis
    (where end is interpreted relative to the writing mode of the containing block)
    .

    If neither is auto,
    the position is over-constrained;
    (with respect to the writing mode of its containing block)
    the computed end side value is ignored,
    and its used value becomes the negation of the start side.

    However,
    (all with respect to the writing mode of the containing block),
    if in the inline axis
    the remaining space is negative
    and both margins are auto,
    the start margin resolves to zero
    and the end margin receives the remaining space.

    If its self-alignment property in the relevant axis is stretch
    Or if it is normal and the box is non-replaced
    and has no auto inset in the relevant axis

    Its automatic size is its stretch-fit size.

The following significant changes were made since the 17 May 2016 Working Draft:

  • Rewrote the whole spec for editorial clarity, technical precision, and compatibility with [CSS-ALIGN-3], [CSS-WRITING-MODES-3], [CSS-BREAK-3], and [CSS-DISPLAY-3].

Privacy and Security Considerations

This specification introduces no new privacy considerations.

If an attacker is able to inject arbitrary CSS,
positioned layout can make it easier to position elements the attacker has control of
over arbitrary other elements of the page,
potentially tricking users of the page.
(There are many routes to this attack: negative margin, transform, etc.
Don’t let people apply arbitrary CSS to bits of your page.)

position: fixed can allow a page to emulate modal dialogs,
potentially tricking a user into thinking they’re interacting with the user agent
and entering in sensitive information that they page can then capture.
User agents must ensure that their native dialogs are positioned
in ways that the page cannot emulate;
in particular,
that at least some of the dialog is outside the «poisoned pixels» that web content can paint to.

Conformance requirements are expressed with a combination of
descriptive assertions and RFC 2119 terminology. The key words “MUST”,
“MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”,
“RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this
document are to be interpreted as described in RFC 2119.
However, for readability, these words do not appear in all uppercase
letters in this specification.

All of the text of this specification is normative except sections
explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example”
or are set apart from the normative text with class="example",
like this:

Informative notes begin with the word “Note” and are set apart from the
normative text with class="note", like this:

Note, this is an informative note.

Advisements are normative sections styled to evoke special attention and are
set apart from other normative text with <strong class="advisement">, like
this: UAs MUST provide an accessible alternative.

A style sheet is conformant to this specification
if all of its statements that use syntax defined in this module are valid
according to the generic CSS grammar and the individual grammars of each
feature defined in this module.

A renderer is conformant to this specification
if, in addition to interpreting the style sheet as defined by the
appropriate specifications, it supports all the features defined
by this specification by parsing them correctly
and rendering the document accordingly. However, the inability of a
UA to correctly render a document due to limitations of the device
does not make the UA non-conformant. (For example, a UA is not
required to render color on a monochrome monitor.)

An authoring tool is conformant to this specification
if it writes style sheets that are syntactically correct according to the
generic CSS grammar and the individual grammars of each feature in
this module, and meet all other conformance requirements of style sheets
as described in this module.

So that authors can exploit the forward-compatible parsing rules to
assign fallback values, CSS renderers must treat as invalid (and ignore
as appropriate) any at-rules, properties, property values, keywords,
and other syntactic constructs for which they have no usable level of
support. In particular, user agents must not selectively
ignore unsupported component values and honor supported values in a single
multi-value property declaration: if any value is considered invalid
(as unsupported values must be), CSS requires that the entire declaration
be ignored.

Once a specification reaches the Candidate Recommendation stage,
non-experimental implementations are possible, and implementors should
release an unprefixed implementation of any CR-level feature they
can demonstrate to be correctly implemented according to spec.

To establish and maintain the interoperability of CSS across
implementations, the CSS Working Group requests that non-experimental
CSS renderers submit an implementation report (and, if necessary, the
testcases used for that implementation report) to the W3C before
releasing an unprefixed implementation of any CSS features. Testcases
submitted to W3C are subject to review and correction by the CSS
Working Group.

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

  • Преимущества верстки с помощью тега <div>
    • Средства позиционирования
    • Центрирование слоев
    • Как из слоя сделать ссылку
    • Скрытие и отображение блочных элементов

Существует два основных типа построения структуры сайта:

  • Табличная;
  • Блочная.

Табличная верстка была доминирующей еще на заре зарождения интернета. К ее преимуществам можно отнести точность заданного позиционирования. Но, тем не менее, она обладает явными недостатками. Главными из них является объемность кода и низкая скорость загрузки.

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

Кроме высокой скорости загрузки блочное построение сайта позволяет в несколько раз уменьшить объем кода html. В том числе и за счет использования классов CSS.

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

Блочное построение на основе тегов <div> также называют послойным, а сами блоки слоями. Это связано с тем, что при использовании определенных значений свойств их можно размещать один поверх другого подобно слоям в Photoshop.

В блочной верстке позиционирование слоев лучше осуществлять с помощью средств каскадных таблиц стилей. Основным свойством CSS, отвечающим за расположение <div>, является float.
Синтаксис свойства:
float: left | right | none | inherit,
Где:

  • left – выравнивание элемента по левому краю экрана. Обтекание остальными элементами происходит справа;
  • right – выравнивание справа, обтекание остальными элементами – слева;
  • none – обтекание не допускается;
  • inherit – наследование значения родительского элемента.

Рассмотрим облегченный пример позиционирования блоков div с помощью этого свойства:

<style type="text/css">
#left {
    width: 200px;
height: 100px;
    float: left; 
    background: rgb(255,51,102);  
   }
#right { 
    width: 200px;
height: 100px;
    float: right;  
    background: rgb(0,255,153);  
   } 
 </style>
 </head>
<body>
<div id="left">
<h1>Левый блок</h1>
</div>
<div id="right">
<h1>Правый блок</h1>
</div>
</body>

Средства позиционирования

Теперь постараемся с помощью этого же свойства расположить третий div по центру страницы. Но, к сожалению, у float нет значения center. А при задании новому блоку значения выравнивания вправо или влево он сдвигается в указанную сторону. Поэтому остается лишь всем трем блокам задать float: left:

Средства позиционирования - 2

Но и это не является оптимальным вариантом. При уменьшении окна все слои выстраиваются в один ряд по вертикали, а при увеличении размеров – прилипают к левому краю окна. Поэтому нужен более совершенный способ выравнивание div по центру.

В следующем примере мы будем использовать слой-контейнер, в котором разместим остальные элементы. Это решает проблему смещения блоков друг относительно друга при изменении размеров окна. Центрирование контейнера посредине осуществляется с помощью задания свойствам margin нулевого значения отступам от верхнего края и auto по бокам (margin: 0 auto):

<style type="text/css">
#container {
    width: 600px;
    margin: 0 auto;
}
#left {
    width: 200px;
	height: 100px;
    float: left; 
    background: rgb(255,51,102);  
   }
#right { 
    width: 200px;
	height: 100px;
    float: left;  
    background: rgb(0,255,153);  
   } 
#center { 
    width: 200px;
	height: 100px;
    float: left;
    background: rgb(255,0,0);  
   } 
   </style>
 </head>
<body>
<div id="container">
<div id="left">
<h1>Левый блок</h1>
</div>
<div id="center">
<h1>Центральный блок</h1>
</div>
<div id="right">
<h1>Правый блок</h1>
</div>
</div>
</body>

Центрирование слоев

Этот же пример показывает, как можно отцентровать div по горизонтали. А если немного отредактировать приведенный выше код, то можно добиться вертикального выравнивания блоков. Для этого нужно лишь изменить длину слоя-контейнера (уменьшить его). То есть после редактирования его css класс должен выглядеть вот так:

#container {
    width: 200px;
    margin: 0 auto;
}

После изменения все блоки выстроятся строго в ряд посредине. И их положение не изменится при любых размерах окна браузера. Вот как выглядит такое центрирование div по центру по вертикали:

Центрирование слоев - 2

В следующем примере для центрирования слоев внутри контейнера мы использовали ряд новых свойств css:

<style type="text/css">
#container {
    width: 450px;
	height:150px;
	margin:0 auto;
	background-color:#66CCFF;
	}
#left {
	width: 100px;
	height: 100px;
    background: rgb(255,51,102);
	display: inline-block;
    vertical-align: middle;
	margin-left: 35px;
	 }
#right { 
width: 100px;
	height: 100px;
    background: rgb(0,255,153);
	display: inline-block;
    vertical-align: middle;
	margin-left: 35px;
	} 
#center {
    width: 100px;
	height: 100px;
    background: rgb(255,0,0);
	display: inline-block;
    vertical-align: middle;
	margin-left: 35px;
	} 
</style>

Краткое описание свойств css и их значений, которые мы использовали в данном примере для центрирования div внутри div:

  • display: inline-block – выравнивает блочный элемент в строку и обеспечивает его обтекание другим элементом;
  • vertical-align: middle – выравнивает элемент посредине относительно родительского;
  • margin-left – устанавливает отступ слева.

Как ни странно звучит, но такое возможно. Иногда div блок как ссылка может понадобиться при верстке различных видов меню. Рассмотрим практический пример реализации слоя-ссылки:

<style type="text/css">
#layer1{
width: 500px; 
height: 100px; 
background: rgb(51,255,204);
border:groove;
}
a {
display: block; 
text-align: center; 
height: 100%;
color: rgb(255,0,51);
}
</style>
</head>
<body>
<div id="layer1">
<a href="https://www.internet-technologies.ru">Ссылка на наш сайт</a>
 </div>
</body>

Как из слоя сделать ссылку

В данном примере с помощью строки display: block мы задали ссылке значение блочного элемента. А чтобы вся высота блока div стала ссылкой, установили height: 100%.

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

Особенно это касается главной страницы, стоимость размещения рекламы на которой является самой высокой. Поэтому и появляется проблема, куда бы «впихнуть» еще один рекламный баннер. И тут уж выравниванием div по центру страницы никак не отделаешься!

Более рациональным решением является сделать какой-нибудь блок скрывающимся. Вот простой пример такой реализации:

<style type="text/css">
#layer1{
	display:block;
    width: 500px; 
     height: 100px; 
     background: rgb(51,255,204);
     border:groove;
}
</style>
<script type="text/javascript">
function show()
{
     if(layer1=="none")
    {
        layer1="block";
      }
    else
    {
        layer1="none";
  }
 document.getElementById("layer1").style.display=layer1;
    }
</script>
 </head>
 <body>
 <input type="button" onclick="show()" value="Волшебная кнопка"/>
<div id="layer1">
 <p>Это волшебная кнопка. Нажатие на нее скроет или отобразит скрывающийся блок.</p>   
 </div>
 </body>

Скрытие и отображение блочных элементов

В данном примере расположение div блоков никак не меняется. Здесь используется простейшая функция JavaScript, меняющая значение свойства css display после нажатия на кнопку (событие onclick).

Синтаксис display:
display: block | inline | inline-block | inline-table | list-item | none | run-in | table | table-caption | table-cell | table-column-group | table-column | table-footer-group | table-header-group | table-row | table-row-group

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

Для скрытия и показа слоя мы использовали два значения свойства display:

  • none – временно удаляет блочный элемент со страницы;
  • block – показывает элемент как блочный.

Еще одним средством css, позволяющим скрывать и показывать элемент, является свойство visibility. Но оно обладает большим недостатком.

Свойство visibility позволяет лишь скрыть элемент. Но практически он присутствует на странице. Поэтому расположить на его месте другой элемент не получится. В то время как свойство display полностью удаляет (на время) элемент и позволяет располагать на его месте другие блочные структуры.

Мы с вами рассмотрели все основные слои настоящего сайта. Надеемся, что полученные знания позволят вам «испечь» по-настоящему вкусный ресурс.

Like this post? Please share to your friends:
  • Как изменить половую ориентацию
  • Как изменить половую конституцию
  • Как изменить половое влечение
  • Как изменить полностью стим
  • Как изменить полностью интерфейс телефона