我遇到一个小问题,我有一个包含<span>
的标题,我想确保在<span>
之前插入一个换行符。老实说,在<span>
之前添加一个<br>
标签并没有什么问题(实际上,能够显示/隐藏这个标签 非常有用)。但是……为了实现布局,总是觉得使用 HTML 感觉有点奇怪。
因此,让我们开始一段旅程。在这段旅程中,我们会经常说“但是……”。
<h1 class="one">
Break right after this
<!-- <br> could go here, but can we do it with CSS? -->
<span>
and before this
</span>
</h1>
块级元素可以做到
我们可以使用<div>
代替<span>
,这样我们就可以通过div
是块级元素的特性来实现换行。
但是我们故意使用<span>
,因为这是设计需求。换行符后的文本应该为内联/内联块,因为它需要背景和内边距等。

您可以通过伪元素插入换行符
这很简单
h1 span::before {
content: "\A";
}
但是……<span>
是内联元素。换行符不会有任何作用!就像一个真正的换行符一样,它不会有任何作用。
我们可以通过使空白符有意义来强制换行符生效……
h1.two span::before {
content: "\A";
white-space: pre;
}
这确实有效。但是……由于存在内边距和背景,当换行时,会留下一小部分。

我们可以通过使用box-decoration-break: clone;
来修复尴尬的左边缘紧贴问题,但是……这只会留下更大的顶部部分。

box-decoration-break
非常适合解决某些问题,但这个问题不行。如果我们将<span>
设置为内联块,换行符将在这个块内发生,这不是我们想要的。

将伪元素设置为块级并保持<span>
不变也不能解决问题。

您可以使用伪元素来注入实际文本,但这有点奇怪。
这是 Aaron Bushnell 的 想法。这里的诀窍是将<span>
设置为块级,然后使用伪元素注入文本,并将其样式设置为内联元素。
h1 span {
display: block;
}
h1 span::before {
content: attr(data-text);
background: black;
padding: 1px 8px;
}

我一直喜欢使用伪元素的技巧,但这感觉有点危险,因为可能会损害可访问性。我认为有些屏幕阅读器可以读取伪元素,但并非全部,而且它们也不应该读取。更不用说,您无法通过这种方式复制和粘贴所有文本。至少文本仍然完全保留在 HTML 中!
利用表格布局
我最喜欢的 想法 来自 Thierry Koblentz。只需将<span>
设置为display: table;
就可以了。当然,这不是表格数据,但这并不重要。您可以通过 CSS 强制表格布局,这完全是为了利用表格布局的独特布局属性,而不是语义。
h1 span {
display: table;
}

