Подтвердить что ты не робот

Почему ширина применяется к кнопке с встроенным дисплеем?

Согласно MDN, a button является встроенным элементом.

Однако элементы кнопки стиль по умолчанию с display: inline-block (см. этот вопрос)

button, textarea,
input, select   { display: inline-block }

Пока все хорошо.

Однако:

Если теперь я устанавливаю кнопку с display:inline - ширина применяется!

DEMO

button,
div {
  width: 200px;
  border: 1px solid red;
  display: inline;
}
<button>button</button>
<div>div</div>
4b9b3361

Ответ 1

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

Обратитесь к разделу 10.2, в котором описывается свойство width. В частности, это объясняет, почему именно свойство width не применяется к встроенным элементам (или встроенным блокам):

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

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

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

Так что же они делают, чтобы предотвратить это? Является ли кнопка замененным элементом? Не могу сказать точно. Но обратите внимание: в разделе раздел 9.2.2 говорится:

Ящики встроенного уровня, которые не являются встроенными блоками (например, замененными элементами линейного уровня, элементами встроенного блока и элементами inline-table), называются атомарными ящиками на уровне строки, поскольку они участвуют в их встроенном контексте форматирования как единый непрозрачная коробка.

В Разделе 10 явно не упоминаются атомарные ящики на уровне строки, но в нем есть разделы для вычисления измерений для встроенных замещаемых элементов, а также элементы встроенного блока, заменяемые или не замененные, все из которых считаются атомными линиями, как упомянутое выше. Во всех этих случаях свойство width применяется как обычно, если оно не auto.

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

Ответ 2

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

Хотя свойство отображения CSS поверхностно довольно просто, оно фактически содержит множество аспектов. Проект черновика уровня 3 css-display отражает некоторые из этих сложностей, но по-прежнему не охватывает его адекватно.

Спецификация HTML5 указывает рендеринг элементов <button>:

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

В блоке inline-block есть несколько аспектов:

1. Элемент встроенного уровня

Это означает, что он участвует в встроенном контексте форматирования в строке строки. Он течет последовательно с другими элементами, находящимися в одной строке. Содержимое линейного окна может быть выровнено по центру с свойством text-align:center на его контейнере, а поле строки укорачивается, избегая плавающих элементов.

2. Применяет свойство width, а значение auto shrink-to-fit

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

3. Элемент block-container

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

4. Базой является базовый уровень последнего содержащегося в нем поля строки

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


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

Однако его ширина для заданного значения auto сжимается до соответствия, как встроенный блок, тогда как ожидаемое поведение для display:block по возможности является максимально возможным. Насколько мне известно, единственное отображаемое значение, которое ведет себя так: display:table, но нет ничего другого, чтобы предположить, что используется display:table.

Так что в спецификации нет ничего, что можно найти точно. Мы можем только надеяться, что когда спецификация css-display завершится, она будет охватывать это поведение.

Ответ 3

Существует 2 типа элементов.

  • Незаменяемые элементы
  • Замененные элементы

Button принадлежит к категории замещенных элементов.

Вы можете найти более подробную ссылку ниже.

Итак, для Button, согласно spec, он становится правильным.

Встроенные, незаменяемые элементы

Свойство width не применяется. Вычисленное значение auto для margin-left или margin-right становится используемым значением 0.

Встроенные, замененные элементы (Этот раздел относится к Button)

Вычисленное значение auto для margin-left или margin-right становится используемым значением 0.

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

Если height и width оба имеют вычисленные значения auto, и элемент не имеет собственного width, но имеет внутреннее height и внутреннее отношение; или если width имеет вычисленное значение auto, height имеет некоторое другое вычисленное значение, и элемент имеет внутреннее отношение; то используемое значение width равно:

 (used height) * (intrinsic ratio)

Если height и width оба имеют вычисленные значения auto, и элемент имеет внутреннее отношение, но не имеет встроенных height или width, тогда используемое значение width равно undefined в CSS 2.1. Однако предполагается, что если содержащийся блок width сам по себе не зависит от замещенного элемента width, то используемое значение width вычисляется по уравнению ограничения, используемому для блочных, незаменяемых элементов в нормальном потоке.

Если width имеет вычисленное значение auto, а элемент имеет собственный width, то это внутреннее width является используемым значением width.

Если width имеет вычисленное значение width, но ни одно из приведенных выше условий не выполняется, тогда используемое значение width становится 300px. Но если 300px слишком велико, чтобы соответствовать устройства, UA должны использовать width самого большого прямоугольника, который имеет соотношение 2: 1 и подходит для устройства.

Ответ 4

Попробуйте установить маржу на -2px.

button,
div {
  width: 200px;
  border: 1px solid red;
  display: inline;
  margin:-2px -2px -2px -2px;
}

Причина в том, что между элементами все еще остается пространство, потому что даже display:inline; не удаляет все пространство. Он удаляет стиль по умолчанию для блока, который обычно применяется браузером. Тем не менее, край -2px удаляет все пространство между кнопкой и div.

FIDDLE