为了更好地理解这一点,让我们首先添加缺失的案例。
.flexy {
display: inline-flex;
}
.noname::before {
content: ' has ';
}
.noname-after::after {
content: ' has ';
}
span {
border:1px solid;
}
<div class="flexy">
A girl <span class="noname">no name</span>
</div>
<br>
<div class="flexy">
A girl <span class="noname"><span>no name</span></span>
</div>
<br>
<div class="flexy">
A girl <span class="noname-after"><span>no name</span></span> some text after
</div>
<br>
<div class="flexy">
A girl <span class="noname-after"></span><span>no name</span> some text after
</div>
<br>
<div class="flexy">
Jon Snow
<span> knows </span>
<span>nothing</span>
</div>
我们可以清楚地看到,当使用before 时缺少前导空格,而使用after 时缺少尾随空格,如果只有after(或before)在跨度内,则两者都缺少。
换句话说,我们遗漏了所有<span> 元素边缘的空格(无论是否使用伪元素),这是合乎逻辑的,因为这是white-space 的默认行为。 From the specification:
随着每一行的布局,
- 如果空格 (U+0020) 在行首 将“空白”设置为“正常”、“nowrap”或“前行”,它已被删除。
- 所有制表符 (U+0009) 都呈现为水平移位,将下一个字形的开始边缘与下一个制表位对齐。制表位出现在从块的起始内容边缘以块的字体呈现的空间宽度 (U+0020) 的 8 倍的点处。
- 如果空格 (U+0020)行尾 将“white-space”设置为“normal”、“nowrap”或“pre-line”,它也被删除了。
- 如果行尾的空格 (U+0020) 或制表符 (U+0009) 将“white-space”设置为“pre-wrap”,UA 可能会在视觉上折叠它们。
现在你会告诉我,我们正在处理 span 元素,我们没有块和新行,但我们在一个 flex 容器内,因此每个元素都会被块化,并且上述规则适用于此。
flex 项的显示值被阻塞ref
值得注意的是,伪元素不是弹性容器的直接子元素,因此它们仍然是块元素内的内联元素。如果我们将它们更改为块元素(使用inline-block1例如)你会看到空格总是会消失:
.flexy {
display: inline-flex;
}
.noname::before {
content: ' has ';
display:inline-block;
}
.noname-after::after {
content: ' has ';
display:inline-block;
}
span {
border:1px solid;
}
<div class="flexy">
A girl <span class="noname">no name</span>
</div>
<br>
<div class="flexy">
A girl <span class="noname"><span style="display:inline-block;">no name</span></span>
</div>
<br>
<div class="flexy">
A girl <span class="noname-after"><span>no name</span></span> some text after
</div>
<br>
<div class="flexy">
A girl <span class="noname-after"></span><span>no name</span> some text after
</div>
<br>
<div class="flexy">
Jon Snow
<span> knows </span>
<span>nothing</span>
</div>
另一个需要注意的重要事情是 flexbox 如何处理空格:
flex 容器的每个流入子项都成为一个 flex 项,每个连续的子文本运行序列都包装在一个匿名块容器 flex 项中。但是,如果整个子文本序列仅包含空格(即可能受 white-space 属性影响的字符),则它会不呈现(就像如果它的文本节点是 display:none)。
现在我们可以清楚地了解正在发生的事情。在我们的 flex 容器中,我们首先通过删除它们之间的所有额外空格来创建 flex 项目。然后每个 flex 项目成为一个块级元素,并在内部应用空白算法来删除该块内的尾随和前导空格。
如果要保留尾随和前导空格,可以更改 white-space 属性:
.flexy {
display: inline-flex;
}
.noname::before {
content: ' has ';
}
.noname-after::after {
content: ' has ';
}
span {
border:1px solid;
white-space:pre;
}
<div class="flexy">
A girl <span class="noname">no name</span>
</div>
<br>
<div class="flexy">
A girl <span class="noname"><span>no name</span></span>
</div>
<br>
<div class="flexy">
A girl <span class="noname-after"><span>no name</span></span> some text after
</div>
<br>
<div class="flexy">
A girl <span class="noname-after"></span><span>no name</span> some text after
</div>
<br>
<div class="flexy">
Jon Snow
<span> knows </span>
<span>nothing</span>
</div>
这是另一个示例,可以帮助您逐步了解正在发生的事情:
span {
border:1px solid;
}
div {
border:1px solid red;
margin:10px 0;
}
Spaces are removed from the start and the end, spaces inside are kept (contiguous spaces are collapsed to only one space)
<div>
<span> text inside span </span> text without span<span> text inside span </span>
</div>
I made the last span inline-block so its first space inside is removed
<div>
<span> text inside span </span> text without span<span style="display:inline-block"> text inside span </span>
</div>
Spaces between flex items are removed (We have 3 items and one inside an anonymous block) then first and last space inside each flex items are also removed
<div style="display:flex;">
<span> text inside span </span> text without span<span> text inside span </span>
</div>
We change the white space algorithm and now all the spaces are kept
<div style="display:flex;white-space:pre;">
<span> text inside span </span> text without span<span> text inside span </span>
</div>
1:该值使元素生成内联级块容器。内联块的内部格式化为块框,元素本身被格式化为原子内联级框。