inline 元素自动变为 block 元素的两种情况

Back

目前为止我遇到了两种不主动设置display,但inline元素可以自动转化成block元素的情况,分别是:

  • 使用absolutefixed定位的时候
  • 父元素使用flexgrid布局的时候

absolute定位和fixed定位的情况

在使用伪元素::before::after的时候,使用absolute定位、设置宽度高度都是十分惯用的操作。但是MDN上对::before::after的描述都是“It is inline by default.”,也就是说,::before::after这两个伪元素默认都是内联(inline)元素,但是在定位操作后它们已经被转化成了块级(block)元素,从而能够设置宽度了。

做一下实验,对于多种position的值测试::before的表现形式:

html
<div class="container static"></div>
<div class="container relative"></div>
<div class="container absolute"></div>
<div class="container fixed"></div>
<div class="container sticky"></div>
css
.container {
  width: 200px;
  height: 200px;
  background: #ddd;
  margin: 10px;
  position: relative;
  border: 1px solid #ddd;
}

.container::before {
  width: 100px;
  height: 100px;
  font-size: 1.5em;
  color: red;
  background:yellow;
}

.static::before {
  position: static; /* position的默认值 */
  content: 'static';
}

.relative::before {
  position: relative;
  content: 'relative';
}

.absolute::before {
  position: absolute;
  content: 'absolute';
}

.fixed::before {
  position: fixed;
  content: 'fixed';
}

.sticky::before {
  position: sticky;
  content: 'sticky';
}

代码根据针对5种定位情况下的伪元素::before都设置了widthheight,显示结果如下:

可以很清楚地看到,使用absolutefixed定位时,伪元素时block元素,因此widthheight能够生效,但是使用其他三种定位时对宽度和高度的设置则均不生效。

使用flex和grid布局的情况

仍然使用上面的例子,在.conatainer中添加flex定位:

css
.container {
  width: 200px;
  height: 200px;
  background: #ddd;
  margin: 10px;
  position: relative;
  border: 1px solid #ddd;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.container span {
  width: 80px;
  height: 80px;
  background: red;
}

div中加入span元素:

html
<div class="container static"><span>static</span></div>
<div class="container relative"><span>relative</span></div>
<div class="container absolute"><span>absolute</span></div>
<div class="container fixed"><span>fixed</span></div>
<div class="container sticky"><span>sticky</span></div>

显示结果:

flex布局时针对::beforewidthheight竟然全部都生效了,与此同时,<span>元素也被转化为了block元素,所以宽度和高度设置也生效了。<span>作为inline元素,也被flex布局转化为了block元素。

还有一个问题在于,使用absolutefixed定位的伪元素并没有像其他三种伪元素一样与<span>元素一起遵循flex布局,而是重叠覆盖了<span>元素。这两种定位之所以特殊,是因为它们并不属于正常文档布局流。文档的描述如下:

The element is removed from the normal document flow, and no space is created for the element in the page layout.

我的理解是这时候::before<span>元素实际上是处于不同的“次元”当中的,因此对于使用absolutefixed定位的元素来说,flex布局是对它们独立生效的。

我认为也正是因为这种特殊性,使得由这两种定位控制的元素会默认被转化为块级元素。


对于grid布局,表现与flex布局时相同,这里不再赘述。