Display inline block что значит

Поддержка браузерами

12.0+ 8.0+ 3.0+ 4.0+ 7.0+ 3.1+

Описание

CSS свойство display указывает тип элемента. От типа элемента зависит то, как он будет отображаться на веб-странице.

Обратите внимание, что по умолчанию в CSS все элементы являются строчными (display:inline). Для переопределения варианта отображения элемента со строчного на блочный, браузеры используют встроенную таблицу стилей, задающую для каждого элемента стили, применяемые к нему по умолчанию. В старых версиях браузеров используется устаревшая встроенная таблица стилей, в которой нет правил для переопределения новых элементов, добавленных в HTML5, в блочные. Поэтому, для таких элементов как <section>, <header>, <nav>, <article>, <aside> и <footer>, способ отображения должен быть задан вручную в таблице стилей:

  <style>   section, header, nav, article, aside, footer { display: block; }  </style>  

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

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

Значение по умолчанию: inline
Применяется: ко всем элементам
Анимируется: нет
Наследуется: нет
Версия: CSS1
Синтаксис JavaScript: object.style.display=»inline»

Синтаксис

display: значение;

Значения свойства

Значение Описание
none Элемент исключается из общего потока, он не отображается на экране и под него не резервируется место на странице ( все элементы ведут себя как обычно, как будто этот элемент отсутствует в исходном коде).
block Элемент воспринимается браузером, как блочный (например, как <div>), т.е. имеет разрыв строки до и после элемента и занимает всю доступную ширину. Появляется возможность применения свойств для блочных элементов.
inline Элемент будет отображаться, как строчный (например, как <span>), содержимое блочных элементов, к которым было применено данное значение, будет начинаться с того места, где окончился предыдущий строчный элемент.
inline-block Элемент отображается, как строчный, но появляется возможность применять к нему свойства, доступные только блочным элементам (например: margin, padding).
list-item Элемент становится блочным и отображается, как элемент списка (тег <li>) с маркером перед началом содержимого.
table Определяет блочный элемент, который ведёт себя как <table>.
table-caption Элемент ведёт себя как <caption>.
table-cell Элемент ведёт себя как <td>.
table-column Элемент ведёт себя как <col>.
table-column-group Элемент ведёт себя как <colgroup>.
table-footer-group Элемент ведёт себя как <tfoot>.
table-header-group Элемент ведёт себя как <thead>.
table-row Элемент ведёт себя как <tr>.
table-row-group Элемент ведёт себя как <tbody>.
flex Преобразует элемент в блочный flex-контейнер. Все дочерние элементы данного контейнера автоматически становятся flex-элементами.
inline-flex Преобразует элемент в строчный flex-контейнер. Все дочерние элементы данного контейнера автоматически становятся flex-элементами.
inline-table Элемент будет вести себя как <table>, но не как блочный, а как строчно-блочный. То есть значение inline-table эквивалентно следующему CSS правилу:

table { display: inline-block;}
inherit Указывает, что значение наследуется от родительского элемента.

Пример

puzzleweb.ru

Основы

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).

  <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.

getinstance.info

Разрешите представить вам перевод статьи «Cross-Browser Inline-Block», написанной Райном Доэрти холодным февралем 2009 года. В статье рассказывается о верстке элементов списка с установкой для свойства display значения inline-block. Статья об этом, а также о трудностях, возникающих в процессе достижения результата и о методах их «лечения».

Inline-block, заманчивое значение для свойства display, которое обещает очень много, а выполняет совсем мало. Очень часто я получал PSD-файлы, подобные этому:

Display inline block что значит
и плакал.

Обычно такой способ отображения не вызывает проблем. Фиксированная ширина, фиксированная высота, float: left и готово. Если бы не одно, но! Дизайн должен отображаться корректно при любом количестве содержимого. В нашем случае, если в одном из блоков окажется чуть больше данных, то он «сломает» всю сетку.

Display inline block что значит

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

Начнем с простого примера, где у пунктов списка для свойства display установлено значение inline-block:

