如何防止 ::before / ::after 元素影响跨度的破坏行为?

Cor*_*rrl 7 html css pseudo-element

由于元素之间没有空格<span>,我希望它们不会换行,而是全部位于同一行,这在所有浏览器中似乎都是如此

span {
  position: relative;
}
Run Code Online (Sandbox Code Playgroud)
<span>Fooooooooooooooooooooooooooooooooooooooooooooooooo</span><span>foo</span><span>Baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar</span><span>bar</span>
Run Code Online (Sandbox Code Playgroud)

但是当添加::before工具提示元素时,这种行为会发生变化。虽然它们在 Firefox (114) 中保持在同一行,但它们在 Safari (16) 和 Chrome (114) 中开始换行。

span {
  position: relative;
}

span::before {
  content: 'tooltip';
  position: absolute;
  left: 0;
  top: 0;
  opacity: 0;
  background: grey;
  color: white;
  transition: opacity 100ms;
}

span:hover::before {
  opacity: 100;
}
Run Code Online (Sandbox Code Playgroud)
<span>Fooooooooooooooooooooooooooooooooooooooooooooooooo</span><span>foo</span><span>Baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar</span><span>bar</span>
Run Code Online (Sandbox Code Playgroud)

为什么会这样?有办法防止吗?

元素上的不同display选项::before没有效果。

但我刚刚注意到,inline-block在s 上设置实际上似乎与添加元素span具有相同的效果::before

span {
  position: relative;
  display: inline-block;
}
Run Code Online (Sandbox Code Playgroud)
<span>Fooooooooooooooooooooooooooooooooooooooooooooooooo</span><span>foo</span><span>Baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar</span><span>bar</span>
Run Code Online (Sandbox Code Playgroud)

对于包装是否有合理的解释,或者这是否可以被视为意外行为?

由于在实际示例中存在应该中断的空格,因此将所有内容包装在white-space: nowrap;容器中并不是一种选择。

这是一个带有空格的示例,空格FoooooooBaaaaaaar应该保持在一起而不是分成两行

span {
  position: relative;
}

span::after {
  content: 'tooltip';
  position: absolute;
  left: 0;
  top: 0;
  opacity: 0;
  background: grey;
  color: white;
  transition: opacity 100ms;
}

span:hover::after {
  opacity: 100;
}
Run Code Online (Sandbox Code Playgroud)
<span>Fooooooo</span><span>Baaaaaaar</span> <span>Fooooooo</span><span>Baaaaaaar</span> <span>Fooooooo</span><span>Baaaaaaar</span> <span>Fooooooo</span><span>Baaaaaaar</span> <span>Fooooooo</span><span>Baaaaaaar</span> <span>Fooooooo</span><span>Baaaaaaar</span> <span>Fooooooo</span><span>Baaaaaaar</span> <span>Fooooooo</span><span>Baaaaaaar</span> <span>Fooooooo</span><span>Baaaaaaar</span> <span>Fooooooo</span><span>Baaaaaaar</span> <span>Fooooooo</span><span>Baaaaaaar</span> <span>Fooooooo</span><span>Baaaaaaar</span> <span>Fooooooo</span><span>Baaaaaaar</span> <span>Fooooooo</span><span>Baaaaaaar</span> <span>Fooooooo</span><span>Baaaaaaar</span> <span>Fooooooo</span><span>Baaaaaaar</span> <span>Fooooooo</span><span>Baaaaaaar</span> <span>Fooooooo</span><span>Baaaaaaar</span>
Run Code Online (Sandbox Code Playgroud)

虽然抽象的例子已经说明了问题,但这里还有一个更现实的例子:给定一个包含特殊字符(例如引号和括号)以及由两个单词组合的单词的句子。出于样式目的,并且因为单词有翻译工具提示,所以所有内容都被拆分为 span 元素。

span {
  position: relative;
}

.word::after {
  content: 'tooltip';
  position: absolute;
  left: 0;
  top: 0;
  opacity: 0;
  background: grey;
  color: white;
  transition: opacity 100ms;
}

.word:hover::after {
  opacity: 100;
}
Run Code Online (Sandbox Code Playgroud)
This is an "example sentence" containing a comboword and also something in (parenthesis).<br><br>

<span class="word">This</span><span class="char"> </span><span class="word">is</span><span class="char"> </span><span class="word">an</span><span class="char"> </span><span class="char">"</span><span class="word">example</span><span class="char"> </span><span class="word">sentence</span><span class="char">"</span><span class="char"> </span><span class="word">containing</span><span class="char"> </span><span class="word">a</span><span class="char"> </span><span class="word">combo</span><span class="word">word</span><span class="char"> </span><span class="word">and</span><span class="char"> </span><span class="word">also</span><span class="char"> </span><span class="word">something</span><span class="char"> </span><span class="word">in</span><span class="char"> </span><span class="char">(</span><span class="word">parenthesis</span><span class="char">)</span><span class="char">.</span>
Run Code Online (Sandbox Code Playgroud)

通常,特殊字符与其旁边的单词之间或组合字之间不会有中断,但::after元素就是这种情况。

意外的休息

Sal*_*n A 6

我正在阅读这里的规格,它说:

流外元素和内联元素边界不会在流中引入强制换行或软换行机会。

显然,position: absolute元素以及</span><span>不应该生成软包装;基于 Chromimum 的浏览器做错了!

文章进一步指出:

为了实现 Web 兼容性,在每个替换元素或其他原子内联之前和之后都有软换行机会,即使与通常会抑制它们的字符相邻,例如 U+00A0 NO-BREAK SPACE。

因此display: inline-block元素可以生成软包裹。

body {
  font: medium monospace;
}
.test > span:nth-child(odd) {
  background-color: #FC0;
}
.test > span:nth-child(even) {
  background-color: #CF0;
}
.test-1 > span {
  position: relative;
}
.test-1 > span::before {
  content: "tooltip";
  position: absolute;
  left: 0;
  top: 0;
  color: #FFF;
  background-color: rgb(0, 0, 0, .65);
}
.test-2 > span {
  display: inline-block;
}
Run Code Online (Sandbox Code Playgroud)
<h1>position: absolute<br>should not wrap</h1>
<p class="test test-1"><span>Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</span><span>Bbbbbbbbbbbbbbbbbbbb</span><span>Cccccccccccccccccccccccccccccc</span><span>Dddddddddddddddddddddddddddddddddddddddddddddddddd</span></p>

<h1>display: inline-block<br>should wrap</h1>
<p class="test test-2"><span>Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</span><span>Bbbbbbbbbbbbbbbbbbbb</span><span>Cccccccccccccccccccccccccccccc</span><span>Dddddddddddddddddddddddddddddddddddddddddddddddddd</span></p>
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!因此,如果行为不符合规范,是否有地方可以报告? (3认同)