Позиционирование блочных элементов в строку с помощью float

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

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

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

<div class="parent">
    <div class="block fl-block">Левый блок</div>
    <div class="block fr-block">Правый блок</div>
</div>
.block{
    width: 100px;
    height: 100px;
    background: tomato;
}

.fl-block{
    float: left;
}

.fr-block{
    float: right;
}

Все работает, но давай посмотрим на блочную модель родителя. Ой... А высота равняется нулю! Как так-то? Что произошло? Ответ на эти вопросы мы начнем с того, что разберем что такое стандартный поток документа.

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

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

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

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

left

Отменяет действие float со значением left

right

Отменяет действие float со значением right

both

Отменяет действие float одновременно со всех краёв

Таким образом в нашем примере нужно поместить элемент со свойством clear и значением both после float-элементов. Но, как же мы сделаем это? Можем создать пустой тег. Но такой прием является дурной практикой в верстке, и такого стоит избегать. Как тогда поступить? Для этого случая у меня припасен один секрет.

Современные возможности CSS позволяют нам добавлять элементы в HTML прямо из CSS. Для этого этой существует псевдоэлементы :before и :after. Они используются для вывода контента перед (:before) или после (:after) содержимого элемента, к которому они добавляются. Для того, чтобы сделать это нужно использовать следующий синтаксис:

элемент:before{
    content: "Перед содержимым";
}

элемент:after{
    content: "После содержимого";
}

А теперь вернемся к нашему примеру и добавим псевдоэлемент :after в конец элемента .parent.

.parent:after{
    content: "";
    display: block;
    clear: both;
}

.block{
    width: 100px;
    height: 100px;
    background: tomato;
}

.fl-block{
    float: left;
}

.fr-block{
    float: right;
}

Еще раз посмотрим на блочную модель родительского элемента, и теперь высота равняется 100 пикселям. Отлично. Мы справились с ошибкой.

Но не остановимся на этом и сделаем еще один эксперимент со свойством float и строчными элементами. Заменим теги <div> на теги <span>.

<div class="parent">
    <span class="block fl-block">Левый блок</span>
    <span class="block fr-block">Правый блок</span>
</div>

Внешне у нас получился ровно тот же результат. Но давай посмотрим на блочную модель дочерних элементов. И у них установлены свойства width и height со значением 100 пикселей. Стоп! У нас же строчные элементы. Почему для них сработали свойства width и height?

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

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

<div class="parent">
    <div class="block">Левый блок</div>
    <div class="content">
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ullam odit qui debitis esse repudiandae est animi quisquam nesciunt fuga, cumque ex fugiat officia libero, accusantium porro. Blanditiis illo asperiores natus adipisci quibusdam dignissimos voluptatibus, suscipit totam debitis eaque sint eius sunt ducimus. Impedit iure deleniti veniam? Soluta, fugiat! Quaerat, quia.
    </div>
</div>
.parent{
  width: 300px;
}

.parent:after{
  content: "";
  display: block;
  clear: both;
}

.block{
  width: 100px;
  height: 100px;
  background: tomato;
  float: left;
  margin: 10px;
}

.content{
  background-color: bisque;
}

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

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

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

Давай теперь посмотрим, как свойство float влияет на свойства width и height. Ранее во всех примерах я вручную задавал их, но в практике редко приходится это делать. Поэтому возьмем и отключим свойства width и height у элемента .block.

Как только элемент становится float-блоком, то свойства width и height рассчитываются по содержимому элемента. Это подтверждает и блочная модель.

Подведем итоги. Когда к элементу применяется float, то он начинает обладать следующими свойствами:

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

results matching ""

    No results matching ""