为什么宽度适用于显示内联的button?

根据MDN ,一个button是一个内联元素。

但是,button元素具有默认样式和display: inline-block (请参阅此问题 )

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

到现在为止还挺好。

然而:

如果我现在设置display:inlinebuttondisplay:inline – 宽度仍然适用!

DEMO

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

现在,根据规范 : width不适用于内联元素(不被replace)

适用于:所有元素,但未被replace的行内元素,表行和行组

既然如此:

为什么宽度仍然适用于内联button元素?

正如在评论中提到的,我很确定这与浏览器特定的呈现行为有关,就像表单元素的典型performance一样。 当你设置display: inline时,我相信正在发生的事情是display: inlinebutton是…什么都不是。 实际上,它与典型的浏览器默认display: inline-blockwidth属性适用于此)相同。

请参阅10.2节 ,它描述了width属性本身。 特别是它解释了为什么width属性不适用于内联元素(或内联框 ):

此属性不适用于未replace的内联元素。 未被replace的内联元素的框的内容宽度是其内部呈现的内容的宽度(在儿童的任何相对偏移之前)。 回想一下内联框stream入线框。 线框的宽度由它们的包含块给出,但是可能由于浮动的存在而被缩短。

简而言之,这是因为内联元素的内容驻留在行框中 。 线框的宽度不能直接控制; 它完全由包含块和任何偶然浮游物决定。 您可以在9.4.2节中看到一个线框渲染示例,其中描述了内联格式化上下文。

如果display: inline实际上是将一个button渲染为一个内联框, 那么它的所有内容都会溢出,并且不再像button一样查看或者运行。 想要防止这种情况发生是有道理的,我想这正是浏览器所做的。

那么他们究竟做了什么来阻止呢? button是一个被replace的元素吗? 我不能肯定地说。 但请注意,在9.2.2节中 ,它说:

不是内联框的内联级框(如replace内联级元素,内嵌块元素和内联表元素)称为primefaces内联级框,因为它们作为单个不透明框参与其内联格式化上下文。

第10部分没有明确提到primefaces内联框,但是它具有用于计算embeddedreplace元素的尺寸的部分,以及embedded块元素(无论是replace还是非replace),所有这些元素都被视为primefaces内联,如上所述。 在所有这些情况下,如果width属性不是auto则会正常应用。

所以,尽pipe一个button是不是一个被replace的元素仍然值得商榷,但对于这个问题来说,这可能根本就不重要。 但它仍然是某种primefaces内联元素,因为它仍然参与内联格式化上下文。 但是,如果你没有设置宽度,那么它的价值看起来会缩小以适应其内容,所以在这种情况下,它的行为可能更接近内联块。 可以这么说, display的实际值变成了inline-block ,尽pipe这从来没有反映在开发者工具中,因为计算的值不会改变(再次是浏览器特定的渲染行为的副作用)。

既然像Boltclock一样,我不认为这个问题有个简单的答案,这就是我对这个问题的一个回答,但是我希望它能够提供信息。

虽然CSS显示属性表面上很简单,但实际上它包含了很多方面。 CSS级别3草案规范CSS显示捕捉了一些这种复杂性,但似乎还没有充分覆盖。

HTML5规范说明了对<button>元素的渲染 :

当button绑定应用于button元素时,该元素应该呈现为呈现为button的“embedded块”框,其内容是元素的内容。

inline-block框有以下几个方面:

1. 内联级元素

这意味着它参与线框内的内联格式化上下文。 它与同一行上的其他元素依次stream动。 线框的内容可以与其容器上的text-align:center属性居中alignment,并通过避免浮动的元素缩短线框。

2.应用宽度属性,自动值缩小到适合值

与非replacedisplay:inline元素不同,宽度值适用。 而且,如果未指定宽度值,则应用缩小拟合algorithm来确定宽度。 这就像浮动的元素,或者display:table元素,但是不同于display:block元素,如果没有指定宽度的话,它们是尽可能宽的。 它也不像被replace的内联元素,而是replace内联块元素,如果没有指定宽度,则使用它们的内在宽度,如果它们有一个,则默认值为300px。 对于replace元素来说,缩小拟合是一个毫无意义的概念。

3. 块容器元素

块容器元素由一堆线盒组成。 内容从一个线框stream向另一个线框,并且内联块元素的高度增长(可能溢出)以完全包含所有的线框。

4.基线是最后包含的线框的基线

当inline-block元素包含多行时,其基线是这些行中的最后一行。 这与浮动或display:table-cell不同display:table-cell也是缩放以适合容器元素。 浮动在正常stream程之外,因此它们没有基线, display:table-cell元素具有作为其第一行框的基线的基线。 具有多行的button根据最后一行的线条规则进行垂直alignment。


现在,这对于默认的显示设置来说很好。 而HTML5渲染要求意味着即使指定的值为inline ,button显示的使用值也是inline-block 。 但是它没有考虑到当指定的值是block时的行为。 在这种情况下,元素在它之前和之后都有一个换行符,而margin:auto将该方框作为display:block元素来margin:auto ,而不是对inline-block期望。

但是,对于auto的指定值,其宽度与inline-block一样是缩小的,而display:block的预期行为尽可能宽。 据我所知,唯一的显示值是display:table ,但没有别的build议使用display:table

所以没有什么规格可以find与之相匹配的东西。 我们只能希望当css-display规范完成时,它会覆盖这个行为。

尝试将边距设置为-2px

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

元素之间还有空间的原因是因为即使display:inline; 并没有消除所有的空间。 它删除了浏览器通常应用的块默认样式。 但是,-2px的边距将删除button和div之间的所有空间。

小提琴

有两种types的元素。

  1. 未被replace的元素
  2. replace的元素

Button属于被replace的元素类别。

您可以在下面的链接find更多。

  • Littlewebhut
  • SitePoint

所以, button ,按规格 ,它是正确的。

内联,非replace元素

width属性不适用。 margin-left margin-rightmargin-right margin-leftauto计算值成为0的使用值。

内联,replace元素 (本节适用于button

margin-left margin-rightmargin-right margin-leftauto计算值成为0的使用值。

如果heightwidth均具有auto计算值并且元素也具有固有width ,则该固有widthwidth的使用值。

如果heightwidth均具有auto计算值并且元素没有固有width ,但是具有固有height和固有比率; 或者如果width的计算值是auto ,则height具有其他一些计算值,并且该元素具有固有比率; 那么width的使用值是:

  (used height) * (intrinsic ratio) 

如果heightwidth计算值都是auto ,并且元素具有固有比率,但没有固有heightwidth ,那么在CSS 2.1中 ,使用的width值是不确定的。 然而,如果包含块的width本身并不取决于被replace元素的width ,则build议使用width的使用值根据在正常stream程中用于块级非replace元素的约束方程来计算。

如果width的计算值为auto ,并且元素具有固有width ,则该固有widthwidth的使用值。

如果width有一个计算值,但是没有满足上述条件,则所使用的width值变为300px 。但是,如果300px太宽300px适合设备,则UA应该使用具有最大width的矩形的width 2:1的比例,而不是适合的设备。