如何防止长单词破坏我的 div?

自从从表格布局切换到 DIV 布局以来,一个共同的问题依然存在:

问题 : 你用动态文本填充你的 DIV 栏,不可避免地会有一个超长的单词延伸到你的 DIV 栏的边缘,使你的站点看起来不专业。

RETRO-WHINING : 这个 永远不会发生在表布局中。表单元格总是很好地扩展到最长单词的宽度。

严重性 : 我看到这个问题,即使在最主要的网站,特别是在德国网站,甚至常见的词,如“速度限制”是非常长的(“ GeschwindigkeitsBegrenzung”)。

有人有可行的解决办法吗?

132666 次浏览

两个解决方案:

  1. overflow:scroll——这可以确保你的内容可以以设计成本的方式显示出来(滚动条很丑陋)
  2. overflow:hidden-只是切断任何溢出。这意味着人们不能阅读的内容。

如果(在 SO 示例中)您想要阻止它重叠填充,那么您可能需要在填充内部创建另一个 div 来保存内容。

编辑: 正如其他答案所说,有很多方法可以截断单词,比如通过 JS 和插入断点符号,或者使用非标准的和/或非常不兼容的 CSS 标签(word-wrap: break-word 似乎不能在 Firefox 中工作)来计算客户端的渲染宽度(永远不要尝试在服务器端这样做,因为它永远不会可靠地工作,跨平台)。

但是,您总是需要一个溢出描述符。如果您的 div 包含另一个过宽的块类型内容(图像、表格等) ,您将需要溢出,以使其不会破坏布局/设计。

因此,一定要使用其他方法(或它们的组合) ,但也要记住添加溢出,以便覆盖所有浏览器。

编辑2(针对你在下面的评论) :

开始使用 CSS overflow属性并不完美,但它可以阻止设计中断。首先应用 overflow:hidden。请记住,溢出可能不会在填充时中断,因此要么嵌套 div,要么使用边框(只要对您最有效)。

这将隐藏溢出的内容,因此您可能会失去意义。您可以使用滚动条(使用 overflow:autooverflow:scroll而不是 overflow:hidden) ,但是根据 div 的尺寸和您的设计,这可能看起来或工作不太好。

为了解决这个问题,我们可以使用 JS 回退并执行某种形式的自动截断。我已经写了一半的伪代码,但是写到一半的时候就变得非常复杂了。如果您需要显示尽可能多,让 连字符一看(如下所述)。

请注意,这是以用户的 CPU 为代价的。这可能导致页面加载和/或调整大小需要很长时间。

你的意思是说,在支持它的浏览器中,word-wrap: break-word不能工作吗?

如果是 包含在样式表的主体定义中,那么它应该可以在整个文档中工作。

如果溢出不是一个好的解决方案,那么只有一个定制的 javascript 可以人为地拆分长单词。

注意: 还有这个 断字标签。这给了浏览器一个点,它可以分割线。不幸的是,<wbr>标签并不适用于所有浏览器,只适用于 Firefox 和 Internet Explorer (以及使用 CSS 技巧的 Opera)。

软连字符

你可以通过插入软连字符(&shy;)告诉浏览器在哪里分割长单词:

averyvery&shy;longword

可以作为

非常长的单词

或者

Avery
长词

一个好的正则表达式可以确保您不会插入它们,除非有必要:

/([^\s-]{5})([^\s-]{5})/ → $1&shy;$2

浏览器和搜索引擎很聪明,在搜索文本时会忽略这个字符,而 Chrome 和 Firefox (还没有测试过其他浏览器)在将文本复制到剪贴板时会忽略这个字符。

<wbr>元素

另一个选择是注入 <wbr>,这是以前的 IE 主义,现在是 在 HTML5中:

averyvery<wbr>longword

不带连字符的断句:

Avery
长词

你可以使用零宽空格字符 &#8203;(或者 &#x200B)来达到同样的效果。


仅供参考,最新的 IE、 Firefox 和 Safari (但目前不是 Chrome)也支持 CSS hyphens: auto:

div.breaking {
hyphens: auto;
}

然而,连字符是基于一个连字符字典,并不能保证打破长的单词。但是,它可以使合理的文本更漂亮。

复古抱怨解决方案

对于布局来说,<table>是不好的,但是对于其他元素来说,display:table是可以的。它将像老式桌子一样古怪(而且有弹性) :

div.breaking {
display: table-cell;
}

下面的 overflowwhite-space: pre-wrap答案也不错。

我刚从 这个问题中了解到 连字符,这也许能解决问题。

对于这个问题,我通常使用的解决方案是为 IE 和其他浏览器设置两种不同的 css 规则:

word-wrap: break-word;

在 IE 中非常完美,但是 字幕不是一个标准的 CSS 属性。这是微软特有的属性,不能在 Firefox 中使用。

