Как изменить позицию объекта в html
CSS предоставляет возможности по позиционированию элемента, то есть мы можем поместить элемент в определенное место на странице
Основным свойством, которые управляют позиционированием в CSS, является свойство position . Это свойство может принимать одно из следующих значений:
- static : стандартное позиционирование элемента, значение по умолчанию
- absolute : элемент позиционируется относительно границ элемента-контейнера, если у того свойство position не равно static
- relative : элемент позиционируется относительно его позиции по умолчанию. Как правило, основная цель относительного позиционирования заключается не в том, чтобы переместить элемент, а в том, чтобы установить новую точку привязки для абсолютного позиционированния вложенных в него элементов
- fixed : элемент позиционируется относительно окна бразуера, это позволяет создать фиксированные элементы, которые не меняют положения при прокрутке
Не следует одновременно применять к элементу свойство float и любой тип позиционирования, кроме static (то есть тип по умолчанию).
Абсолютное позиционирование
Область просмотра браузера имеет верхний, нижний, правый и левый края. Для каждого из этих четырех краев есть соответствующее свойство CSS: left (отступ от края слева), right (отступ от края справа), top (отступ от края контейнера сверху) и bottom (отступ снизу). Значения этих свойств указываются в пикселях, em или процентах. Необязательно задавать значения для всех четырех сторон. Как правило, устанавливают только два значения — отступ от верхнего края top и отступ от левого края left.
Блочная верстка в HTML5 .headerHELLO WORLD
Здесь элемент div с абсолютным позиционированием будет находиться на 100 пикселей слева от границы области просмотра и на 50 снизу.

При этом не столь важно, что после этого элемента div идут какие-то другие элементы. Данный блок div в любом случае будет позиционироваться относительно границ области просмотра браузера.
Если элемент с абсоютным позиционированием располагается в другом контейнере, у которого в свою очередь значение свойства position не равно static , то элемент позиционируется относительно границ контейнера:
Позиционирование в HTML5 .outer < position: absolute; left: 80px; top: 40px; width: 430px; height: 100px; border: 1px solid #ccc; >.inner

Относительное позиционирование
Относительное позиционирование также задается с помощью значения relative . Для указания конкретной позиции, на которую сдвигается элемент, применяются те же свойства top, left, right, bottom:
Позиционирование в HTML5 .outer < position: relative; left: 80px; top: 40px; width: 300px; height: 100px; border: 1px solid #ccc; >.inner
Свойство z-index
По умолчанию при совпадении у двух элементов границ, поверх другого отображается тот элемент, который определен в разметке html последним. Однако свойство z-index позволяет изменить порядок следования элементов при их наложении. В качестве значения свойство принимает число. Элементы с большим значением этого свойства будут отображаться поверх элементов с меньшим значением z-index.
Позиционирование в HTML5 body < margin:0; padding:0; >.content < position: relative; top: 15px; left: 20px; width: 250px; height: 180px; background-color: #eee; border: 1px solid #ccc; >.redBlock < position: absolute; top: 20px; left:50px; width: 80px; height: 80px; background-color: red; >.blueBlock

