为什么宽度适用于带有内联显示的按钮?
Why does width apply to a button with display inline?
根据 MDN,button
是一个内联元素。
但是,按钮元素有 default styling with display: inline-block
(See this question)
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>
现在,根据 spec:width
不适用于内联元素(不可替换)
Applies to: all elements but non-replaced inline elements, table rows,
and row groups
既然如此:
为什么宽度仍然适用于内联 button
元素?
如评论中所述,我很确定这与特定于浏览器的呈现行为有关,这是典型的表单元素。当您在按钮上设置 display: inline
时,我相信发生的事情是……什么都没有。实际上,它与典型的浏览器默认值 display: inline-block
相同,width
属性 确实适用。
参考section 10.2,它描述了width
属性本身。特别是它解释了为什么 width
属性 不适用于内联元素(或 内联框 ):
This property does not apply to non-replaced inline elements. The content width of a non-replaced inline element's boxes is that of the rendered content within them (before any relative offset of children). Recall that inline boxes flow into line boxes. The width of line boxes is given by the their containing block, but may be shorted by the presence of floats.
简而言之,是因为行内元素的内容驻留在line boxes中。 line box的宽度不能直接控制;它完全由包含块和任何附带的浮动决定。您可以在 section 9.4.2 中查看行框渲染示例,它描述了行内格式化上下文。
如果 display: inline
实际上使按钮呈现为内嵌框,all its contents would spill over 并且它看起来或功能将不再像按钮。想要防止这种情况发生是有道理的,我认为这正是浏览器所做的。
那么他们究竟做了什么来防止这种情况发生呢?按钮是可替换元素吗?我不能肯定地说。但请注意,在 section 9.2.2 中,它表示:
Inline-level boxes that are not inline boxes (such as replaced inline-level elements, inline-block elements, and inline-table elements) are called atomic inline-level boxes because they participate in their inline formatting context as a single opaque box.
第 10 节没有明确提及原子行内级框,但它确实有用于计算行内替换元素的尺寸的部分,以及内联块元素无论是替换还是非替换,所有这些都被认为是原子的如上所述内联。在所有这些情况下,如果 width
属性 不是 auto
.
,则它会正常应用
因此,虽然按钮是否是替换元素仍有争议,但对于这个问题而言,这可能根本无关紧要。但它仍然是 some 一种原子内联元素,因为它仍然参与内联格式化上下文。不过,就其价值而言,如果您不设置宽度,它似乎会缩小以适合其内容,因此在这种情况下,它的行为可能更接近内联块。人们可以说 display
的 actual value 变成了 inline-block
,尽管这从未反映在开发人员工具中,因为计算值不会改变(同样是特定于浏览器的渲染的副作用行为)。
因为像 Boltclock 一样,我不认为对此有一个简单的答案,这既是我对这个问题的想法的转储,也是答案,但我希望它能提供信息。
CSS显示属性虽然表面上很简单,但实际上包含了很多方面。 CSS 级别 3 规范草案 css-display 捕获了其中的一些复杂性,但似乎仍未充分涵盖它。
HTML5 规范说 the rendering of <button>
elements:
When the button binding applies to a button element, the element is
expected to render as an 'inline-block' box rendered as a button whose
contents are the contents of the element.
一个inline-block
盒子有很多方面:
1。一个 inline-level 元素
这意味着它参与了行框内的内联格式化上下文。它与同一行上的其他元素按顺序流动。 line box 的内容可以在其容器上与 text-align:center
属性 居中对齐,并且通过避免浮动元素来缩短 line box。
2。应用 width property and the auto value is shrink-to-fit
与未替换的 display:inline
元素不同,宽度值适用。而且,如果未指定宽度值,则会应用收缩以适合算法来确定宽度。这类似于浮动元素或 display:table
元素,但不同于 display:block
元素,后者在未指定宽度时尽可能宽。它也不同于替换内联元素和替换内联块元素,如果没有指定宽度,则使用它们的固有宽度(如果它们有宽度),如果没有则使用默认值 300px。收缩到适合是替换元素的无意义概念。
3。一个block-container元素
块容器元素由一堆行框组成。内容从一个行框流向下一个行框,行内块元素的高度增长(可能会溢出)以完全包含所有行框。
4。基线是last contained line box
的基线
当行内块元素包含多行时,其基线是这些行中的最后一行。这与浮动或 display:table-cell
元素不同,它们也是收缩以适合块容器元素。浮动在正常流之外,因此它们没有基线,display:table-cell
元素有一个基线,即它们的 first 行框的基线。具有多行的按钮会根据最后一个行框规则垂直对齐。
现在,这对于默认显示设置来说很好。而 HTML5 渲染要求意味着即使指定值为 inline
,按钮显示的使用值为 inline-block
。但它不考虑指定值为 block
时的行为。在这种情况下,元素前后都有一个换行符,并且 margin:auto
像 display:block
元素那样使框居中,而不是 inline-block
所期望的那样。
但是,它的指定值 auto
的宽度像内联块一样收缩以适合,而 display:block
的预期行为是尽可能宽。据我所知,唯一表现如此的显示值是 display:table
,但没有其他迹象表明正在使用 display:table
。
所以我在规范中找不到与此完全匹配的内容。我们只能希望 css-display 规范完成后,它将涵盖此行为。
有 2 种类型的元素。
- 非替换元素
- 替换元素
Button
属于替换元素类别。
您可以在下面找到更多信息 link。
所以,对于button
,根据spec,就变成对了。
内联,非替换元素
width
属性不适用。 margin-left
或 margin-right
的计算值 auto
变为 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
的使用值在 CSS 2.1 中未定义。但是,建议如果包含块的 width
本身不依赖于被替换元素的 width
,则 width
的使用值是从用于块的约束方程中计算的水平,正常流程中的非替换元素。
如果width
的计算值为auto
,并且该元素具有内在的width
,那么内在的width
就是[=13的使用值=].
若width
的计算值为width
,但满足上述条件none,则width
的使用值为300px
.但是,如果 300px
太宽而无法容纳设备,UA 应该使用具有 2:1 比例且适合设备的最大矩形的 width
代替。
根据 MDN,button
是一个内联元素。
但是,按钮元素有 default styling with display: inline-block
(See this question)
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>
现在,根据 spec:width
不适用于内联元素(不可替换)
Applies to: all elements but non-replaced inline elements, table rows, and row groups
既然如此:
为什么宽度仍然适用于内联 button
元素?
如评论中所述,我很确定这与特定于浏览器的呈现行为有关,这是典型的表单元素。当您在按钮上设置 display: inline
时,我相信发生的事情是……什么都没有。实际上,它与典型的浏览器默认值 display: inline-block
相同,width
属性 确实适用。
参考section 10.2,它描述了width
属性本身。特别是它解释了为什么 width
属性 不适用于内联元素(或 内联框 ):
This property does not apply to non-replaced inline elements. The content width of a non-replaced inline element's boxes is that of the rendered content within them (before any relative offset of children). Recall that inline boxes flow into line boxes. The width of line boxes is given by the their containing block, but may be shorted by the presence of floats.
简而言之,是因为行内元素的内容驻留在line boxes中。 line box的宽度不能直接控制;它完全由包含块和任何附带的浮动决定。您可以在 section 9.4.2 中查看行框渲染示例,它描述了行内格式化上下文。
如果 display: inline
实际上使按钮呈现为内嵌框,all its contents would spill over 并且它看起来或功能将不再像按钮。想要防止这种情况发生是有道理的,我认为这正是浏览器所做的。
那么他们究竟做了什么来防止这种情况发生呢?按钮是可替换元素吗?我不能肯定地说。但请注意,在 section 9.2.2 中,它表示:
Inline-level boxes that are not inline boxes (such as replaced inline-level elements, inline-block elements, and inline-table elements) are called atomic inline-level boxes because they participate in their inline formatting context as a single opaque box.
第 10 节没有明确提及原子行内级框,但它确实有用于计算行内替换元素的尺寸的部分,以及内联块元素无论是替换还是非替换,所有这些都被认为是原子的如上所述内联。在所有这些情况下,如果 width
属性 不是 auto
.
因此,虽然按钮是否是替换元素仍有争议,但对于这个问题而言,这可能根本无关紧要。但它仍然是 some 一种原子内联元素,因为它仍然参与内联格式化上下文。不过,就其价值而言,如果您不设置宽度,它似乎会缩小以适合其内容,因此在这种情况下,它的行为可能更接近内联块。人们可以说 display
的 actual value 变成了 inline-block
,尽管这从未反映在开发人员工具中,因为计算值不会改变(同样是特定于浏览器的渲染的副作用行为)。
因为像 Boltclock 一样,我不认为对此有一个简单的答案,这既是我对这个问题的想法的转储,也是答案,但我希望它能提供信息。
CSS显示属性虽然表面上很简单,但实际上包含了很多方面。 CSS 级别 3 规范草案 css-display 捕获了其中的一些复杂性,但似乎仍未充分涵盖它。
HTML5 规范说 the rendering of <button>
elements:
When the button binding applies to a button element, the element is expected to render as an 'inline-block' box rendered as a button whose contents are the contents of the element.
一个inline-block
盒子有很多方面:
1。一个 inline-level 元素
这意味着它参与了行框内的内联格式化上下文。它与同一行上的其他元素按顺序流动。 line box 的内容可以在其容器上与 text-align:center
属性 居中对齐,并且通过避免浮动元素来缩短 line box。
2。应用 width property and the auto value is shrink-to-fit
与未替换的 display:inline
元素不同,宽度值适用。而且,如果未指定宽度值,则会应用收缩以适合算法来确定宽度。这类似于浮动元素或 display:table
元素,但不同于 display:block
元素,后者在未指定宽度时尽可能宽。它也不同于替换内联元素和替换内联块元素,如果没有指定宽度,则使用它们的固有宽度(如果它们有宽度),如果没有则使用默认值 300px。收缩到适合是替换元素的无意义概念。
3。一个block-container元素
块容器元素由一堆行框组成。内容从一个行框流向下一个行框,行内块元素的高度增长(可能会溢出)以完全包含所有行框。
4。基线是last contained line box
的基线当行内块元素包含多行时,其基线是这些行中的最后一行。这与浮动或 display:table-cell
元素不同,它们也是收缩以适合块容器元素。浮动在正常流之外,因此它们没有基线,display:table-cell
元素有一个基线,即它们的 first 行框的基线。具有多行的按钮会根据最后一个行框规则垂直对齐。
现在,这对于默认显示设置来说很好。而 HTML5 渲染要求意味着即使指定值为
inline
,按钮显示的使用值为 inline-block
。但它不考虑指定值为 block
时的行为。在这种情况下,元素前后都有一个换行符,并且 margin:auto
像 display:block
元素那样使框居中,而不是 inline-block
所期望的那样。
但是,它的指定值 auto
的宽度像内联块一样收缩以适合,而 display:block
的预期行为是尽可能宽。据我所知,唯一表现如此的显示值是 display:table
,但没有其他迹象表明正在使用 display:table
。
所以我在规范中找不到与此完全匹配的内容。我们只能希望 css-display 规范完成后,它将涵盖此行为。
有 2 种类型的元素。
- 非替换元素
- 替换元素
Button
属于替换元素类别。
您可以在下面找到更多信息 link。
所以,对于button
,根据spec,就变成对了。
内联,非替换元素
width
属性不适用。 margin-left
或 margin-right
的计算值 auto
变为 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
的使用值在 CSS 2.1 中未定义。但是,建议如果包含块的 width
本身不依赖于被替换元素的 width
,则 width
的使用值是从用于块的约束方程中计算的水平,正常流程中的非替换元素。
如果width
的计算值为auto
,并且该元素具有内在的width
,那么内在的width
就是[=13的使用值=].
若width
的计算值为width
,但满足上述条件none,则width
的使用值为300px
.但是,如果 300px
太宽而无法容纳设备,UA 应该使用具有 2:1 比例且适合设备的最大矩形的 width
代替。