对于 Firefox,只使用 CSS 的最好方法是设置规则

overflow: hidden;

用于包含要换行的文本的元素。它不包装文本,但 隐藏超过容器限制的文本部分。如果不需要显示所有文本(例如,如果文本位于 <a>标记中) ,那么这是一个很好的解决方案

HYPHENATER 是正确的答案(上面给出的)。你的问题背后真正的问题是,网页浏览器仍然(在2008年)非常原始,他们没有连字符功能。听着,我们还处在电脑使用的早期阶段——我们必须要有耐心。只要设计师统治网络世界,我们就很难等到一些真正有用的新特性。

更新: 截至2011年12月,我们现在有了另一个选择,在 FF 和 Safari 中这些标签的新兴支持:

p {
-webkit-hyphens: auto;
-moz-hyphens: auto;
hyphens: auto;
}

我已经做了一些基本的测试,它似乎可以在最近版本的 Mobile Safari 和 Safari 5.1.1上运行。

兼容性表: https://developer.mozilla.org/en/CSS/hyphens#AutoCompatibilityTable

是的,如果可能的话,设置一个绝对宽度和设置 overflow : auto工作得很好。

正如我们所知,这是一个复杂的问题,并且不受浏览器之间任何共同方式的支持。大多数浏览器根本不支持这个特性。

在一些 HTML 电子邮件的工作中,用户的内容被使用,但脚本是不可用的(甚至 CSS 也不是支持得很好) ,下面的 CSS 位包装在你的无间隔内容块周围,至少应该有所帮助:

.word-break {
/* The following styles prevent unbroken strings from breaking the layout */
width: 300px; /* set to whatever width you need */
overflow: auto;
white-space: -moz-pre-wrap; /* Mozilla */
white-space: -hp-pre-wrap; /* HP printers */
white-space: -o-pre-wrap; /* Opera 7 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: pre-wrap; /* CSS 2.1 */
white-space: pre-line; /* CSS 3 (and 2.1 as well, actually) */
word-wrap: break-word; /* IE */
-moz-binding: url('xbl.xml#wordwrap'); /* Firefox (using XBL) */
}

对于基于 Mozilla 的浏览器,上面提到的 XBL 文件包含:

<?xml version="1.0" encoding="utf-8"?>
<bindings xmlns="http://www.mozilla.org/xbl"
xmlns:html="http://www.w3.org/1999/xhtml">
<!--
More information on XBL:
http://developer.mozilla.org/en/docs/XBL:XBL_1.0_Reference


Example of implementing the CSS 'word-wrap' feature:
http://blog.stchur.com/2007/02/22/emulating-css-word-wrap-for-mozillafirefox/
-->
<binding id="wordwrap" applyauthorstyles="false">
<implementation>
<constructor>
//<![CDATA[
var elem = this;


doWrap();
elem.addEventListener('overflow', doWrap, false);


function doWrap() {
var walker = document.createTreeWalker(elem, NodeFilter.SHOW_TEXT, null, false);
while (walker.nextNode()) {
var node = walker.currentNode;
node.nodeValue = node.nodeValue.split('').join(String.fromCharCode('8203'));
}
}
//]]>
</constructor>
</implementation>
</binding>
</bindings>

不幸的是,Opera 8 + 似乎不喜欢上述任何一种解决方案,因此 JavaScript 将不得不成为这些浏览器(比如 Mozilla/Firefox)的解决方案另一个包含 Opera 后期版本的跨浏览器解决方案(JavaScript)是使用 Hedger Wang 的脚本: Http://www.hedgerwow.com/360/dhtml/css-word-break.html

其他有用的连结/想法:

模拟 Mozilla/Firefox 的 CSS 文字包装
Http://blog.stchur.com/2007/02/22/emulating-css-word-wrap-for-mozillafirefox/

[ OU ] Opera 中没有文字包装,IE 中显示良好
Http://list.opera.com/pipermail/opera-users/2004-november/024467.html
Http://list.opera.com/pipermail/opera-users/2004-november/024468.html

如果你有这个

  <style type="text/css">
.cell {
float: left;
width: 100px;
border: 1px solid;
line-height: 1em;
}
</style>


<div class="cell">TopLeft</div>
<div class="cell">TopMiddlePlusSomeOtherTextWhichMakesItToLong</div>
<div class="cell">TopRight</div>
<br/>
<div class="cell">BottomLeft</div>
<div class="cell">BottomMiddle</div>
<div class="cell">bottomRight</div>

只需切换到包含 div 的垂直格式,并在 CSS 中使用 min-width 而不是 width-

  <style type="text/css">
.column {
float: left;
min-width: 100px;
}
.cell2 {
border: 1px solid;
line-height: 1em;
}
</style>


