Display: inline-block
HTML&CSS

Display: inline-block

Оригинал: About inline-blocks, Christian van Deursen

Для того, чтобы элементы на странице располагались друг за другом мы можем использовать свойство dislpay: inline-block. Этот способ завоевал популярность как альтернатива использованию свойства float. В этой статье мы рассмотрим, как использовать inline-block и как справиться с проблемами, которые он вызывает.

Основы

HTML-элементы могут быть «блочными» или «инлайновыми». Блок inline-block ведет себя как сочетание того и другого. На самом деле это инлайновый элемент, который внутри ведет себя как блочный. Чтобы лучше понять свойства inline-block элементов, давайте взлянем на характеристики блочных и инлайновых элементов.

Инлайновые элементы:

  • Имеют значение свойства display равное inline
  • Имеют ширину равную ширине содержимого
  • Выстраиваются друг за другом горизонтально
  • Вертикальные отступы не могут быть заданы
  • Высота и ширина не могут быть заданы
  • Для управления позиционированием могут быть использованы свойства direction и text-align
  • Левый и правый отступы могут использоваться для управления горизонтальным позиционированием
  • Свойство vertical-align может быть использовано для управления вертикальным позиционированием

Блочные элементы:

  • Свойство display имеет значение block, list-item или table
  • По умолчанию имеют ширину равную ширине внутренней области своего контейнера
  • Выстраиваются друг за другом вертикально
  • Могут быть заданы высота и ширина
  • Отступы могут быть использованы для управления позиционированием

Display: inline-block

Мы можем объединить блочное и инлайновое поведение, задав блоку значение свойства display равное inline-block.


a { display: inline-block; }

Internet Explorer 6 и 7 не поддерживают значение inline-block для элементов, которые не являются инлайновыми по умолчанию. Для таких случаев есть простое решение:


div {
    display: inline-block;
    *zoom: 1; /* trigger hasLayout for IE7 and below */
    *display: inline; /* the star targets only IE7 and below */
}

После этого блоки будут иметь следующие характеристики:

  • Блоки выстраиваются друг за другом горинтально
  • Могут быть определены высота и ширина
  • Отступы можно использовать для управления позиционированием
  • Свойство vertical-align может быть использовано для управления вертикальным позиционированием

Для чего используется inline-block

Вы можете задать блоку значение display: inline-block, если необходимо задать ширину/высоту или вертикальные отступы, и при этом блок должен остаться инлайновым. Также такой прием имеет ряд преимуществ по сравнению со свойством float, например:

  • Элементы остаются частью потока, поэтому не требуются clearfix'ы
  • Мы можем больше контролировать вертикальное выравнивание, используя свойство vertical-align и задавая ему значения top, middle или bottom
  • Не требуется дополнительная разметка, когда колонки имеют содержимое разной высоты
  • Центрирование колонок можно выполнить как с помощью отступов, так и с помощью свойства text-align: center

Если элементы имеют свойство display: inline-block, вы увидите, что стороны блоков «не касаются» друг друга. Между ними всегда есть небольшой «пробел». Это расстояние, которое отделяет слова друг от друга в предложении. Это «инлайновая часть» инлайн-блоков. Даже если на странице с такими блоками нет текста, между самими блоками все равно будут отступы. Это происходит из-за символов форматирования кода в редакторе: пробелы, табы, переводы строки. Хорошо, когда такой отступ повляется при установке ссылки на некоторое слово в предложении, но когда мы верстаем макет сетки, например, эти пробелы являются настоящей головной болью.

Есть несколько способов удаления таких отступов. Я привел их ниже.

Удаление пробелов


<ul>
    <li>Lorem.</li><li>Sapiente!</li><li>Repudiandae?</li><li>Veniam!</li><li>Dolorum.</li>
</ul>

Пробелы внутри тегов


<ul>
  <li>Lorem.</li><li>
  Sapiente!</li><li>
  Repudiandae?</li><li>
  Veniam!</li><li>
  Dolorum.</li>
</ul>

Пробелы в комментариях


<ul>
  <li>Lorem.</li><!--
--><li>Sapiente!</li><!--
--><li>Repudiandae?</li><!--
--><li>Veniam!</li><!--
--><li>Dolorum.</li>
</ul>

Обнуление размера шрифта