<ul>  <li>  <h4>This is awesome</h4>  <img src="1450821541436477177797"  alt="lobster" width="75" height="75"/>  </li> ... <ul>  <style>  li {  width: 200px;  min-height: 250px;  border: 1px solid #000;  display: inline-block;  margin: 5px;  } </style>

Результат выглядит корректно в Firefox 3, Safari 3 и в Opera:

Display inline block что значит

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

А происходит здесь следующее, базовая линия (baseline) каждого элемента <li> выравнивается с базовой линией родительского элемента <ul>. Вы спросите, что такое базовая линия? Лучше один раз увидеть, чем сто раз услышать:

Display inline block что значит

Базовая линия на рисунке выше обозначена линией, идущей через основание символов. Значением по-умолчанию для свойства vertical-align у inline и inline-block элементов является baseline. Это значит, что базовая линия элементов выравнивается с базовой линией родителя. На рисунке ниже представлен пример такого выравнивания:

Display inline block что значит

Как видите, каждая базовая линия блоков на рисунке выше выравнена по базовой линии текста «This is the baseline», который не является элементом <li>. Это просто текстовый узел, находящийся непосредственно в <ul>, помещенный туда в качестве индикатора расположения базовой линии элемента <ul>.

Получить желаемый изначально вариант выравнивания довольно просто, достаточно для свойства vertical-align указать значение top и получить в результате отличную сетку:

Display inline block что значит

Вот только это не работает в Firefox 2, IE 6 и 7:

Display inline block что значит

Для начала займемся Firefox 2.

Firefox 2 не поддерживает значение inline-block, зато отлично понимает специфичное для Мозиллы значение -moz-inline-stack для свойства display. Оно приводит к результатам, подобным действию inline-block. Когда мы добавляем его перед display: inline-block, то Firefox 2 игнорирует вышеуказанное, так как не понимает его, и использует -moz-inline-stack. Другие браузеры используют inline-block, игнорируя непонятное для них -moz-inline-stack.

<style>  li {  width: 200px;  min-height: 250px;  border: 1px solid #000;  display: -moz-inline-stack;  display: inline-block;  vertical-align: top;  margin: 5px;  } </style>

К сожалению, это вызывает небольшой баг:

Display inline block что значит

Честно, я не знаю, что является его причиной. К счастью, лечится он довольно просто обертыванием всего содержимого элемента <li> дополнительным <div>.

<li>  <div>  <h4>This is awesome</h4>  <img src="1450821541436477177797"  alt="lobster" width="75" height="75"/>  </div> </li>

Display inline block что значит

Теперь перейдем к IE 7. Он тоже не поддерживает inline-block, но мы можем использовать трюк, благодаря которому элементы <li> будут выводиться на экран так, будто используют значение inline-block. Как? Будем использовать hasLayout, волшебное свойство IE, делающее доступными многие манипуляции. Вы не можете явно указать для элемента hasLayout: true или сделать это каким-либо подобным простым образом, однако можете запустить механизм, указав zoom: 1.

Технически элементы с hasLayout, установленным в значение true сами отвечают за рендеринг самих себя и дочерних элементов. Объедините это с min-height и width, и получите результат, очень близкий к display: block. Это как магический порошок, заставляющий исчезать все появляющиеся при отображении проблемы.

Когда мы добавим zoom: 1 и *display: inline (звездочка является хаком для IE 6 и IE 7) для элементов <li>, то научим IE 7 отображать их совсем как inline-block:

<style>  li {  width: 200px;  min-height: 250px;  border: 1px solid #000;  display: -moz-inline-stack;  display: inline-block;  vertical-align: top;  margin: 5px;  zoom: 1;  *display: inline;  } </style>

Display inline block что значит

Почти готово. Остался лишь IE 6:

Display inline block что значит

IE 6 не поддерживает min-height, но взамен мы можем использовать его неверное обращение к свойству height. Установим для _height (обратите внимание на подчеркивание спереди) значение в 250px и получим все элементы <li> с нужной высотой. Если же содержимое превысит указанную величину, то просто растянет свой контейнер. Все остальные браузеры проигнорируют _height.

Финальный CSS и HTML выглядит так:

<style>  li {  width: 200px;  min-height: 250px;  border: 1px solid #000;  display: -moz-inline-stack;  display: inline-block;  vertical-align: top;  margin: 5px;  zoom: 1;  *display: inline;  _height: 250px;  } </style>  <li>  <div>  <h4>This is awesome</h4>  <img src="1450821541436477177797"  alt="lobster" width="75" height="75"/>  </div> </li>

habr.com

Чуть-чуть истории

Для молодых верстальщиков и фронтендеров инлайн-блоки — что-то очень древнее. Но ни в CSS1, ни в CSS2 никакого inline-block не было. Появился он только в CSS2.1, а стандартом CSS2.1 стал лишь в 2011-м, в эпоху «CSS3». В Firefox до 3-й версии (а версии тогда «жили» не по полтора месяца, а годами) inline-block приходилось эмулировать через -moz-inline-box, который был не чем иным, как… мозилловской реализацией старой версии флексбоксов (да-да, инлайн-блоки эмулировали флексбоксами, вот так ирония!). Как ни странно, IE это значение поддерживал (в нем оно впервые и появилось!), но… только для элементов с дефолтным inline (впрочем, это ограничение обходилось простым хаком). В общем, веселое было время:)

В начале 2010-х инлайн-блоки пережили всплеск популярности как основа для сеток. Они давали намного больше простора для разных вариантов выравнивания, чем надоевшие флоаты, и при этом не нуждались ни в каких «клиарфиксах». И по сей день они — один из самых популярных фолбэков для нормальных систем раскладки (флексбоксов и гридов).

Но как и флоаты, инлайн-блоки не были предназначены для раскладки блоков, так что своих хитрых хаков и тут хватало. Не случайно две статьи про такие хаки до сих пор у нас в числе самых популярных.

Не inline и не block

Во многих учебниках и руководствах для новичков про inline-block пишут, что он «строчный и блочный одновременно». Это неправда.

Inline-block — не inline-элемент (который может разрываться между строками, для которого вертикальные padding-и и border-ы не влияют на его положение, который игнорирует width и height и т.д.). И не блочный элемент (который пытается заполнить всю доступную ширину контейнера, margin-ы которого схлопываются с margin-ами соседей и даже потомков, в который могут вторгаться флоаты и т.д.). У него есть отдельные черты того и другого, но…

Пожалуй, проще всего понять, что такое inline-block на самом деле, обратившись к новой спецификации CSS Display 3 уровня.

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

  1. Внешнее поведение элемента — как он взаимодействует с соседями, т.е. в каком контексте форматирования он сам находится (или, как говорит спецификация, участвует);
  2. Внутреннее поведение элемента — как он влияет на размещение своих потомков, т.е. какой контекст форматирования действует в нем самом.

Для каждого поведения теперь есть отдельный набор ключевых слов, так что значения свойства display по новому стандарту будут составными. А старые значения с дефисом будут псевдонимами, алиасами для некоторых из таких комбинаций (говорю «будут», потому что браузеры еще не понимают составных значений, но в стандарт это уже заложено).

Какому же составному значению будет псевдонимом наш inline-block? Думаете, «inline block» («инлайновый снаружи, блочный внутри»)? Вот и нет! На самом деле его полное значение вот какое:

inline flow-root

Иначе говоря, он участник инлайнового контекста снаружи и начало нового блочного контекста форматирования внутри. Неожиданно! Но логично.

В инлайновом контексте форматирования ничего блочного быть не может. По построению. Как только в контейнере появляется что-то с display:block, контейнер по волшебству — то есть по стандарту — превращается из контейнера текста в контейнер блоков, и у нового блока появляются анонимные блочные соседи. Поэтому, чтобы вставить блочное содержимое в инлайновый контекст, нужен некий «переходник». Начало блочного контекста форматирования, ведущее себя как элемент строки — это он и есть. По-видимому, редакторы спецификаций сами поняли это только с появлением самого flow-root. Из-за этого «запоздалого прозрения» пришлось спешно решать еще одну проблему… но о ней чуть позже, в продолжениях.

То, что он сам участвует в инлайновом контексте — ключевая особенность инлайн-блока. Из нее вытекают и многие его преимущества, и почти все раздражающие недостатки. Они, кстати, будут и у inline-table, inline-flex и inline-grid, так что это знание пригодится во многих ситуациях.

Атомарный элемент строки

За одним редким исключением (о нем в другой раз), все «переходники» между инлайновым и каким-либо другим контекстами форматирования ведут себя как сплошные прямоугольники, при этом встроенные в строку текста, как буквы или эмодзи. Кстати, так же себя ведут и «переходники» между текстом и чем-то, вообще не относящимся к CSS — замещаемые элементы (картинки, видео…) и виджеты (напр. элементы форм), как их называют в HTML5. CSS называет такие неделимые прямоугольники атомарными элементами строки (atomic inline boxes).

Ключевой момент здесь то, что это элементы строки. А значит, подчиняются непростым для понимания правилам инлайнового контекста:

See the Pen Приключения инлайн-блоков в строчном контексте форматирования by Ilya Streltsyn (@SelenIT) on CodePen.

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

Минимальное пространство по высоте

Любой инлайн-блок, даже самый маленький, заставляет браузер использовать целый контейнер строки, минимальная высота которого определяется свойством line-height родителя. Увеличить (распереть) эту высоту инлайн-блок может, но уменьшить — нет. А поскольку высота строки складывается из двух частей — над базовой линией и под ней, возможна ситуация, когда инлайн-блок «распирает» верхнюю часть, «отпихивая» собой базовую линию от «потолка» контейнера строки (как пустой инлайн-блок в нашем примере), но пространство под ним остается! Даже если крошечный инлайн-блок будет единственным потомком родителя, он всё равно займет целую строку.

Так что, если у крошечной кнопки или иконки вдруг появились «непонятные отступы», которых не видно даже в браузерном отладчике (!), просто вспомните про эту особенность. Побороть ее можно, задав контейнеру очень маленькую line-height (вплоть до 0). Но лучше сразу использовать для таких вещей не инлайн-блоки, а обычные блоки или флексбоксы — там ни с чем бороться не надо.

Пробелы имеют значение

Про эту «проблему», думаю, читатели нашего сайт давно знают (см. вторую по популярности статью:). Но упомянуть ее надо. Коротко: в инлайновом контексте любые пробельные символы подряд (сами пробелы, табуляции и переводы строки, в т.ч. между тегами) внутри текста, при дефолтном white-space: normal, отображаются на экране как один пробел. В примере выше видно, почему это не баг: ведь инлайн-блоки вписываются в текст. А значит, отделяются пробелами от соседних слов на общих основаниях и прижимаются вплотную к знакам препинания и другим символам, если надо. Если нужно другое поведение, лучшее решение — использовать что-то другое. Не инлайн-блоки, а, например, те же флексбоксы.

Здесь же стоит упомянуть, что по умолчанию инлайн-блок может переноситься на новую строку, даже если перед ним нет пробела. Так сложилось исторически. Если нужно «приклеить» инлайн-блок к соседнему слову, чтоб они переносились только вместе (например, иконку к ссылке), можно, например, обернуть их в общий <span> с white-space: nowrap.

«Странное» действие middle

В последней строке примера видно, что второй инлайн-блок, с vertical-align: middle, не выровнен по середине контейнера строки, а стоит гораздо ниже. Можно подумать, что vertical-align вообще не сработало, но если присмотреться, видно, что текст в нем на пиксель ниже общей базовой линии.

Разгадка в том, что middle выравнивает середину высоты инлайн-блока с серединой высоты строчных букв текста родительского элемента. Т.е. ставит ее на 0.5ex выше базовой линии. Середина контейнера строки с этой точкой обычно не совпадает. Поэтому такое выравнивание сдвигает инлайн-блок и, как часто бывает в строчном контексте, может дополнительно «распереть» контейнер строки и вызвать еще один непонятный отступ над (или под) элементом. Будьте начеку!

Уникальная базовая линия

Эту особенность я даже вынес в отдельный раздел, потому что она (на сегодняшний день) уникальна именно для инлайн-блоков: их базовой линией, по которой они выравниваются относительно окружающего текста, считается базовая линия последней строки текста внутри них. Это видно на примере «инлайн-блока в две строки» выше. У элементов с другими display: inline-что-то (о них мы позже поговорим отдельно) базовая линия берется не по последней, а по первой строке. Чуть ниже мы увидим, как эта уникальность может нам пригодиться.

Важный нюанс: если контента в инлайн-блоке нет, то базовой линией считается нижняя граница его внешнего отступа (см. последний инлайн-блок в примере). Если его overflow не равно visible — тоже. Так что если под пустыми или обрезанными инлайн-блоками появляется больше пустого места, чем под непустыми — это не баг (если мешает, можно просто поменять vertical-align). Уникален ли этот нюанс для инлайн-блоков, или другие display: inline-* должны его перенять — было неясно, но (добавлено 22.08.2018) оказалось, что да, это тоже исключение из правила.

inline-block в роли блока

И всё же многим атомарный элемент строки очень похож на блок. У него есть все элементы боксовой модели (margin/border/padding), и все они работают предсказуемо, увеличивая занимаемое элементом место (как мы опять же видели в примере). У него есть размеры. В частности, ему можно задать width: 100% (минус боковые padding-и, если надо) — и он растянется на всю доступную ширину контейнера. И внутри у него может быть полноценное блочное содержимое — заголовки, абзацы, даже флоаты и таблицы (если надо). Чем не блок? Но всё же существенная разница есть.

Неуправляемая анонимная блочная обертка

Контейнер строки, в котором живет инлайн-блок и который нельзя сделать ниже определенного минимального размера, никуда не девается. И если рядом с этим контейнером строки оказывается что-то блочное, то он оборачивается в анонимный блок. То есть на самом деле у нас получается этакая «матрёшка»: снаружи анонимный обычный блок (с параметрами по умолчанию — на всю доступную ширину родителя, отступы по нулям и т.п.). В нем — строка «виртуального» текста, со свойствами, унаследованными от родительского контейнера. Внутри этой строки — атомарный элемент на всю ее ширину. И только внутри него — отдельный блочный контекст форматирования со своим блочным содержимым.

Анонимный блок всегда продолжает родительский контекст форматирования, поэтому «ужиматься», чтобы разместиться рядом с флоатом, не умеет. Сам инлайн-блок — атомарный элемент строки, как длинное неразрывное слово — тоже. Поэтому, если контента в нем много, инлайн-блок будет стремиться заполнить всю ширину родителя, а не только свободное место рядом с флоатом. Это еще одно важное отличие инлайн-блока от обычного, блочного flow-root.

See the Pen Сравнение обычного flow-root и инлайн-блока (inline flow-root) в блочном окружении by Ilya Streltsyn (@SelenIT) on CodePen.

Много строк внутри — одна строка снаружи

Еще раз отметим, что с точки зрения родительского блочного контейнера инлайн-блок в своей анонимной блочной обертке считается единственной строкой «призрачного» текста. В некоторых случаях это бывает полезно (см. ниже).

Полезные применения inline-block

Тривиальное

Прямое назначение инлайн-блоков — вставка чего-то «блокоподобного» (кнопки, текстовые иконки, теги, беджи и т.п.) прямо в текст.

See the Pen wxdavy by Ilya Streltsyn (@SelenIT) on CodePen.

Хак: фолбэк для флексбоксов (и гридов)

С оговорками, но всё же у текста в CSS есть аналоги многих возможностей флексбоксов. Включая многие виды горизонтального (влево, вправо, центр, по ширине) и вертикального (по базовой линии, по верхнему или нижнему краю контейнера строки…) выравнивания. Поэтому инлайн-блоки издавна используют как своего рода «флексбоксы (а то и гриды) для бедных».

Но они не владеют главным «волшебством» самого свойства flex (автоматический размер) и не умеют подстраиваться к высоте соседей. И, наверное, не стоит тратить время и силы, пытаясь воспроизвести в фолбэке все красоты современного решения. Если в ископаемом браузере, который к тому же наверняка работает на ископаемом же «железе», блоки просто выстроены по горизонтали в цепочку, и макет не разваливается — его неизбалованному пользователю этого достаточно.

Хак: еще одна альтернатива клиарфиксу

Как любой элемент, создающий блочный контекст форматирования, inline-block не выпускает наружу ни «плавающих» потомков, ни margin-ов обычных, всегда охватывая их по габаритам. Поэтому его в принципе можно использовать «вместо клиарфикса». Но помните об издержках неуправляемой анонимной обертки. И лучше используйте «нормальный», блочный flow-root. А где его нет — подбирайте наиболее подходящий для вас вариант из сравнительной таблицы (мой фаворит — column-count: 1;).

Хак: запрет переноса строк в колонках

В многоколоночной раскладке по умолчанию блоки могут разрываться и переноситься в новую колонку по частям. Обычно так и надо, но иногда нужно какой-то блок перенести только целиком. Есть давний хак, когда для этого таким блокам меняют display на inline-block. Теперь вы знаете, благодаря чему он работает: ведь для блочного контекста весь анонимный блок с инлайн-блоком внутри — это одна строка!

Хак: выравнивание флекс- или грид-элементов по последней строке заголовка

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

See the Pen MBmwRw by Ilya Streltsyn (@SelenIT) on CodePen.

Допустим, маркетолог вот такого каталога требует, чтобы товары в нем были непременно выровнены по низу заголовков (или по верху описаний, что то же самое). Первое, что приходит на ум — таблица, либо грид с разбивкой заголовка и текста в разные грид-элементы. Но если сделать весь header каждого товара инлайн-блоком, этот инлайн-блок окажется единтственным содержимым первой как-бы-текстовой строки, и ее базовая линия пройдет по последней строке этого инлайн-блока. Теперь достаточно выровнять сами товары по этой базовой линии, т.е. align-items: baseline — и вуаля.

Примечание: к сожалению, в Firefox с выравниванием в гриде нашелся странный баг. Я долго не мог воспроизвести его отдельно, потому что задавал заголовку явную ширину (чтоб форсировать перенос на новую строку), а оказалось, что эта ширина (не в процентах, и не больше 100% по факту) тот баг… почему-то фиксит:). Так что в примере как раз применен этот «фикс», но возможности метода это изрядно ограничивает.  Добавлено: похожая проблема в iOS Safari, но там даже «фикс» не помогает:(

Зато со флексбоксами никаких подобных проблем пока не нашлось, что радует.

Миф об «инлайн-блочных элементах в HTML»

Напоследок — небольшой курьез. С развитием CSS старинное деление HTML-элементов по внешнему виду, на «блочные» и «строчные», стало порождать домыслы о том, что другим видам CSS-отображения тоже могут соответствовать какие-то свои категории контента в HTML. Так, видимо, родился миф об «инлайн-блочных элементах в HTML». Чаще всего в таковые «записывают» элемент <button>, реже <img> и др. Так вот, это ерунда.

В HTML не было и нет такой категории элементов, и выделять ее нет смысла, полезной информации она не даст. Классифицируйте элементы по их логической роли: структурные, заголовочные, текстовые, интерактивные и т.д., как это делают современные стандарты. Эта классификация сразу даст вам подсказку, для чего элемент может использоваться (например, структурный — для разметки крупных логических блоков страницы, чтобы пользователю скринридера было удобно легко переходить между ними, поэтому их не должно быть на странице слишком много) и что в него можно вкладывать (скажем, интерактивные элементы обычно нельзя вкладывать друг в друга, чтобы браузер не запутался, чьё действие выполнять). А внешний вид любому (ну, почти) элементу можно придать любой — с помощью CSS. В том числе и вид инлайн-блока.

В CSS — и в этой статье — термины «блок» и «строчный элемент»/«элемент строки» относятся исключительно к внешнему виду, и могут относиться вообще не к элементу DOM, а к псевдоэлементу. Общего с устаревшей классификацией элементов из HTML 4 у них не больше, чем у JavaScript и Java. Не дайте себя запутать, и да пребудет с вами CSSила! 🙂

css-live.ru

Как превратить блочный тег в строчный и наоборот с помощью display inline и block

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

Для каждого тега, соответствующего конкретному элементу, даны начальные значения по умолчанию. Подробная информация по этому вопросу предоставлена на специальной странице валидатора W3C (Default style sheet for HTML 4). Скажем, здесь целый список HTML тегов, которым соответствует значение block:

«>

Кстати, если display вообще не указан, то для конкретного тега будет применено именно дефолтное значение. В этом случае при необходимости изменить вид HTML вебэлемента следует просто прописать ему нужный параметр display. Это еще раз подтверждает тесную связь между языком гипертекстовой разметки и каскадными таблицами стилей.

Если мы посмотрим на перечень всех значений для свойства дисплей в таблице валидатора W3C, то обнаружим следующее:

«>

Здесь перечислены все возможные параметры для дисплей. В том случае, если не указано конкретное значение, по умолчанию будет действовать display inline, что соответствует тегу строки. Потому на странице спецификации «Defolt style sheet for HTML 4» теги, которые по умолчанию являются строчными, вообще отсутствуют в списке.

Как вы помните, в общем случае CSS правила дают команду браузеру, как отображать тот или иной вебэлемент. Скажем, для блочных и строчных это выглядит так: display:block и display:inline соответственно.

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

Возьмем для примера часто встречающиеся при создании вебсайтов теги, для удобства придав каждому цветовой оттенок фона с помощью CSS свойства background:

<H2 style="background:#E8987A;">Заголовок</H2>  <p style="background:#AD814F;">Текст</p>  <span style="background:#60D4AE;">Тег span</span>

В итоге данные вэбэлементы отобразятся в браузере в полном соответствии со своими умолчательными параметрами CSS правила дисплей. Вся эта композиция на вебстранице будет иметь такой вид (здесь можете посмотреть в живую):

«>

Заголовок H2 и тег P являются блочными (block), поэтому занимают по ширине всю доступную область. Один из важнейших структурных вебэлементов SPAN — строчный (inline), по этой причине его ширина ограничивается содержанием. Далее пропишем для P правило инлайн:

<p style="display:inline;background:#AD814F;">Текст</p>

Теперь в нашем примере произойдут вот такие превращения:

«>

Эти изменения вы можете проследить в отдельной вкладке. Как видим, текстовый элемент превратился в строчный и его ширина теперь определяется входящим контентом («Текст»). SPAN занял место в строке рядом с ним, поскольку пространство позволяет.

Абсолютно также можно провести обратную операцию и строчный вебэлемент сделать блочным. Применим теперь параметр блок к SPAN:

<span style="display:block;background:#60D4AE;">Тег span</span>

После такого редактирования картина будет таковой:

«>

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

Display list-item — делаем списки из блочных элементов

Дальше поэкспериментируем немного в области создания HTML списков, которые, как известно, составляются с помощью тегов UL, OL, LI. Мы же обойдемся без них, применим для выполнения этой задачи лишь правило display:list-item.

Для этого возьмем заголовок из предыдущего примера, а также несколько простых абзацев. Но так все-таки не остается видимой области для маркеров. Чтобы решить задачу в полном объеме, требуется задать отступы слева для всех пунктов списка с помощью свойства margin-left, указав ему конкретное значение (например, 25 пикселов):

<h2 style="background:#E8987A;">Заголовок</h2>  <p style="background:#AD814F;display:list-item;margin-left:25px;">Текст 1<p>  <p style="background:#AD814F;display:list-item;margin-left:25px;">Текст 2<p>  <p style="background:#AD814F;display:list-item;margin-left:25px;">Текст 3<p>

Результирующий вид окажется таким:

«>

Таким образом маркированный список готов. При необходимости вид самих маркеров можно настроить как угодно, применив правило CSS list-style. Вполне возможно произвести и обратное действие. То есть при наличии созданного на основе тех же UL и LI списка обратить его в стандартные абзацы, указав block для каждого элемента LI.

Как я отметил выше, у свойства CSS дисплей существует еще немало параметров, посредством которых можно, например, оформлять таблицы. Каждому вебэлементу HTML таблицы соответствует определенный параметр display:

«>

Но подробно расписывать данный аспект я не намерен, поскольку эта тема требует отдельной публикации, да и применяются данные значения весьма редко, не говоря уже о том, что даже популярные браузеры воспринимают табличные CSS правила по-разному, особенно это касается старых версий Интернет Эксплорера. Так что ограничусь пока общей информацией.

goldbusinessnet.com

Использование inline-block элементов для создания кнопок

Сделаем еще один небольшой сравнительный анализ. В примере ниже представлены ссылки, внешний вид которых с помощью css-стилей отображает их как кнопки. Но 2 из них имеют display: inline-block, одна — display: inline (по умолчанию заданный в спецификации для ссылки) и еще одна  — display: block. Над каждой кнопкой подписано, каким образом она была отформатирована.

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

Что касается кнопок с display: inline-block и display: inline, у которых размер был сформирован padding-ами, то при добавлении текста они просто расширяются. Оранжевая кнопка  Sale, у которой размер имеет фиксированную ширину и высоту, увеличивается за счет добавленного текста вниз, хотя ни фон, ни рамка на этот текст не распространяются. Кнопка-ссылка с display: block изначально занимает всю ширину родительского элемента, поэтому добавление текста не влияет на ее размер на больших экранах. А вот на маленьких в ней текст за счет фиксированной высоты тоже выходит за пределы фона вниз. Еще можно заметить, что для желтой кнопки с display: inline несколько иначе определяются отступы от заголовка сверху — она расположена чуть выше всех остальных кнопок, хотя margin ни для одной из них в свойствах задан не был. Форматирование кнопок определялось такими свойствами:

Использование inline-block элементов для создания колонок

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

Например, у нас есть такая html-разметка: внутри родительского элемента с классом wrap есть 3 колонки с классами .col с заголовком и 3-мя абзацами. Можно воспользоваться аббревиатурой Emmet:

Нажимаем Tab и получаем разметку:

Для всех элементов добавим свойство box-sizing: border-box, чтобы ширина элементов не зависела от padding и border, а для родительского элемента .wrap зададим следующие максимальную ширину и внешние отступы:

Для 3-х колонок ширина их контейнера представляет собой 100%. Мы хотим, чтобы между колонками были отступы по 2%. Поскольку нам необходимы отступы только между первой и второй, а затем между второй и третьей, но не после 3-й колонки, то пространство контейнера следует разделить следующим образом: 100% — 4% margin = 96%. Далее 96%/3= 32% — получаем width каждой колонки. Затем используем это для свойств наших колонок с классом .col:

Обязательно нужно отключить правый margin для последней колонки, что мы и сделали с помощью псевдокласса :last-child.

И вот, что мы получим в итоге:

Вуа-ля — и нет 3-х колонок, которые выстроились в одну линию. Вместо этого есть 2 колонки в одном ряду + одна в нижнем ряду. Совсем не то, что нужно. В чем же причина «сваливания» последней колоки?

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

Чтобы этого избежать, имеет смысл воспользоваться функцией calc(), которая появилась в стандарте CSS3 и давно уже поддерживается современными браузерами. Важным моментом в ее использовании является установка пробелов ДО и ПОСЛЕ знака минус:

Результат уже намного лучше:

Для того чтобы колонки с разным количеством текста не выбивались из одной линии, необходимо использовать свойство vertical-align чаще всего со значением top. Добавим его к нашим css-свойствам:

В результате получим колонки разной высоты, но выровненные по верхней линии:

You May Also Like

About the Author: admind

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.