指定一个适合换行的位置

140

假设我有一个文本,我想在HTML表格单元格中显示:

Honey Nut Cheerios, Wheat Chex, Grape-Nuts, Rice Krispies, Some random cereal with a very long name, Honey Bunches of Oats, Wheaties, Special K, Froot Loops, Apple Jacks

我希望这行文字能在逗号后面的位置断开。有没有一种方法可以告诉HTML渲染器尝试在指定位置断开,而不是在空格后面尝试断开,而不需要使用非断开空格?如果我使用非断开空格,则宽度无条件增大。如果换行算法首先尝试使用逗号并且不能使该行适合,则希望在空格之后发生换行。我尝试将文本片段包装在<span>元素中,但那似乎没有任何有用的作用。
<html>
  <head>
      <style type="text/css">
        div.box { width: 180px; }
        table, table td { 
          border: 1px solid; 
          border-collapse: collapse; 
        }
      </style>
  </head>
  <body>
    <div class="box">
      <table>
      <tr>
          <td>lorem ipsum</td>
          <td>lorem ipsum</td>
          <td>lorem ipsum</td>
      </tr>
      <tr>
          <td>lorem ipsum</td>
          <td>
            <span>Honey Nut Cheerios,</span>
            <span>Wheat Chex,</span>
            <span>Grape-Nuts,</span>
            <span>Rice Krispies,</span>
            <span>Some random cereal with a very long name,</span>
            <span>Honey Bunches of Oats,</span>
            <span>Wheaties,</span>
            <span>Special K,</span>
            <span>Froot Loops,</span>
            <span>Apple Jacks</span>
          </td>
          <td>lorem ipsum</td>
      </tr>
      </table>
    </div>
  </body>
</html>

注意:看起来CSS3 text-wrap: avoid的行为是我想要的,但我似乎无法使其工作。


你可以在<span>标签内使用不间断空格 - Gabriele Petrioli
8
我不想使用断行空格。我很想使用“不想断行但如果必须我就会”的空格,但据我所知,这种空格并不存在。 - Jason S
1
你应该接受@EggertJóhannesson的答案,因为它提供了一个很好的解决方法! - Gabriele Petrioli
完成(抱歉,我不经常关注旧问题)。https://jsfiddle.net/kqa8p1f4/2/与https://jsfiddle.net/kqa8p1f4/1/。 - Jason S
我知道已经过去了几年,但我有另一个可行的解决方案。如果与任何<span>黑科技</span>结合使用,断行算法将被完全覆盖。 - user3186555
显示剩余2条评论
10个回答

189

通过使用

span.avoidwrap { display:inline-block; }

并将我想要保持在一起的文本包装起来

<span class="avoidwrap"> Text </span>

它会首先按优先级块进行包装,然后根据需要再进行更小片段的包装。


21
非常好用!只有一个额外的注意事项:行内块开始和结束处的空格会被忽略,因此要通过空格来分隔块中的文本,需要将其放置在行内块之间。例如,如果span元素样式被设置为行内块,则 <span>Hello </span><span> world</span> 将会显示为 Helloworld,而 <span>Hello</span> <span>world</span> 则会正常显示为 Hello world - user
5
“更语义化的代码让浏览器拥有更多控制权,这通常是件好事。在这种情况下,它使得关键时可以出问题。” - Lodewijk
非常好用 - 当像“-”这样的字符不能断开时很重要。例如:Perikles <span class="avoidwrap">(um 500-429 v.Chr.)</span> - Sarah Trees
12
@Lodewijk:<wbr>并不表示首选断行位置,而是可能的一个。 - Dan Dascalescu
3
请注意,此技术也适用于嵌套的<span>,因此您可以(实际上)指定首选断点的层次结构 - Michael Dyck
显示剩余2条评论

32

有一个非常不错的响应式设计方案来自Dan Mall,我比较喜欢。我将在这里添加它,因为其他一些关于响应式换行的问题被标记为重复问题。
对于您的情况,您可以使用以下内容:

<span>Honey Nut Cheerios, <br class="rwd-break">Wheat Chex, etc.</span>

在您的媒体查询中加入一行CSS:

@media screen and (min-width: 768px) {
    .rwd-break { display: none; }
}

14

一个简单的答案是使用零宽度空格字符&#8203;。它用于在特定点内部单词中制作断词空格