ul {
  font-size: 0;
}
ul li {
  display: inline-block;
  font-size: 16px;
}

Этот метод заключается в установке размера шрифта в ноль. Размер пробелов зависит от размера шрифта, так что, когда мы устанавливаем размер шрифта в ноль — пробелы исчезают. Это решение осложняется при работе с относительными единицами, такими как em’ы, поскольку, если размер шрифта родителя равен нулю, все значения, основанные на em, так же будут равны нулю. Однако это работает с rem’ами. Кажется, это решение не совсем работает в Android. Я проверял в Android версий 2.2, 2.3.3, 4.1, 4.2 и 4.3 и в каждом их них находилась ошибка. Android 2.2 и 2.3.3 похоже полностью игнорируют размер шрифта. В Android 4.1, 4.2 и 4.3 пробелы исчезают не полностью. Строка из трех блоков (по 1/3) работает как ожидается, но в строке из 4 блоков (по 1/4) последний блок сдвигается на строку ниже.

Отрицательный правый отступ


li {
  display: inline-block;
  margin-right: -0.25em;
}

Этот способ сводит на нет пробелы, устанавливая отрицательное значение для правого отступа, которое по меньшей мере равно размеру пробела. Поиск оптимального значения для этого отступа не так прост. Я обнаружил, что значение, которое сводит на нет пробелы, отличается среди различных браузеров и зависит не только от font-size, но и от масштаба при просмотре страницы.

Невидимый шрифт

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

Открытые теги

Если оставить теги открытыми, дополнительные пробелы также не появятся:


<ul>
  <li>One
  <li>Two
  <li>Three
</ul>

Это может быть не самое красивое решение, но оно проходит HTML-валидацию (не XHTML).

Удаление пробелов с помощью JavaScript

Удалить пробелы также можно с помощью JavaScript: http://codepen.io/hucklesby/pen/sDGaC

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

Каков оптимальный размер правого отступа, чтобы убрать пробелы в разных браузерах? Я сделал несколько тестов, чтобы найти оптимальное значение для пяти основных настольных браузеров. Для этого я создал простой простой макет с двумя инлайн-блок колонками, убирав пробелы с помощью отрицательного правого отсупа. Затем я просматривал страницу с различными значениями отступа, размера шрифта и в разном масштабе. Я также обнаружил, что изменение ширины окна браузера также играет роль, делая пробелы видимыми или нет. Если при каком-то масштабе пробелы становились видимыми — браузер не проходил тест с этим отступом. Когда не было видно пробелов при любом значении отступа, я отмечал, что браузер «прошел тест» с данным отступом. В таблице ниже приведены размеры отступов, для которых бразуеры прошли тест.

Все браузеры, кроме Internet Explorer, были протестированы на OSX 10.9.1. Internet Explorer использовался на OC Windows 8 Pro.

Размер отступа, необходимый для удаления пробела
Fontsize:
9px
Margin value (em)
-0.24 -0.25 -0.26 -0.27 -0.28 -0.32 -0.34
Chrome 32.0
Firefox 26.0
IE 10.0
Safari 7.0.1
Opera 12.16
Размер отступа, необходимый для удаления пробела
Fontsize:
standard
Margin value (em)
-0.24 -0.25 -0.26 -0.27 -0.28 -0.32 -0.34
Chrome 32.0
Firefox 26.0
IE 10.0
Safari 7.0.1
Opera 12.16
Размер отступа, необходимый для удаления пробела
Fontsize:
72px
Margin value (em)
-0.24 -0.25 -0.26 -0.27 -0.28 -0.32 -0.34
Chrome 32.0
Firefox 26.0
IE 10.0
Safari 7.0.1
Opera 12.16

Значения отрицательного отступа находятся в диапазоне от −0.24em до −0.34em. Это покрывает большинство популярных десктопных браузеров и размер шрифта от 9px до 72px. Теперь давайте посмотрим, что происходит, если мы установим правый отстум в −0.32em и откроем страницу в IE, для которого необходимо значение −0.24em.

display: inline-block в IE

Синяя линия в увеличенном блоке — это выделение в IE developer tools. Оно показывает, что правый блок перекрывает левый больше чем на пиксель (0.32 — 0.24 * 16 = 1.28px).

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

Сетка с использованием inline-block