Теперь добавим к стилю блока redBlock новое правило:
.redBlock
Здесь z-index равен 100. Но это необязательно должно быть число 100. Так как у второго блока z-index не определен и фактически равен нулю, то для redBlock мы можем установить у свойства z-index любое значение больше нуля.
И теперь первый блок будет накладываться на второй, а не наоборот, как было в начале:
Позиционирование элементов с помощью JS
CSS отлично справляется с позиционированием элементов, но иногда его не хватает. Учимся выбирать, когда нужен CSS, а когда — JS.
Время чтения: 11 мин
Открыть/закрыть навигацию по статье
- Кратко
- Когда использовать стили
- Когда использовать скрипты
- Как менять позиционирование на скриптах
- Изменять классы
- Изменять style
- Изменение margin или top / left / right / bottom
- Изменение transform
- Изменение кастомных свойств CSS
- Саша Беспоясов советует
Контрибьюторы:
Обновлено 16 ноября 2022
Кратко
Скопировать ссылку «Кратко» Скопировано
Элементы на странице можно позиционировать не только с помощью стилей, но и с помощью JavaScript. В этой статье мы рассмотрим ситуации, когда это оправдано и как таким позиционированием пользоваться.
Прежде чем мы приступим к непосредственно позиционированию, давайте определимся, зачем нам ещё один способ расставлять элементы, когда у нас уже есть CSS.
Когда использовать стили
Скопировать ссылку «Когда использовать стили» Скопировано
Используйте стили для позиционирования всегда, когда это возможно.
CSS — это инструмент, который специально был придуман для стилизации документов.
- Это работает в среднем быстрее.
- Это не собьёт с толку других разработчиков, которые будут читать ваш код.
- Это разделяет зоны ответственности между скриптами и стилями.
Когда использовать скрипты
Скопировать ссылку «Когда использовать скрипты» Скопировано
Используйте скрипты для позиционирования тогда, когда стилей не хватает.
CSS ограничен в обратной связи на действия пользователей на экране. В нём есть такие штуки как @keyframes , transition , :hover , :active , :focus и т. д., но этого не всегда достаточно.
Иногда нужно, чтобы в ответ на действия пользователя на странице происходили сложные преобразования или чтобы пользователи сами могли управлять анимациями на странице.
Такие случаи — это не просто стилизация документа, а скорее смесь из стилизации и программной логики. Чтобы решить такую задачу, нам нужны как инструменты стилизации (CSS), так и инструменты для программирования логики (JS).
Как менять позиционирование на скриптах
Скопировать ссылку «Как менять позиционирование на скриптах» Скопировано
Изменять положение элементов (как и любые стили элементов) на странице можно несколькими способами.
Изменять классы
Скопировать ссылку «Изменять классы» Скопировано
Допустим, мы хотим переместить элемент при клике на него в другое место. Для решения такой задачи нам вполне подойдёт способ с изменением класса у элемента.
.element /* Стили самого элемента. */> .element-initial /* Стили, определяющие начальное положение элемента на странице, например: */ transform: translateX(0px);> .element-final /* Стили, определяющие конечное положение, например: */ transform: translateX(50px);>.element /* Стили самого элемента. */ > .element-initial /* Стили, определяющие начальное положение элемента на странице, например: */ transform: translateX(0px); > .element-final /* Стили, определяющие конечное положение, например: */ transform: translateX(50px); >Элементу изначально заданы классы element element — initial , которые задают его стили, а также его начальное положение.
Теперь в ответ на действие пользователя (например, в ответ на клик), поменяем класс элемента, отвечающий за положение. Воспользуемся методом class List . toggle ( ) у элемента, чтобы добавить класс, если его нет на элементе, и убрать, если класс есть:
// Обрабатываем событие клика на элементе:element.addEventListener('click', () => element.classList.toggle('element-final') element.classList.toggle('element-initial')>)// Обрабатываем событие клика на элементе: element.addEventListener('click', () => element.classList.toggle('element-final') element.classList.toggle('element-initial') >)Тогда получим элемент, который меняет своё положение при клике на него:
Этот способ изменять стили элемента с помощью скриптов самый простой и чистый — все стили остаются описанными внутри CSS. Однако он не всегда подходит.
Использовать такой способ можно, когда мы заранее знаем, куда и откуда мы хотим переместить элемент, но не знаем момент, когда нам это понадобится.
Изменять style
Скопировать ссылку «Изменять style» Скопировано
Второй способ изменять положение элемента — менять атрибут style с помощью JS.
При работе со style следует помнить, что у этого атрибута высокая специфичность, из-за чего он будет перебивать основные стили элемента. Его следует использовать с осторожностью.
Он подойдёт в случае, когда мы мгновенно хотим отражать изменения на элементе, даже если не знаем, что и когда поменяется. Например, если мы хотим перемещать элемент мышкой на экране, нам может понадобиться менять его style .
Для изменения положения через style можно использовать разные свойства.
Изменение margin или top / left / right / bottom
Скопировать ссылку «Изменение margin или top / left / right / bottom» Скопировано
Первое, что приходит на ум — изменение соответствующих CSS-свойств типа margin или left / top / right / bottom .
Создадим элемент с классом element :
.element width: 50px; height: 50px; background: black; position: absolute;>.element width: 50px; height: 50px; background: black; position: absolute; >Теперь попробуем написать драг-н-дроп для мыши.
// Сперва создадим ссылку на этот элемент,// чтобы обрабатывать события на нём:const element = document.querySelector('.element') // Переменная dragging будет отвечать за состояние элемента.// Если его тащат, то переменная будет со значением true.// По умолчанию она false.let dragging = false // В переменных startX и startY мы будем держать координаты точки,// в которой находился элемент, когда мы начали его тащить мышью.let startX = 0let startY = 0 // При событии mousedown (когда на элемент нажимают мышью)// мы отмечаем dragging как true — значит, элемент начали тащить.element.addEventListener('mousedown', (e) => dragging = true // В значения для startX и startY мы помещаем положение курсора // через свойства события e.pageX и e.pageY. startX = e.pageX - Number.parseInt(element.style.left || 0) startY = e.pageY - Number.parseInt(element.style.top || 0) // Из положения курсора мы вычитаем отступы элемента, если они есть. // Вычитание отступов нам нужно, чтобы элемент «запоминал» // своё последнее положение, иначе мы всегда будем начинать тащить его // от начала экрана.>) // Далее мы обрабатываем событие перемещения мыши по body.// Мы наблюдаем именно за body, потому что хотим,// чтобы изменения работали на всей странице,// а не только внутри элемента element.document.body.addEventListener('mousemove', (e) => // Если элемент не тащат, то ничего не делаем. if (!dragging) return // Если тащат, то высчитываем новое положение, // вычитая начальное положение элемента из положения курсора. element.style.top = `$px` element.style.left = `$px`>) // Когда мы отпускаем мышь, мы отмечаем dragging как false.document.body.addEventListener('mouseup', () => dragging = false>)// Сперва создадим ссылку на этот элемент, // чтобы обрабатывать события на нём: const element = document.querySelector('.element') // Переменная dragging будет отвечать за состояние элемента. // Если его тащат, то переменная будет со значением true. // По умолчанию она false. let dragging = false // В переменных startX и startY мы будем держать координаты точки, // в которой находился элемент, когда мы начали его тащить мышью. let startX = 0 let startY = 0 // При событии mousedown (когда на элемент нажимают мышью) // мы отмечаем dragging как true — значит, элемент начали тащить. element.addEventListener('mousedown', (e) => dragging = true // В значения для startX и startY мы помещаем положение курсора // через свойства события e.pageX и e.pageY. startX = e.pageX - Number.parseInt(element.style.left || 0) startY = e.pageY - Number.parseInt(element.style.top || 0) // Из положения курсора мы вычитаем отступы элемента, если они есть. // Вычитание отступов нам нужно, чтобы элемент «запоминал» // своё последнее положение, иначе мы всегда будем начинать тащить его // от начала экрана. >) // Далее мы обрабатываем событие перемещения мыши по body. // Мы наблюдаем именно за body, потому что хотим, // чтобы изменения работали на всей странице, // а не только внутри элемента element. document.body.addEventListener('mousemove', (e) => // Если элемент не тащат, то ничего не делаем. if (!dragging) return // Если тащат, то высчитываем новое положение, // вычитая начальное положение элемента из положения курсора. element.style.top = `$e.pageY - startY>px` element.style.left = `$e.pageX - startX>px` >) // Когда мы отпускаем мышь, мы отмечаем dragging как false. document.body.addEventListener('mouseup', () => dragging = false >)Тогда получится вот такой драг-н-дроп:
Это работает, но не очень эффективно, потому что изменения в этих свойствах заставляют браузер делать много лишней работы.
Мы можем сделать лучше.
Изменение transform
Скопировать ссылку «Изменение transform» Скопировано
Перепишем наш драг-н-дроп, меняя теперь значение свойства transform .
Основа кода останется той же, стили и разметка не поменяются вовсе. В скриптах мы слегка изменим определение положения элемента.
// . element.addEventListener('mousedown', (e) => dragging = true // В этот раз мы не сможем считать нужные нам значения напрямую. // Вместо этого нам потребуется вначале вычислить стиль элемента // через window.getComputedStyle(), а затем узнать значение // свойства transform. const style = window.getComputedStyle(element) // Мы могли бы просто считать значение style.transform, // но это бы нам не сильно помогло. // При обычном считывании мы бы получили нечто вроде: // matrix(1, 0, 0, 1, 27, 15); // // Это матрица афинных преобразований. // Её можно представить в виде: // matrix(scaleX, skewY, skewX, scaleY, translateX, translateY); // где: // - scaleX — масштабирование по горизонтали, // - scaleY — масштабирование по вертикали, // - skewX — перекос по горизонтали, // - skewY — перекос по вертикали, // - translateX — смещение по горизонтали, // - translateY — смещение по вертикали. // // Но даже учитывая, что у нас есть все необходимые числа, // работать с этим неудобно — это же просто строка. // // К счастью мы можем воспользоваться DOMMatrixReadOnly, // который преобразует эту матрицу в удобную для использования: const transform = new DOMMatrixReadOnly(style.transform) // Теперь мы можем воспользоваться свойствами, // которые содержат в себе значения translateX и translateY. const translateX = transform.m41 const translateY = transform.m42 // Дальше — как раньше, только вычитаем не top и left, // а translateX и translateY. startX = e.pageX - translateX startY = e.pageY - translateY>)// добавляем возможность отпустить элемент при отжатии клавишиdocument.body.addEventListener("mouseup", () => dragging = false;>);// . element.addEventListener('mousedown', (e) => dragging = true // В этот раз мы не сможем считать нужные нам значения напрямую. // Вместо этого нам потребуется вначале вычислить стиль элемента // через window.getComputedStyle(), а затем узнать значение // свойства transform. const style = window.getComputedStyle(element) // Мы могли бы просто считать значение style.transform, // но это бы нам не сильно помогло. // При обычном считывании мы бы получили нечто вроде: // matrix(1, 0, 0, 1, 27, 15); // // Это матрица афинных преобразований. // Её можно представить в виде: // matrix(scaleX, skewY, skewX, scaleY, translateX, translateY); // где: // - scaleX — масштабирование по горизонтали, // - scaleY — масштабирование по вертикали, // - skewX — перекос по горизонтали, // - skewY — перекос по вертикали, // - translateX — смещение по горизонтали, // - translateY — смещение по вертикали. // // Но даже учитывая, что у нас есть все необходимые числа, // работать с этим неудобно — это же просто строка. // // К счастью мы можем воспользоваться DOMMatrixReadOnly, // который преобразует эту матрицу в удобную для использования: const transform = new DOMMatrixReadOnly(style.transform) // Теперь мы можем воспользоваться свойствами, // которые содержат в себе значения translateX и translateY. const translateX = transform.m41 const translateY = transform.m42 // Дальше — как раньше, только вычитаем не top и left, // а translateX и translateY. startX = e.pageX - translateX startY = e.pageY - translateY >) // добавляем возможность отпустить элемент при отжатии клавиши document.body.addEventListener("mouseup", () => dragging = false; >);А также немного обновим изменение положения:
// . document.body.addEventListener('mousemove', (e) => if (!dragging) return const x = e.pageX - startX const y = e.pageY - startY // В этот раз мы можем объединить обновлённые координаты // в одну запись translate, которую потом // присвоим в качестве значения свойству transform. element.style.transform = `translate($px, $px)`>)// . document.body.addEventListener('mousemove', (e) => if (!dragging) return const x = e.pageX - startX const y = e.pageY - startY // В этот раз мы можем объединить обновлённые координаты // в одну запись translate, которую потом // присвоим в качестве значения свойству transform. element.style.transform = `translate($x>px, $y>px)` >)В итоге получим такой же драг-н-дроп, но работающий на transform .
Но мы можем ещё лучше
Изменение кастомных свойств CSS
Скопировать ссылку «Изменение кастомных свойств CSS» Скопировано
Сейчас код рабочий, но его трудно читать. Как минимум потому, что надо знать, как работает матрица преобразований и DOM Matrix Read Only .
Мы же можем не менять значение transform вовсе, а вместо этого менять значение CSS-переменных, чтобы обновлять положение элемента!
Первым делом определяем кастомные свойства CSS в стилях элемента:
.element width: 50px; height: 50px; background: black; position: absolute; /* В переменной --x мы будем держать значение координаты по горизонтали; в переменной --y — по вертикали. */ --x: 0px; --y: 0px; /* Укажем transform, значением которого передадим translate с указанными переменными. В итоге нам не придётся менять сам transform, мы сможем ограничиться лишь изменением значений переменных --x и --y. */ transform: translate(var(--x), var(--y));>.element width: 50px; height: 50px; background: black; position: absolute; /* В переменной --x мы будем держать значение координаты по горизонтали; в переменной --y — по вертикали. */ --x: 0px; --y: 0px; /* Укажем transform, значением которого передадим translate с указанными переменными. В итоге нам не придётся менять сам transform, мы сможем ограничиться лишь изменением значений переменных --x и --y. */ transform: translate(var(--x), var(--y)); >Теперь подправим скрипт, чтобы сперва считать значение этих переменных:
// . element.addEventListener('mousedown', (e) => dragging = true // Получаем стиль элемента: const style = window.getComputedStyle(element) // Считываем значение каждой переменной через getPropertyValue: const translateX = parseInt(style.getPropertyValue('--x')) const translateY = parseInt(style.getPropertyValue('--y')) // Дальше всё остаётся по-старому :–) startX = e.pageX - translateX startY = e.pageY - translateY>)// . element.addEventListener('mousedown', (e) => dragging = true // Получаем стиль элемента: const style = window.getComputedStyle(element) // Считываем значение каждой переменной через getPropertyValue: const translateX = parseInt(style.getPropertyValue('--x')) const translateY = parseInt(style.getPropertyValue('--y')) // Дальше всё остаётся по-старому :–) startX = e.pageX - translateX startY = e.pageY - translateY >)А теперь изменим обновление стилей:
// . document.body.addEventListener('mousemove', (e) => if (!dragging) return // Обратите внимание, насколько лаконичной стала запись. // Мы всего лишь указываем, какое значение должна // принять каждая из переменных: element.style.setProperty("--x", `$px`) element.style.setProperty("--y", `$px`)>)// . document.body.addEventListener('mousemove', (e) => if (!dragging) return // Обратите внимание, насколько лаконичной стала запись. // Мы всего лишь указываем, какое значение должна // принять каждая из переменных: element.style.setProperty("--x", `$e.pageX - startX>px`) element.style.setProperty("--y", `$e.pageY - startY>px`) >)В результате получаем такой же драг-н-дроп!
На практике
Скопировать ссылку «На практике» Скопировано
Методы позиционирования элементов в CSS
HTML-документ состоит из большого количества элементов, вложенных друг в друга. Чтобы из этих элементов и CSS построить изображение страницы , их необходимо как-то в ней расположить. По умолчанию размещение всех элементов на странице осуществляется в нормальном или базовом потоке .
Что это значит? Во-первых, вывод элементов на страницу браузер осуществляет в том порядке, в котором они следуют в HTML коде .
123
Во-вторых, в коде элементы вложены друг в друга, и чтобы это учитывать при выводе используют так называемые воображаемые слои для отображения элементов . При этом слой элемента тем выше (ближе к нам), чем данный элемент является более вложенным в коде, т.е. глубже расположен в нём.
Этот элемент находится позади других элементов.Этот вложенный элемент принадлежит воображаемому слою, который находится поверх слоя родителя. Этот элемент ещё ближе к нам, его слой располагается над слоем уже его родителя.
В-третьих, положение элемента в потоке зависит от значения свойства display .
inline 1inline 2inline 3inline 4inline 1inline 2inline 1inline 2inline 3
Например, элементы, имеющее блочное отображение ( 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 никакого влияния на него не оказывают, т.к. его местонахождение определяется потоком документа .
Пример выстраивания статично позиционированных элементов:

Относительное позиционирование (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 вверх и влево относительно его исходного положения:
FIRST ELEMENTSECOND ELEMENTTHIRD ELEMENT
Если в некоторой области страницы оказываются несколько позиционированных элементов, то они перекрывают друг на друга в определённом порядке. При этом по умолчанию выше оказывается тот элемент, который ниже описан в коде. Но порядок перекрытия элементов (их положение перпендикулярное экрану, т.е. вдоль оси Z) можно изменить. Осуществляется в CSS это с помощью свойства z-index . z-index может принимать отрицательные и положительные целые число, auto и 0 . Но, хорошей практикой является использование в качестве z-index чисел из диапазона 0-9999 .
При этом чем больше у элемента значение z-index , тем ближе он располагается к нам, и, следовательно, перекрывает все элементы в данной области, у которых значение z-index меньше.
Абсолютное позиционирование (absolute)
Установка абсолютного позиционирования элементу осуществляется посредством задания ему position: absolute .
Этот тип позиционирования позволяет разместить элемент именно там, где вы хотите.
Позиционирование выполняется относительно ближайшего позиционированного предка.
Под позиционированным элементом понимается элемент с position , равным relative , absolute , fixed или sticky .
В этом примере позиционирование элемента #id-3 будет выполнять относительно #id-2 , т.к. он является позиционированным и является по отношению к нему более близким предком.
Если данный элемент не был бы позиционированным, то позиционирование #id-3 выполнялось бы относительно #id-1 :
Если среди предков у элемента с position: absolute нет позиционированного элемента, то в этом случае он будет позиционироваться относительно HTML страницы, т.е. элемента body .
Когда элементу устанавливаем position: absolute без указания CSS-свойств ( top , left , right и bottom ), определяющих его положение , он будет находиться в том месте, в котором он был бы расположен, если бы находился в потоке (при этом при вычислении его положения учитываются только элементы, расположенные до него в коде и находящиеся в потоке).
При этом другие элементы его видеть не будут, и, следовательно, они будут расположены на странице, не обращая никакого внимание на него.
FIRST ELEMENTSECOND ELEMENTTHIRD ELEMENT
CSS-свойства для управления положением абсолютно позиционированного элемента работают по-другому чем с position: relative .
CSS-свойства top , bottom , left и right задают положение элемента относительно ближайшего позиционированного предка или body , если такого предка нет.
Установить ширину (высоту) абсолютно позиционированному можно с помощью установки ему двух координат top и bottom ( left и right ).
Если элементу одновременно установить top , bottom и height , то предпочтение будет отдано top и height .
Абсолютное позиционирование применяется очень часто совместно с относительным позиционированием в дизайнерских целях, когда необходимо разместить различные элементы относительного друг друга, так же может применяться для создания выпадающих меню, разметки сайта и т.д.

Фиксированное позиционирование (fixed)
Задание элементу фиксированного позиционирования осуществляется посредством установки ему position: fixed .
Фиксированное позиционирование похоже на абсолютное, но в отличии от него оно всегда привязывается к краям окна браузера (viewport), и остаётся в таком положении даже при скроллинге страницы.
Фиксированное позиционирование применяется для закрепления на странице навигационных меню, кнопки «вверх», панелей с социальными кнопками и многого другого.

Совместное использование относительного и абсолютного позиционирования
Относительное позиционирование очень часто используется вместе с абсолютным позиционированием.
-
Если расположить блоки с абсолютным позиционированием в блок с относительным, то расстояния будут уже задаваться не от края окна браузера, а от границ относительного блока.

Например: для создания фиксированных макетов состоящих из 3 блоков, выровненных по верхнему краю. Установим высоту «400px» относительному блоку для наглядности .
Левый блокОсновной блокПравый блок
Дополнительно к блокам можно применять свойство z-index , которое предназначено для позиционирования элементов по оси Z. Чем больше значение свойства z-index , тем ближе элемент расположен к нам, и наоборот, чем меньше значение, тем дальше расположен элемент от нас.
Позиционирование содержимого
Одной из лучших сторон CSS является то, что стили дают нам возможность позиционировать содержимое и элементы на странице практически любым мыслимым образом. Это вносит структурность в наш дизайн и помогает сделать контент более наглядным.
Есть несколько разных типов позиционирования в CSS, каждый из этих типов имеет свою область действия. В этой главе мы собираемся взглянуть на несколько различных случаев применения — создание многократно используемых макетов и уникальное позиционирование одноразовых элементов, а также описание нескольких методов как это сделать.
Позиционирование через float
Один из способов позиционирования элементов на странице — через свойство float . Это свойство довольно универсально и может применяться разными путями.
По существу, свойство float берёт элемент, убирает его из обычного потока страницы и позиционирует слева или справа от родительского элемента. Все остальные элементы на странице будут обтекать такой элемент. Например, абзацы будут обтекать изображение, если для элемента
установлено свойство float .
Когда свойство float применяется к нескольким элементам одновременно, это даёт возможность создать макет с обтекаемыми элементами расположенными рядом или напротив друг друга, как показано в многоколоночном макете.
Свойство float принимает несколько значений, два самых популярных — это left и right , они позволяют элементу располагаться слева или справа от своего родителя.
float на практике
Давайте создадим общий макет страницы с шапкой вверху, двумя колонками в центре и подвалом внизу. В идеале эту страницу следует разметить с помощью элементов , , и , как описано в уроке 2 «Знакомство с HTML». Внутри элемента HTML может выглядеть так:
Демонстрация макета без float
Здесь элементы и являются блочными, поэтому они укладываются один поверх другого по умолчанию. Однако мы хотим, чтобы эти элементы располагались бок о бок. Установив float для как left , а для как right , мы можем позиционировать их как две колонки, расположенных напротив друг друга. Наш CSS должен выглядеть так:
section < float: left; >aside
Для справки, обтекаемые элементы располагаются по краю родительского элемента. Если нет родителя, обтекаемый элемент будет располагаться по краю страницы.
Когда мы устанавливаем элемент обтекаемым, то убираем его из обычного потока HTML-документа. Это приводит к тому, что ширина этого элемента по умолчанию становится шириной его содержимого. Иногда, например, когда мы создаём колонки для многократно используемого макета, такое поведение нежелательно. Это можно исправить путём добавления свойства width с фиксированным значением для каждой колонки. Кроме того, чтобы обтекаемые элементы не соприкасались друг с другом, в результате чего содержимое одного элемента располагается рядом с другим, мы можем использовать свойство margin , чтобы установить пространство между элементами.
Ниже мы расширяем предыдущий блок кода, добавив margin и width для каждой колонки, чтобы лучше формировать наш желаемый результат.
section < float: left; margin: 0 1.5%; width: 63%; >aside
Демонстрация макета с float
float могут изменить значение display у элемента
Для обтекаемого элемента также важно понимать, что элемент удаляется из обычного потока страницы и что у элемента может измениться значение display , заданное по умолчанию. Свойство float опирается на то, что у элемента значение display задано как block и может изменить значение display у элемента по умолчанию, если он ещё не отображается как блочный элемент.
Например, элемент, у которого display указан как inline , такой как строчный , игнорирует любые свойства height или width . Однако, если для строчного элемента указать float , значение display изменится на block и тогда элемент уже может принимать свойства height или width .
Когда мы применяем float для элемента, то должны следить за тем, как это влияет на значение свойства display .
Для двух колонок вы можете установить float , для одной колонки как left , а для другой как right , но для нескольких колонок нам придётся изменить наш подход. Скажем, к примеру, мы хотели бы получить ряд из трёх колонок между нашими элементами и . Если мы выбросим наш элемент и воспользуемся тремя элементами , наш HTML может выглядеть следующим образом:
Чтобы расположить эти три элемента в строку из трёх колонок, мы должны задать float для всех элементов как left . Мы также должны настроить ширину с учётом дополнительных колонок и расположить их один рядом с другим.
section
Здесь у нас есть три колонки, все с равной шириной и значением margin , а также с float , заданным как left .
Демонстрация трёхколоночного макета с float
Очистка и содержимое float
Свойство float было первоначально разработано, чтобы позволить содержимому обтекать вокруг изображений. Для изображения может быть задано float и всё содержимое вокруг этого изображения, естественно, обтекает вокруг него. Хотя это прекрасно работает для картинок, свойство float на самом деле не было предназначено для использования в макете и с целью позиционирования и, таким образом, оно идёт с несколькими ловушками.
Одной из этих ловушек является то, что иногда надлежащие стили не отображаются на элементе, который расположен рядом с обтекаемым элементом или является его родителем. Когда элемент установлен обтекаемым, то он убирается из обычного потока страницы и, как результат, стили элементов вокруг этого обтекаемого элемента могут получить негативное влияние.
Часто значения свойств margin и padding интерпретируются некорректно, заставляя их сливаться с обтекаемым элементом. Другие свойства также могут быть затронуты.
Другая ошибка состоит в том, что иногда нежелательный контент начинает обтекать элемент с float . Удаление элемента из потока документа позволяет всем элементам вокруг обтекаемого элемента обходить его и задействовать любое доступное пространство вокруг обтекаемого элемента, что часто бывает нежелательно.
В нашем предыдущем примере с двумя колонками, после того как мы добавили float к элементам и , но до того как установили свойство width к любому из них, содержимое внутри элемента располагалось между двумя обтекаемыми элементами выше него, заполняя всё доступное пространство. Следовательно, элемент находился бы в промежутке между элементами и , занимая свободное место.
Демонстрация макета без очистки float
Чтобы предотвратить содержимое от обматывания вокруг обтекаемых элементов, нам нужно сделать очистку float и вернуть страницу в её обычный поток. Мы рассмотрим как очистить float , а затем взглянем на их содержимое.
Очистка float
Очистка float происходит с помощью свойства clear , которое принимает несколько различных значений: наиболее часто используемые значения — left , right и both .
Значение left очищает левые float , в то время как значение right очищает правые float . Значение both , однако, очистит левые и правые float и часто является наиболее идеальным вариантом.
Возвращаясь к нашему предыдущему примеру, если мы используем свойство clear со значением both для элемента , то можем очистить float . Важно, что clear применяется к элементу, указанному после обтекаемых элементов, а не раньше, чтобы вернуть страницу в её обычный поток.
footer
Демонстрация макета с очисткой float
Содержимое float
Вместо очистки float , ещё одним вариантом является установка содержимого float . Результат получится почти такой же, однако содержимое float действительно гарантирует, что все наши стили будут отображаться надлежащим образом.
Чтобы установить содержимое float , обтекаемые элементы должны находиться внутри родительского элемента, он будет выступать в качестве контейнера, оставляя поток документа полностью обычным за его пределами. В стилях для этого родительского элемента представлен класс group , как показано здесь:
.group::before, .group::after < content: ""; display: table; >.group::after < clear: both; >.group
Здесь немного что происходит, но, по сути, всё что CSS делает — очищает все обтекаемые элементы внутри элемента с классом group и возвращает документ в обычный поток.
Более конкретно, псевдоэлементы ::before и ::after , как указано в уроке 4, динамически генерируют элементы выше и ниже элемента с классом group . Эти элементы не включают в себя какой-либо контент и отображаются как табличные элементы, подобно элементам блочным. Динамически генерируемый элемент после элемента с классом group очищает float внутри элемента с классом group , так же, как и clear ранее. И, наконец, элемент с классом group также очищает все float , которые могут появиться до него на случай, если существует float со значением left или right . Также сюда включена небольшая хитрость, которая заставляет старые браузеры играть красиво.
Здесь больше кода, чем единственная команда clear: both , но он может оказаться весьма полезным.
Рассматривая наш макет страницы с двумя колонками мы могли бы обернуть и родительским элементом. Этот родительский элемент будет содержать в себе обтекаемые элементы. Код будет выглядеть следующим образом:
.group::before, .group::after < content: ""; display: table; >.group::after < clear: both; >.group < clear: both; *zoom: 1; >section < float: left; margin: 0 1.5%; width: 63%; >aside
Демонстрация макета с содержимым float
Показанная здесь техника известна как «clearfix» и часто встречается на других сайтах с именем класса clearfix или cf. Мы решили использовать имя класса group , потому что он представляет группу элементов и лучше выражает содержимое.
Когда для элементов задано float важно следить за тем, как они влияют на поток страницы и убедитесь, что поток страницы сбрасывается путём очистки или через содержимое float, как надо. В противном случае, отслеживание float может вызвать немало головной боли, особенно на страницах, содержащих несколько строк, в каждой из которых несколько колонок.
На практике
Вернёмся к сайту Styles Conference и опробуем на нём добавление float к некоторому содержимому.
-
Перво-наперво, перед применением float к любому элементу, давайте обеспечим содержимым эти обтекаемые элементы, добавив clearfix в наш CSS. В файле main.css, чуть ниже наших стилей сетки, добавим clearfix под именем класса group , как и раньше.
/* ======================================== Clearfix ======================================== */ .group::before, .group::after < content: ""; display: table; >.group::after < clear: both; >.group
Styles Conference
/* ======================================== Основной заголовок ======================================== */ .logo
Styles
Conference.logo
/* ======================================== Основной подвал ======================================== */ .primary-footer small
.primary-footer
С учётом всех этих изменений в элементах и , мы должны быть уверены, что внесли их на каждой странице, а не только на странице index.html.

Рис. 5.02. Главная страница Styles Conference теперь включает трёхколоночный макет
Демонстрация и исходный код
Ниже вы можете просмотреть сайт Styles Conference в его нынешнем состоянии, а также скачать исходный код сайта на данный момент.
Уникальное позиционирование элементов
Рано или поздно каждый пожелает точно позиционировать элемент, но float или строчно-блочные элементы не позволяют проделать такой трюк. Обтекаемые элементы, которые удаляют элемент из потока страницы, часто приводят к нежелательным результатам, поскольку окружающие элементы обтекают вокруг элемента с float . Строчно-блочные элементы, если только мы не создаём колонки, могут быть довольно неудобны, когда дело касается правильного положения. Для подобных ситуаций мы можем использовать свойство position в сочетании со свойствами смещения блока.
Свойство position определяет, как элемент позиционируется на странице и будет ли он отображаться в обычном потоке документа. Оно применяется в сочетании со свойствами смещения блока — top , right , bottom и left , которые точно определяют, где элемент будет расположен путём перемещения элемента в разных направлениях.
По умолчанию у каждого элемента значение position установлено как static , это означает, что элемент существует в обычном потоке документа и не принимает какие-либо свойства для его смещения. Значение static наиболее часто переписывается значением relative или absolute , которые мы рассмотрим дальше.
Относительное позиционирование
Значение relative для свойства position позволяет элементам отображаться в обычном потоке страницы, резервируя место для элемента как предполагалось и не позволяя другим элементам его обтекать. Однако, оно также позволяет модифицировать положение элемента с помощью свойств смещения. К примеру, рассмотрим следующие HTML и CSS:
div < height: 100px; width: 100px; >.offset
Демонстрация относительного позиционирования
Здесь для второго элемента с классом offset задано значение position как relative , а также два свойства смещения — left и top . Это сохраняет исходное положение элемента и другим элементам не разрешено двигаться в эту область. Кроме того, свойства смещения перемещают элемент, выталкивая его на 20 пикселей от левого и на 20 пикселей от верхнего исходного местоположения.
Для относительно позиционированных элементов важно знать, что свойства смещения блока определяют, куда элемент будет перемещён, учитывая его исходное положение. Таким образом, свойство left со значением 20 пикселей фактически толкает элемент вправо на 20 пикселей. Свойство top со значением 20 пикселей затем будет толкать элемент вниз на 20 пикселей.
Когда мы позиционируем элемент с помощью свойств смещения, элемент перекрывает элемент под ним, а не сдвигает его вниз, как это делают свойства margin или padding .
Абсолютное позиционирование
Значение absolute для свойства position отличается от значения relative тем, что элемент с абсолютным позиционированием не появляется в обычном потоке документа, исходное пространство и положение абсолютно позиционируемого элемента не резервируется.
Кроме того, абсолютно позиционируемые элементы перемещаются относительно их ближайшего относительно позиционированного родительского элемента. Если относительно позиционированного родителя не существует, то абсолютно позиционированный элемент будет позиционироваться относительно элемента . Это небольшая часть информации; давайте взглянем на то, как это работает внутри некоторого кода:
section < position: relative; >div
Демонстрация абсолютного позиционирования
В этом примере элемент позиционируется относительно, но не включает каких-либо свойств смещения. Следовательно, его положение не меняется. Элемент с классом offset включает значение position как absolute . Поскольку элемент является ближайшим относительно позиционированным родительским элементом для , то элемент будет позиционироваться относительно элемента .
Для относительно позиционированных элементов свойства смещения определяют, в каком направлении элемент будет перемещён относительного самого себя. Для абсолютно позиционируемых элементов свойства смещения определяют, в каком направлении элемент будет перемещён относительно его ближайшего относительно позиционированного родителя.
В результате свойств right и top , элемент появится в 20 пикселях справа и 20 пикселях сверху внутри .
Поскольку элемент позиционируются абсолютно, он не располагается в обычном потоке страницы и будет перекрывать любые окружающие его элементы. Кроме того, исходное положение не сохраняется и другие элементы могут занять это место. Как правило, большая часть позиционирования может происходить без применения свойств position и свойств смещения, но в некоторых случаях они могут оказаться чрезвычайно полезны.
Резюме
Изучение позиционирования содержимого в HTML и CSS является огромным шагом в сторону освоения этих языков. Добавьте к этому блочную модель и вот мы уверенно движемся по пути превращения во фронтенд-разработчиков.
Для проверки, в этом уроке мы рассмотрели следующее:
- Что такое float и как его использовать, чтобы позиционировать содержимое.
- Как очистить и установить содержимое обтекаемых элементов.
- Как позиционировать содержимое с помощью строчно-блочных элементов.
- Как удалить пустое пространство между строчно-блочными элементами.
- Как уникально позиционировать контент через относительное и абсолютное позиционирование элементов.
Мы добавляем новые навыки с каждым уроком, так что давайте продолжим. Следующая тема — типографика!
Ресурсы и ссылки
- CSS Float Theory via Smashing Magazine
- CSS Positioning 101 via A List Apart
См. также