Pull to refresh

Альтернатива для .clearfix

Reading time4 min
Views35K

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


Для начала рассмотрим, что же происходит с элементами и родительским элементом когда к ним добавляется свойство float: right и left. Рассмотрим небольшой пример:


<!-- Пример 1 - базовый -->
<style>
ul {
  padding: 20px;
  margin: 20px;
}
li {
  float: left;
  list-style: none;
  margin-left: 5px;
  border: 1px solid red;
}
</style>
<ul>
  <li>первый</li>
  <li>второй</li>
  <li>третий</li>
</ul>
<p>Какой-то текст</p>

В примере LI имеют свойство float: left; и, как и следовало ожидать, выстраиваются в ряд один за другим и "Какой-то текст" прицепляется следом. Что же, это классическое поведение float. Но давайте посмотрим на родителя, ведь у нас еще есть UL: куда же делся он? Ему мы float не ставили, и по умолчанию это элемент блочный, почему же после него нет переноса?


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


Что же произойдет, если для родительского блока поставить clear: both;? Ровным счетом ничего, ведь, как я уже заметил ранее, float родителю мы не ставили и соответственно его ничто не обтекает, его как бы совсем нет, его содержимое было "вырвано из потока".


Давайте рассмотрим как с этим справится .clearfix:


<!-- Пример 2 - с применением .clearfix -->
<style>
.clearfix:after {
  content: "";
  display: table;
  clear: both;
}
ul {
  padding: 20px;
  margin: 20px;
}
li {
  float: left;
  list-style: none;
  margin-left: 5px;
  border: 1px solid red;
}
</style>
<ul class="clearfix">
  <li>первый</li>
  <li>второй</li>
  <li>третий</li>
</ul>
<p>Какой-то текст</p>

С задачей .clearfix справился. Как же он это делает? Он добавляет после выбранного элемента псевдоэлемент, который огибает все float элементы, расположенные ниже. Ниже именно потому, что родительский элемент в потоке пустой, его почти нет, и поэтому :after помещает элемент физически в самое начало, и браузеру приходится просчитывать, когда же все элементы закончат флоатиться, чтобы остановиться.


А вот вариант без использования .clearfix:


<!-- Пример 3 - без применения .clearfix -->
<style>
ul {
  padding: 20px;
  margin: 20px;
  display: inline-block;
}
li {
  float: left;
  list-style: none;
  margin-left: 5px;
  border: 1px solid red;
}
</style>
<ul class="clearfix">
  <li>первый</li>
  <li>второй</li>
  <li>третий</li>
</ul>
<p>Какой-то текст</p>

Свойство display: inline-block; для родительского элемента. Результат такой же, отличие лишь в том, что .clearfix оставляет родительский элемент блочным, либо таким, каким он был определен ранее. Как этим воспользоваться — решайте сами. И для классических решений эти способы практически равноценны.


Но если сам родительский элемент (и элементы внутри него) флоатится, а относительно него нужно расположить другие блоки, может возникнуть ситуация, когда .clearfix использовать нельзя. Родительский элемент будет занимать 0 размер (содержимое и он сам "вырваны из потока"). И чтобы спозиционировать в его окружении другие элементы, нужно будет либо прописывать фиксированную высоту (а она может быть непостоянной), либо "играться" с position: absolute; (что тоже не всегда можно предусмотреть непостоянством контента). В ряде случаев, добавляя в такие "узлы" на сайте дополнительный контент, может понадобиться пересмотреть всю концепцию верстки и переверстывать весь "узел".


Использование свойства display облегчит диагностику верстки средствами разработки (firebug или другими встроенными в браузеры средствами инспектирования), именно тогда, когда .clearfix применить не получается. Ведь если не сделать эту операцию, то родительский элемент найти инспектором не получится (если у него нет отступов), и под его содержимое не будет отведено место при рендэринге страницы (это хорошо заметно в примере 1 при инспектировании). display: inline-block; как раз и поможет избежать этих проблем.


Варианты верстки доступны по ссылке тут


Давайте еще рассмотрим вот такой вариант.
У clearfix — в родителя div.box не вошел внешний отступ(margin), который прописан для UL, а inline-block все воспринял как нужно все отступы на месте.


А для того, чтобы ширина inline-block стала как у block добавляем width: calc(100% — 80px) — не забываем что отступы внешние и внутренние нужно исключить из ширины.


Итого: в вашем распоряжении — более одного способа решения данной задачи. Хорошо, когда есть выбор, пользуйтесь на здоровье!

Tags:
Hubs:
Total votes 20: ↑13 and ↓7+6
Comments33

Articles