Давайте взглянем на inline-block в действии по поробуем создать сетку с его помощью. Для удаления пробелов я использовал HTML-комментарии. Первая строка показывает блоки, вертикально выровненные по центру. По умолчанию inline-block элементы имеют значение свойства vertical-align: middle. Строки 3 и 4 показывают поведение блоков с vertical-align: top и vertical-align: bottom. Центрирование элемента по горизонтали сделано с помощью свойства text- align: center, заданного контейнеру (.grid).

1/4
1/4
1/4
1/4
1/3
1/3
1/3
1/4
1/4
1/4
1/4
1/4
1/4
1/4
1/4
2/4
2/4
2/4

<div class="grid">
    <div class="grid-cel fourths-1">
      <div class="module">1/4</div>
    </div><!--

 --><div class="grid-cel fourths-1">
      <div class="module">1/4</div>
    </div><!--

 --><div class="grid-cel fourths-1">
      <div class="module">1/4</div>
    </div><!--

 --><div class="grid-cel fourths-1">
      <div class="module">1/4</div>
    </div><!--

 --><div class="grid-cel thirds-1">
      <div class="module">1/3</div>
    </div><!--

 --><div class="grid-cel thirds-1">
      <div class="module">1/3</div>
    </div><!--

 --><div class="grid-cel thirds-1">
      <div class="module">1/3</div>
    </div><!--

 --><div class="grid-cel fourths-1 top">
      <div class="module">1/4</div>
    </div><!--

 --><div class="grid-cel fourths-1 top">
      <div class="module">1/4</div>
    </div><!--

 --><div class="grid-cel fourths-1 top">
      <div class="module">1/4</div>
    </div><!--

 --><div class="grid-cel fourths-1 top">
      <div class="module">1/4</div>
    </div><!--

 --><div class="grid-cel fourths-1 bottom">
      <div class="module">1/4</div>
    </div><!--

 --><div class="grid-cel fourths-1 bottom">
      <div class="module">1/4</div>
    </div><!--

 --><div class="grid-cel fourths-1 bottom">
      <div class="module">1/4</div>
    </div><!--

 --><div class="grid-cel fourths-1 bottom">
      <div class="module">1/4</div>
    </div><!--

  --><div class="grid-cel fourths-2 left">
       <div class="module">2/4</div>
     </div><!--

  --><div class="grid-cel fourths-2">
       <div class="module">2/4</div>
    </div><!--

  --><div class="grid-cel fourths-2 right">
       <div class="module">2/4</div>
     </div>
</div><!-- end of .grid -->




/**
 * General
 */

/* Changing the box-model to border-box*/

* {
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

/**
 * Grid
 */

.grid {
  text-align: center;
  padding: 0 0 0 1.25em;
}
.grid-cel {
  display: inline-block;
  padding: 0 1.25em 0 0;
  text-align: left;
  *zoom: 1;
  *display: inline;
}

/* Vertical alignment */

.grid-cel.top {
  vertical-align: top;
}
.grid-cel.bottom {
  vertical-align: bottom;
}

/* Thirds */

.thirds-1 {
  width: 33.333333%;
}

/* Fourths */

.fourths-1 {
  width: 25%;
}
.fourths-2 {
  width: 50%;
}

.fourths-2.left {
  margin-right: 50%;
}
.fourths-2.right {
  margin-left: 50%;
}

/**
 * Content
 */

.module {
  margin: 0 0 1.25em;
  text-align: center;
  line-height: 4.166666666666667;
  background-color: #dedede;
}

/* Simulate content height */
.grid-cel:nth-child(2) .module,
.grid-cel:nth-child(10) .module,
.grid-cel:nth-child(14) .module {
  line-height: 5.555555555555555;
}
.grid-cel:nth-child(3) .module,
.grid-cel:nth-child(9) .module,
.grid-cel:nth-child(13) .module {
  line-height: 6.944444444444445;
}
.grid-cel:nth-child(4) .module,
.grid-cel:nth-child(8) .module,
.grid-cel:nth-child(12) .module {
  line-height: 8.333333333333334;
}

Дополнительная информация

Некоторые CSS-фреймворки для сетки вместо float используют inline-block. Для примера, можно посмотреть Inuit или Griddle.

Рассылка
Подпишитесь на рассылку и получайте дайджест новостей и статей.
Никакого спама!
Подписаться