它是不间断空格&nbsp;(实际上是单词连接器&#8288;)的完全相反单词连接器不间断空格的零宽度版本。

(还有其他非断词代码,如非断连字符&#8209;(这里有一个关于不同“变体”nbsp的详细答案)

如果您想要一个仅限HTML(无CSS / JS)的解决方案,可以使用零宽度空格不间断空格的组合,但这将非常混乱,编写人类可读版本需要一些努力。

ctrl + cctrl + v 很有帮助。

例子:

   Honey&nbsp;Nut&nbsp;Cheerios,<!---->&#8203;<!--
-->Wheat&nbsp;Chex,<!---->&#8203;<!--
-->Grape&#8209;Nuts,<!---->&#8203;<!--
-->Rice&nbsp;Krispies,<!---->&#8203;<!--
-->Some&nbsp;random&nbsp;cereal&nbsp;with&nbsp;a&nbsp;very&nbsp;long&nbsp;name,<!---->&#8203;<!--
-->Honey&nbsp;Bunches&nbsp;of&nbsp;Oats,<!---->&#8203;<!--
-->Wheaties,<!---->&#8203;<!--
-->Special&nbsp;K,<!---->&#8203;<!--
-->Froot&nbsp;Loops,<!---->&#8203;<!--
-->Apple&nbsp;Jacks

看不懂?这是没有注释标签的相同HTML:

   Honey&nbsp;Nut&nbsp;Cheerios,&#8203;Wheat&nbsp;Chex,&#8203;Grape&#8209;Nuts,&#8203;Rice&nbsp;Krispies,&#8203;Some&nbsp;random&nbsp;cereal&nbsp;with&nbsp;a&nbsp;very&nbsp;long&nbsp;name,&#8203;Honey&nbsp;Bunches&nbsp;of&nbsp;Oats,&#8203;Wheaties,&#8203;Special&nbsp;K,&#8203;Froot&nbsp;Loops,&#8203;Apple&nbsp;Jacks

然而,由于电子邮件 HTML 渲染不是完全标准化的,因此对于这种使用场景来说,这个解决方案非常好,因为它使用了没有 CSS / JS

另外,如果您将其与任何基于<span>的解决方案结合使用,则可以完全控制断行算法

(编辑说明:)

我唯一能想到的问题是,如果您想动态更改首选分割点,则需要不断地使用 JS 操作每个跨度比例大小,并处理文本中的那些 HTML 实体。


1
什么是跨度黑客? - Jason S
其他答案利用了<span>标签。 - user3186555
我想要指出的是,尽管这个解决方案似乎不是最简单的,但它是最可靠的,因为这些实体在浏览器、电子邮件解析器或任何其他HTML解析器中不应经常更改语义表示。 - user3186555
2
如果您要分割的文本被复制并以某种方式解析,则可能会遇到问题-那么额外的数字可能会妨碍。如果您尝试在“ @”处拆分电子邮件,则复制和粘贴将失败,用户无法得知原因。如果您希望数据由爬虫阅读或复制粘贴,则不建议使用此解决方案。 - isacvale

8
你应该做的事情(使用Unicode所用之处)会提供最佳结果:

在这里输入图片描述

<table border="1">
  <thead>
    <tr><th>Method</th><th>Results</th></tr>
  </thead>
  <tbody>
    <tr><td>&lt;wbr></td><td>Honey Nut Cheerios,<wbr> Wheat Chex,<wbr> Grape&#8209;Nuts,<wbr> Rice Krispies,<wbr> Some random cereal with a very long name,<wbr> Honey Bunches of Oats,<wbr> Wheaties,<wbr> Special K,<wbr> Froot Loops,<wbr> Apple Jacks</td></tr>
    <tr><td>U+200B Zero width Space</td><td>Honey Nut Cheerios,&#8203;Wheat Chex, &#x200b;Grape&#8209;Nuts, &#x200b;Rice Krispies, &#x200b;Some random cereal with a very long name, &#x200b;Honey Bunches of Oats, &#x200b;Wheaties, &#x200b;Special K, &#x200b;Froot Loops, &#x200b;Apple Jacks</td></tr>
    <tr><td>U+00A0 No&#8209;break Space</td><td>Honey&nbsp;Nut&nbsp;Cheerios, Wheat&nbsp;Chex, Grape&#8209;Nuts, Rice&nbsp;Krispies, Some&nbsp;random&nbsp;cereal&nbsp;with&nbsp;a&nbsp;very&nbsp;long&nbsp;name, Honey&nbsp;Bunches&nbsp;of&nbsp;Oats, Wheaties, Special&nbsp;K, Froot&nbsp;Loops, Apple&nbsp;Jacks</td></tr>
  </tbody>
</table>


2
使用您上面的标记,请使用{ white-space:nowrap }。这是您可以期望的最好结果。

谢谢,但那行不通,因为它基本上会将span元素中的空格转换为&nbsp;,并且完全不允许空格换行。我只是想阻止渲染器在我的项目之间断开,但如果必须这样做,我希望它可以这样做。 - Jason S
@Jason S:我已经在我的答案中添加了其他选项。 - Marcel
&nbsp;和空格有什么不同?据我所知,选择要么是一个字符允许换行,要么不允许。因此,'-'、' '、&#8203;<wbr>&shy;都允许换行(分别打印连字符、空格、无内容、无内容和仅在换行时打印连字符),而&nbsp;则不允许。 - Jason S
@Jason S:添加了使用示例。 - Marcel
我刚试了一下,似乎它并不优先于空格进行换行。优先级才是我需要的。如果对于其他字符或元素的换行行为是“是”或“否”,那么我的问题就没有解决方案。如果有相对的换行优先级,那么我可能会有一个解决方案。 - Jason S
好的,我刚才偏离了正题,意识到自己在谈论 "<wbr>" 就好像它意味着“需要时优先换行”之类的东西。现在我会从我的回答中剔除无用信息,去睡觉了。 - Marcel

2
答案是否定的(您无法更改所使用的换行算法)。
但有一些解决方法(最好的解决方法是接受的答案)。
您可以在非断行空格&nbsp;之间进行排列,但仅限于连在一起的单词之间(您在span中拥有的内容,但不是逗号后面),或者您可以像@Marcel提到的那样使用white-space:nowrap
这两种解决方案都是相同的,并且如果一组单词不适合自己,则两种解决方案都不会将其分开。

@arootbeer:我支持你的编辑,但是Gaby撤销了它。Gaby:为什么?你想误导用户吗? - Dan Dascalescu
@DanDascalescu,所有在SO上的答案是否都应该被更改为指向同一页中的已接受答案?我的答案有1个(sum)投票,而有一个已接受的答案有48个投票。我非常确定已接受的答案是得到关注的(当然是)。除此之外,我坚持认为没有办法改变所使用的破解算法(正如OP所要求的那样)。 - Gabriele Petrioli
您正在犯错误的二分法和滑坡谬误。SO上的大多数答案都是实现结果的另一种方式。其中有一部分存在虚假陈述。针对这些答案,我建议作者们表明他们关心真相和其他用户,并修改答案。以您的声望来看,我期望如此。 - Dan Dascalescu
@DanDascalescu 我仍然不同意,但既然你们两个都认为这很重要,我已经把它加回来了。 - Gabriele Petrioli
1
检查我的解决方案是否使用了你自己的逻辑来反击你。将其与任何跨度解决方案结合使用,那么你就完全掌控了断行算法。 - user3186555
显示剩余2条评论

-1

现在我们有了HTML5:

HTML5引入了<wbr>标签。(它代表单词断点。)

添加<wbr>告诉浏览器在此处打断,而不是在其他任何地方打断,因此很容易在逗号后打断单词:

Honey Nut Cheerios,<wbr> Wheat Chex,<wbr> Grape-Nuts,<wbr> Rice Krispies,<wbr> Some random cereal with a very long name,<wbr> Honey Bunches of Oats,<wbr> Wheaties,<wbr> Special K,<wbr> Froot Loops,<wbr> Apple Jacks

它支持除了IE之外的所有主要浏览器。


15
为什么你在给出建议前没有进行测试?它不起作用。<wbr> 具有另一个用途。更不用说这个答案是一个早先存在的 答案 的重复了。 - user
2
WBR 没有其他用途。https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/wbr - Lodewijk
17
<wbr>仅提供一个断点机会,它并没有“告诉浏览器在这里而不是其他地方断行”的功能。当放置在空格之前时,通常无效,因为空格通常是换行机会。 - Jukka K. Korpela
7
在任何浏览器中都无法使用此方法。答案是错误的:<wbr>标签并不会优先于普通空格强制换行,所以在这个例子中只会按照正常的方式进行换行。 - adrian
5
为了澄清,<wbr> 的作用是表示“这里可以断开”,当该位置被认为是“单词内部”时。它的含义是“把两个字符之间的位置视为有空格”,而不是“更倾向于在此处断开”。如果已经有一个空格,则 <wbr> 没有意义。 - Semicolon
显示剩余4条评论

-3

你只需在 CSS 中调整边距设置(在这种情况下是 margin-right)。

text {
    margin-right: 20%;
}

-3
使用 <div> 代替 <span>,或为 SPAN 指定一个类并赋予它 display:block 属性。

-6

4
“<wbr>”是用于标记过长单词的断点,但它并不能解决首选行断点的问题。 - user
4
@user3075942 直接引用自规范:“wbr元素表示换行机会。” 这正是OP所要求的。请停止根据您在维基上阅读到的内容对人们进行投票。 - Mathias Bynens
3
是的,机会。但浏览器已经有了在空格处断开的机会。问题是如何告诉浏览器在哪些空格处最好断开。 - user
9
不,那不是答案。它并不增加特定现有断点的使用可能性,它只添加了一个新的断点可能性,在不存在断点的地方添加断点。连续两个断点没有任何用处。参考链接为:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr。 - Torin Finnemann
1
@MathiasBynens:很抱歉,但您是不正确的。一个简单的测试将证明它。 - Dan Dascalescu
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接