<div class="column">
<div class="cell2">TopLeft</div>
<div class="cell2">BottomLeft</div>
</div>
<div class="column">
<div class="cell2">TopMiddlePlusSomeOtherTextWhichMakesItToLong</div>
<div class="cell2">BottomMiddle</div>
</div>
<div class="column">
<div class="cell2">TopRight</div>
<div class="cell2">bottomRight</div>
</div>
<br/>

当然,如果您显示的是真正的表格数据,那么使用真正的表格是可以的,因为它在语义上是正确的,并且会通知使用应该位于表格中的屏幕阅读器的用户。它是使用他们的一般布局或图像切片,人们会私刑你。

在 Firefox 3.5中可以使用“ word 包装: break-word” Http://hacks.mozilla.org/2009/06/word-wrap/

使用风格 word-break:break-all;。我知道它的工作表。

需要设置“表格布局: 固定”的文字包装工作

刚刚检查了 IE 7,Firefox 3.6.8 Mac,Firefox 3.6.8 Windows 和 Safari:

word-wrap: break-word;

适用于 div 内部的长链接,该 div 具有设置的宽度,并且没有在 css 中声明的溢出:

#consumeralerts_leftcol{
float:left;
width: 250px;
margin-bottom:10px;
word-wrap: break-word;
}

我没看到任何不兼容的问题

跨浏览器文字包装

.word_wrap
{
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
}

对于 此评论中的正则表达式,它很好,但是它只在5个非空格或连字符组之间添加害羞的连字符。这允许最后一组比预期的长得多,因为后面没有匹配的组。

例如:

'abcde12345678901234'.replace(/([^\s-]{5})([^\s-]{5})/g, '$1&shy;$2')

结果是:

abcde&shy;12345678901234

下面的版本使用积极的前瞻来避免这个问题:

.replace(/([^\s-]{5})(?=[^\s-])/g, '$1&shy;')

结果是:

abcde&shy;12345&shy;67890&shy;1234

更新: 在 CSS 中处理这个问题非常简单,开销也很低,但是当中断发生时,您无法控制中断发生的位置。如果您不在乎,或者您的数据有很长的字母数字运行,没有任何自然间断,那么这样做是可以的。我们有很多长文件路径、 URL 和电话号码,所有这些都有比其他地方更好的突破点。

我们的解决方案是首先使用正则表达式替换,在每15个(比如说)字符后面加一个零宽空格,这些字符不是空格,也不是我们希望中断的特殊字符之一。然后我们做另一个替换,在这些特殊字符后面加上一个零宽空格。

零宽度的空格非常好,因为它们在屏幕上永远不会显示出来; 当显示出来时,害羞的连字符会让人感到困惑,因为数据中有明显的连字符。将文本复制到浏览器外时,也不包括零宽度空格。

我们当前使用的特殊中断字符是句点、正斜杠、反斜杠、逗号、下划线、@、 | 和连字符。你可能认为你不需要做任何事情来鼓励在连字符之后断开,但是 Firefox (至少3.6和4)不会在连字符被数字包围的情况下自己断开(比如电话号码)。

我们还希望根据可用的布局空间控制人工中断之间的字符数。这意味着匹配长非中断运行的正则表达式需要是动态的。由于性能原因,我们不想一遍又一遍地创建相同的正则表达式,所以我们使用了一个简单的正则表达式缓存,由正则表达式及其标志键控。

下面是代码; 您可能会在一个实用程序包中给函数命名空间:

makeWrappable = function(str, position)
{
if (!str)
return '';
position = position || 15; // default to breaking after 15 chars
// matches every requested number of chars that's not whitespace or one of the special chars defined below
var longRunsRegex = cachedRegex('([^\\s\\.\/\\,_@\\|-]{' + position + '})(?=[^\\s\\.\/\\,_@\\|-])', 'g');
return str
.replace(longRunsRegex, '$1&#8203;') // put a zero-width space every requested number of chars that's not whitespace or a special char
.replace(makeWrappable.SPECIAL_CHARS_REGEX, '$1&#8203;'); // and one after special chars we want to allow breaking after
};
makeWrappable.SPECIAL_CHARS_REGEX = /([\.\/\\,_@\|-])/g; // period, forward slash, backslash, comma, underscore, @, |, hyphen




cachedRegex = function(reString, reFlags)
{
var key = reString + (reFlags ? ':::' + reFlags : '');
if (!cachedRegex.cache[key])
cachedRegex.cache[key] = new RegExp(reString, reFlags);
return cachedRegex.cache[key];
};
cachedRegex.cache = {};

这样测试:

makeWrappable('12345678901234567890 12345678901234567890 1234567890/1234567890')

