2.3. CSS позиционирование

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

Позиционирование и свободное перемещение элементов

1. Типы позиционирования

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

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

Если для относительно позиционированного элемента одновременно задать свойства top и bottom или left и right, то в первом случае сработает только top, во втором — left.

absolute Абсолютно позиционированный элемент полностью удаляется из потока документа и позиционируется относительно его блока-контейнера (другого элемента или окна браузера). Блок-контейнер для абсолютно позиционированного элемента — ближайший элемент-предок, значение свойства position которого не равно static.

Местоположение краёв элемента определяется с помощью свойств смещения. Пространство, которое занимал такой элемент, схлопывается, как будто элемента не существовало на странице. Абсолютно позиционированный элемент может перекрывать другие элементы или быть перекрытым ими (за счёт свойства z-index). Любой абсолютно позиционированный элемент генерирует блок, то есть принимает значение display: block;.

fixed Фиксирует элемент в нужном месте страницы. Блоком-контейнером фиксированного элемента является окно просмотра, при этом элемент полностью удаляется из потока документа.
initial Устанавливает значение свойства в значение по умолчанию.
inherit Наследует значение свойства от родительского элемента.
static-relative-absolute

Рис. 1. Разница между статичным, относительным и абсолютным позиционированием

2. Свойства смещения

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

top, right, bottom, left
Значение:
auto Значение по умолчанию. Вычисляемое значение свойства равно нулю.
длина Смещение задаётся в единицах длины.
% Процентные значения вычисляются относительно высоты блока-контейнера для top и bottom и ширины блока-контейнера для right и left.
initial Устанавливает значение свойства в значение по умолчанию.
inherit Наследует значение свойства от родительского элемента.

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

3. Позиционирование внутри элемента

Для блока-контейнера абсолютно позиционированного элемента задаётся свойство position: relative без смещений. Это позволяет позиционировать элементы внутри элемента-контейнера.

Разметка HTML

CSS-стили

relative-absolute

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

4. Проблемы позиционирования

1. Если ширине или высоте абсолютно позиционированного элемента присвоено значение auto, то её значение будет определяться шириной или высотой содержимого элемента. Если ширина или высота объявлена явно, то именно это значение и будет присвоено.
2. Если внутри блока с position: absolute расположены элементы, для которых задано обтекание float, то высота этого элемента будет равна высоте самого высокого из этих элементов.
3. Для элемента с position: absolute нельзя одновременно устанавливать свойство float, а для элемента с position: relative — можно.
4. Если предок позиционированного элемента является блочным элементом, то блок-контейнер формируется областью содержимого, ограниченной рамкой (border). Если предок — строковый элемент, блок-контейнер формируется внешней границей его содержимого. Если предка нет, блоком-контейнером является элемент body.

5. Свободное перемещение элементов

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

float

Рис. 3. Свободное перемещение элементов

Плавающий блок принимает размеры своего содержимого с учетом внутренних отступов и рамок. Верхние и нижние отступы margin плавающих элементов не схлопываются. Свойство float применяется как к блочным элементам, так и к строчным элементам.

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

Свойство автоматически изменяет вычисляемое (отображаемое в браузере) значение свойства display на display: block для следующих значений: inline, inline-block, table-row, table-row-group, table-column, table-column-group, table-cell, table-caption, table-header-group, table-footer-group. Значение inline-table меняет на table.

Свойство не оказывает никакого влияния на элементы с display: flex и display: inline-flex.

float
Значение:
none Значение по умолчанию. Также отменяет любое перемещение для элемента из группы элементов, для которых уже установлено обтекание.
left Элемент изымается из нормального потока элементов и позиционируется по левому краю блока-контейнера.
right Элемент позиционируется по правому краю блока-контейнера.
initial Устанавливает значение свойства в значение по умолчанию.
inherit Наследует значение свойства от родительского элемента.

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

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

6. Отмена обтекания элементов

6.1. Свойство clear

Свойство clear определяет, как будет располагаться элемент, идущий следом за плавающим элементом. Свойство отменяет обтекание с одной или обоих сторон элемента, установленное свойством float. Для предотвращения отображение фона или границ под плавающими элементами используется правило {overflow: hidden;}.

clear
Значение:
left Отменяет обтекание по левой стороне, смещая элемент вниз. Правое обтекание остается в силе.
right Отменяет обтекание по правой стороне, смещая элемент вниз. Левое обтекание остается в силе.
both Отменяет обтекание с обеих сторон элемента, смещая его вниз.
none Значение по умолчанию. Также отменяет очистку обтекания, установленное для элементов одной группы.
initial Устанавливает значение свойства в значение по умолчанию.
inherit Наследует значение свойства от родительского элемента.

