【问题标题】:Why does a ::before pseudoelement with content have only leading spaces stripped in a 'display: flex' container?为什么带有内容的 ::before 伪元素在“display:flex”容器中只去除了前导空格?
【发布时间】:2019-06-26 02:23:20
【问题描述】:

jsfiddle

请注意,除了伪元素 (::before.content) 之外,每个元素的前导和尾随空格都被相当一致地去除,它只修剪了前导空格。为什么是这样?我希望尾随空格也会被删除

.flexy {
  display: inline-flex;
}

.noname::before {
  content: ' has ';
}
<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">
  Jon Snow
  <span> knows </span>
  <span>nothing</span>
</div>

【问题讨论】:

    标签: css flexbox


    【解决方案1】:

    为了更好地理解这一点,让我们首先添加缺失的案例。

    .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)在跨度内,则两者都缺少。

    换句话说,我们遗漏了所有&lt;span&gt; 元素边缘的空格(无论是否使用伪元素),这是合乎逻辑的,因为这是white-space 的默认行为。 From the specification:

    随着每一行的布局,

    1. 如果空格 (U+0020) 在行首 将“空白”设置为“正常”、“nowrap”或“前行”,它已被删除
    2. 所有制表符 (U+0009) 都呈现为水平移位,将下一个字形的开始边缘与下一个制表位对齐。制表位出现在从块的起始内容边缘以块的字体呈现的空间宽度 (U+0020) 的 8 倍的点处。
    3. 如果空格 (U+0020)行尾 将“white-space”设置为“normal”、“nowrap”或“pre-line”,它也被删除了
    4. 如果行尾的空格 (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:该值使元素生成内联级块容器。内联块的内部格式化为块框,元素本身被格式化为原子内联级框。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-09
      • 2018-09-03
      • 1970-01-01
      • 1970-01-01
      • 2013-04-17
      • 2013-10-15
      相关资源
      最近更新 更多