更新2: 看起来零宽度空格实际上包含在复制的文本中,至少在某些情况下,你无法看到它们。显然,鼓励人们复制带有隐藏字符的文本是一种邀请,邀请人们将这样的数据输入其他程序或系统,甚至是您自己的程序或系统,这可能会导致问题。例如,如果它最终出现在数据库中,那么针对它的搜索可能会失败,像这样的搜索字符串也可能会失败。像这样使用箭头键来移动数据需要(正确地)一个额外的按键来移动你看不到的字符,如果用户注意到的话,他们会觉得有点奇怪。

在一个封闭的系统中,你可以在输入中过滤掉那个字符来保护你自己,但是这对其他程序和系统没有帮助。

总而言之,这种方法很有效,但我不确定哪种最好的选择造成断裂的字符将是。

更新3: 让这个字符最终出现在数据中不再是一种理论上的可能性,而是一个观察到的问题。用户提交从屏幕上复制下来的数据,它被保存在数据库中,搜索中断,事情排序怪异等等。.

我们做了两件事:

  1. 为此应用程序编写了一个实用程序,用于从所有数据源中的所有表的所有列中删除它们。
  2. 添加了过滤功能,将其移除到我们的标准字符串输入处理器中,所以当任何代码看到它时,它已经消失了。

这种方法很有效,技术本身也是如此,但这是一个警示故事。

更新4: 我们在这样一个上下文中使用它,其中提供给它的数据可能是 HTML 转义的。在适当的情况下,它可以在 HTML 实体的中间插入零宽度的空格,从而得到有趣的结果。

修正的方法是将与号添加到不断行的字符列表中,如下所示:

var longRunsRegex = cachedRegex('([^&\\s\\.\/\\,_@\\|-]{' + position + '})(?=[^&\\s\\.\/\\,_@\\|-])', 'g');

经过多次战斗,这对我有效:

.pre {
font-weight: 500;
font-family: Courier New, monospace;
white-space: pre-wrap;
word-wrap: break-word;
word-break: break-all;
-webkit-hyphens: auto;
-moz-hyphens: auto;
hyphens: auto;
}

适用于最新版本的 Chrome,Firefox 和 Opera。

注意,我排除了其他人建议的许多 white-space属性——这实际上破坏了我的 pre缩进。

对我来说,在一个没有固定大小和动态内容的 div 上,它的工作原理是:

display:table;
word-break:break-all;

在所有的字包装和打破, 保持你的溢出,看看这是否解决了你的问题。只要改变你的 div 的显示: display: inline;

为了与 IE8 + 兼容使用:

-ms-word-break: break-all;
word-break: break-all;


/* Non standard for webkit */
word-break: break-word;


-webkit-hyphens: auto;
-moz-hyphens: auto;
hyphens: auto;

看这里 http://css-tricks.com/snippets/css/prevent-long-urls-from-breaking-out-of-container/

我所要做的就是将其应用到带有设置宽度的 div 容器的样式。

一个简单的函数(需要 underscore.js)——基于@porneL answer

    String.prototype.shyBreakString = function(maxLength) {
var shystring = [];
_.each(this.split(' '), function(word){
shystring.push(_.chop(word, maxLength).join('&shy;'));
});
return shystring.join(' ');
};

将此添加到 div 的 css: word-wrap: break-word;

我必须这样做,因为如果属性没有按照正确的顺序声明,它就会在错误的位置随机地断开单词,而且不会添加连字符。

    -moz-white-space: pre-wrap;
white-space: pre-wrap;
hyphens: auto;
-ms-word-break: break-all;
-ms-word-wrap: break-all;
-webkit-word-break: break-word;
-webkit-word-wrap: break-word;
word-break: break-word;
word-wrap: break-word;
-webkit-hyphens: auto;
-moz-hyphens: auto;
-ms-hyphens: auto;
hyphens: auto;

最初由 Enigmo 发布: https://stackoverflow.com/a/14191114

p {
overflow-wrap: break-word;
}




@-moz-document url-prefix() {
p {
white-space: -moz-pre-wrap;
word-wrap: break-word;
}
}

用这个

word-wrap: break-word;
overflow-wrap: break-word;
word-break: break-all;

我已经写了一个函数,工程伟大的地方,它插入 &shy; x 字母到单词好断行。这里的所有答案并不支持所有的浏览器和设备,但是使用 PHP 可以很好地工作:

/**
* Add line-break to text x characters in
* @param  string  $text
* @param  integer $characters_in
* @return string
*/
function line_break_text($text, $characters_in = 10) {


$split = explode(' ', $text);


if ( ! empty($split)) {


foreach ($split as $key => $var) {


if ( strlen($var) > $characters_in ) {


$split[$key] = substr_replace($var, '&shy;', $characters_in, 0);


}


}


}


return implode(' ', $split);


}