6.2. Очистка потока стилями при помощи класса clearfix и псевдокласса :after

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

Разметка HTML

CSS-стили

float1

Рис. 4. "Эффект схлопывания" блока-контейнера

Решение проблемы:
Создаем класс .clearfix и в сочетании с псевдоклассом :after применяем его к блоку-контейнеру.

Разметка HTML

CSS-стили

float2

Рис. 5. Применение "очищающего" метода для блока-контейнера, содержащего плавающий элемент

6.3. Легкий способ очистки потока

Существует ещё один прием очистки потока для элемента, содержащего плавающие элементы, например, для маркированного горизонтального списка:

ul-overflow

Рис. 6. Очистка потока горизонтального списка
  • zeyser

    Спасибо. Помогла ваша статья со схлопованием. Все написано лаконично и от того понятно.

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

    • Некто Пельмень

      Здравствуйте, возможно ли распространение материала на другом ресурсе, с указанием ссылки на данный сайт?

      • Здравствуйте. Смотря какой материал и в каком количестве вы собираетесь распространять.

        • мишСа

          спасибо вам огромное Елена вы очень много помогаете новичкам .много статей прочитал о сss.там один набор слов или категория понимание сложности

          • И вам спасибо за теплые слова, очень приятно) Я тоже столкнулась с такой проблемой при изучении веб-технологий и считаю, что если человек не может понятно объяснить другим материал, значит он сам не до конца его понимает.

          • мишСа

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

          • Да, главное — практика. По большому счету понять теги и разметку несложно, затруднение вызывают css-стили. Можно взять пример кода и поэкспериментировать в онлайн-редакторе (я люблю http://codepen.io), меняя значения свойств или убирая их.

          • мишСа

            основном мне понравился ваша макет в теме 3д .фон природы рисовать живую бабочку

          • Бабочка мне самой нравится))

        • МишСА

          Благодарю вас!

  • fgjhksdhgk1

    хреновое объяснение, из определения значений свойства position вообще ничего не понятно, сформулировано неграмотно и нелогично

    • 1SekСчастья

      Уважаемый будучи чуточку умнее, то не писали бы «хреновое объяснение» .Ваша проблема в том,что Вы, будучи не первоклассным специалистом решили перескочить основы из книжек, и преступили сразу реализации примеров. Без прочтения основ CSS нет смысла вообще, искать «сам ни знаю что». Автору спасибо, человек показывает вам на практике, что и как должно быть. Если вы не читаете книжки, то для Вас будет все вокруг «сформулировано неграмотно и нелогично».

  • David

    Елена, здравствуйте! Спасибо за Ваш труд!

    Задам глупый вопрос. А почему на рисунке 1 в случае relative-позиционирования отсчет смещения идёт от нижней границы положения этого же div’а в потоке, а не от верхней границы предка? То есть, вроде бы, картинка в обоих случаях (absolute и relative) должна быть одинаковой, а у Вас она разная.

    • Здравствуйте! Согласна, пример не удачный, поэтому заменила его. Если рассматривать позиционированные элементы внутри одного родительского блока, то разницы не будет. Но если каждый позиционированный элемент поместить в разные блоки-контейнеры, как в данном случае, то разница будет видна.

  • Alexander Inkognito

    Спасибо за материал. Предлогаю расширить описание relative и absolute. Долго не мог понять что и зачем, но все просто — absolute позиционирует относительно _первого_ предка с _установленым_ свойством position(даже не важно в какое значение оно установлено), а если таких нет то относитильно окна браузера. relative _всегда_ позиционирует относительно предка.

    • Пожалуйста. Немного поправлю вас:
      1) Если нужно абсолютно позиционировать элемент внутри контейнера, для контейнера задаётся position: relative. При этом место, которое занимал абсолютно позиционированный элемент схлопывается, то есть сам контейнер становится меньше по высоте.
      2) Относительно позиционированный элемент позиционируется относительно своего положения. И место по высоте в контейнере, которое он занимал, не схлопывается при его перемещении.

  • Mikhail Kuzmichev

    Спасибо большое! Двое суток пытался разобраться с перекрытием блоков, оказалось все так просто с «.clearfix;after».

  • Да… это интересно… а вот как сделать позиционирование блока известной высоты по центру как по вертикали, так и по горизонтали, при чем независимо от разрешения экрана (или если известна высота блока/экрана). Желательно CSS код с примерами использования.
    То, что я имею ввиду в прикрепленной картинке
    https://uploads.disquscdn.com/images/0f0247e749242311c2f81d04292b2b9abd9cdd272b5fb02b6f90bdc879c2ea88.jpg