实时演示
包括一个我们只使用<br>
的演示,这也是可以的。
查看 CodePen 上 Chris Coyier (@chriscoyier) 创建的 尝试在标题之前插入换行符,并在标题中使用内联块元素 演示。
但是
……是啊……办公室里又是一个无聊的一天。曾经用几 KB 代码编写的旧网站,现在变成了占用数兆字节的庞然大物,需要大量带宽和服务器集群才能做到……嗯……基本上就是以前做的事情,但现在添加了许多漂亮的图片和颜色。:D < 翻白眼 >
但是,为什么不使用
div
而不是span
,并将其标记为display: inline-block
呢?我会让你解释这将如何提供帮助 ;) 演示一下吗?
我会选择这个方法
这不起作用。
使用内联块,如果
div
外部和内部的文本可以放在一行,则不会换行。我不明白为什么要在这里使用它。换行符就是换行符,为什么要假装它是其他东西呢?
因为文档中描述的内容块内的换行符应该与样式化的换行符有所区别。一句话:语义,儿子!
实际上,这有助于响应式文本。始终换行。这样,您只需使用媒体查询来让它在您想要的时候换行。抱歉我的英语不好。我不是英语母语人士。
如何使用 flexbox?
http://codepen.io/freekbron/pen/jrNNMZ/
太棒了!这很难想象,因为您通常不会将文本节点视为 flex 项,但嘿,我敢说它符合规范。
<span>
作为 flex 项的优点在于您可以使用更多属性,例如……将
<span>
定位到右侧,这并不是说您会在这种情况下这样做,但是……flexbox 是理想的选择 ;) 我能想到的唯一缺点是,如果由于某种原因,您无法将所有兄弟节点设置为 flex 项。Morgan,使用
display:table
(或display:block; width: fit-content
,如 Šime Vidas 所述)您也可以做到,使用margin-left: auto
。我经常使用 flexbox,我几乎忘记了这是一个常见的问题……
SelenIT,啊哈……内在尺寸,嗯……到目前为止,这看起来是最简单的方法。在这里学到了东西!
我的同事昨天问我关于在 h1 标题中添加换行符的事情。我脑子里就出现了这些想法。
为什么不在
<span>
上使用white-space: nowrap;
,这样它会自动为您换行。无需媒体查询
nowrap
只是阻止<span>
内的内容换行。如果整个 H1 可以放在一行,则不会换行。
如果我们在它上面添加一个巨大的
margin-right
,并隐藏由这个边距引起的容器溢出,则它会起作用: http://codepen.io/SelenIT/pen/rLBxod非常有限,但在某些情况下仍然可行。但我个人最喜欢的是
display:table
技巧。如果在 -Element 右边留出很大的空白,当文本长度超过框体时就会出现问题。由于设置了 overflow: hidden;,文本会溢出,用户无法阅读。
我也喜欢表格解决方案。
Berit,完全同意,这是这种方法的局限性。
但是
display: table
会让后续文本换行,而不是与 span 元素保持在同一行。这是一种将元素像块级元素一样处理,但跨度到内容宽度而不是容器宽度的技巧。您可以使用
width: fit-content
使<div>
像内联块级元素一样(不过,Edge 不支持)。演示:https://jsbin.com/bexukec/edit?html,css,output另一种变体
http://codepen.io/aagd/pen/PzYpMZ
为什么不使用
white-space: pre-line
呢?像这样:http://codepen.io/grantbunyan/pen/pbzGMQ/
当然,您需要确保父元素的开始标签后面不包含换行符,但这似乎是一个非常自然的解决方案。
这可能在代码格式方面算是风格问题,但绝对比添加或删除标记要好。
尽管如此,我仍然不反对在这些情况下使用
<br>
。出于好奇,屏幕阅读器是否会读出
<br>
的存在?也许只是我,但我会在
<h1>
中添加一个:before
,像这样但我可能遗漏了什么……
感谢你的提醒,Chris!我完全同意使用 data-attr 技巧的可访问性方面。我认为
<br>
方法可能是这里最快的解决方法,但看到所有这些替代方案还是很酷的!h1.two span::before {
content: “\A”;
white-space: pre;
font-family: monospace;
margin: -2em;
color: transparent;
}
→ 似乎 span 中缺少左侧填充
为了避免缺少左侧填充
h1.three span::before {
content: “\A”;
white-space: pre;
font-family: monospace;
margin: -2em;
color: transparent;
-webkit-box-decoration-break: clone;
box-decoration-break: clone;
}
不错的例子。但我希望看到一些控制响应式设计中换行符的更多方法。任何从事桌面出版或印刷设计的人都知道换行符的重要性:它可以在视觉上平衡多行,提高可读性,甚至影响理解能力。但响应式设计出现了:现在您需要考虑屏幕宽度以及换行符如何在所有设备尺寸上工作。
这是从一个更大的项目中提取的一些代码:http://codepen.io/team/adpearance/pen/QEwEwQ/
生成的类让我可以控制何时显示换行符,或者何时让文本自然流动。它并不理想;我仍然希望对将重要的单词组合在一起有更多控制,但好吧……这是一个开始。
我认为许多人建议他们的变体只是复制了所需的图像,而不是所需的行为。
只需在
h1
上添加text-align: center
,就可以修剪掉错误的换行符。因为实际上,内联块级 span 也应该居中,而不是粘在左边。在这里,我将其添加到第 7 号和 Thierry 的第 8 号,它们都失败了。
http://codepen.io/anon/pen/LZVQNd