如何防止长词的打破我的div?

自从TABLE-布局切换到DIV布局以来,一个常见的问题依然存在:

问题 :你用dynamic文本填充你的DIV,不可避免地会有一个超长的单词延伸到div列的边缘,使你的网站显得不专业。

RETRO-WHINING :表格布局从未发生过。 一个表格单元格将总是很好地扩展到最长单词的宽度。

严重性 :即使在最主要的网站上,尤其是在德国网站上,即使是像“限速”这样常见的词汇也很长的网站(“Geschwindigkeitsbegrenzung”),我们都会看到这个问题。

有没有人有一个可行的解决scheme呢?

软连字符

您可以通过插入软连字符( ­ )来告诉浏览器在何处分割长单词:

 averyvery­longword 

可能会呈现为

averyverylongword

要么

averyvery-
长字

一个很好的正则expression式可以确保你不会插入它们,除非必要:

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

浏览器和search引擎在search文本时足够聪明,可以忽略这个字符,Chrome和Firefox(还没有testing过其他的)在将文本复制到剪贴板时忽略它。

<wbr>元素

另一个select是注入一个以前的IE-ISM ,它现在在HTML5中 :

 averyvery<wbr>longword 

打破没有连字符:

averyvery
长字

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


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

 div.breaking { hyphens: auto; } 

然而,连字符是基于连字典,并不能保证打破冗长的单词。 它可以使理由更漂亮的文字虽然。

复古呜咽的解决scheme

布局不好,但display:table其他元素的display:table是好的。 它会像老式的桌子一样古怪(有弹性):

 div.breaking { display: table-cell; } 

overflowwhite-space: pre-wrap下面的white-space: pre-wrap答案也是好的。

两个修复:

  1. overflow:scroll – 这确保您的内容可以看到在devise的代价(滚动条是丑陋的)
  2. overflow:hidden – 只是切断任何溢出。 这意味着人们无法阅读内容。

如果(在这个例子中)你想阻止它重叠的填充,你可能需要在填充内创build另一个div来保存你的内容。

编辑:作为其他答案的状态,有各种截断单词的方法,是在客户端(不要试图做这个服务器端,因为它永远不会工作可靠,跨平台) JS和插入中断字符,或者使用非标准和/或非常不兼容的CSS标签( word-wrap: break-word 在Firefox中不起作用 )。

尽pipe你总是需要一个溢出描述符。 如果你的div包含另一个太宽的块types的内容(图像,表等),你将需要溢出,使其不破坏布局/devise。

所以通过一切手段使用另一种方法(或他们的组合),但也记得添加溢出,所以你覆盖所有的浏览器。

编辑2(以解决您的评论如下):

开始使用CSS overflow属性是不完美的,但它停止devise打破。 应用overflow:hidden首先overflow:hidden 。 请记住,填充可能不会中断,因此无论是嵌套div还是使用边框(无论哪个最适合您)。

这将隐藏溢出的内容,因此你可能会失去意义。 你可以使用一个滚动条(使用overflow:autooverflow:scroll而不是overflow:hidden ),但取决于div的大小和你的devise,这可能不看起来或工作很好。

为了解决这个问题,我们可以使用JS把事情拉回来,做一些forms的自动截断。 我半途而废地为你写了一些伪代码,但是中途变得非常复杂。 如果你需要尽可能地展示,请给连字符一下( 如下所述 )。

请注意,这是以用户的CPU为代价的。 这可能会导致页面花费很长时间来加载和/或resize。

这是一个复杂的问题,正如我们所知道的那样,并且不支持浏览器之间的任何常见方式。 大多数浏览器根本不支持本地function。

在使用HTML电子邮件进行的一些工作中,用户内容被使用,但是脚本不可用(即使CSS不被支持),下面的一些CSS在你的未分配内容块的包装中至less应该有所帮助:

 .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+似乎并不喜欢上述任何一种解决scheme,因此JavaScript将不得不成为这些浏览器(如Mozilla / Firefox)的解决scheme。另一种跨浏览器解决scheme(JavaScript),包括Opera将会使用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

CSS跨浏览器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+ */ } 

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

如果包含在样式表的主体定义中 ,它应该贯穿整个文档。

如果溢出不是一个好的解决scheme,只有一个自定义的javascript可以人为地分解长词。

注意:还有这个Word Break标签 。 这给了浏览器一个可以分割线的地方。 不幸的是, <wbr>标签在所有浏览器中都不起作用,只有Firefox和Internet Explorer(以及具有CSS技巧的Opera)。

使用样式word-break:break-all; 。 我知道它在桌子上工作。

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

 word-wrap: break-word; 

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

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

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

我刚刚从这个问题中发现了关于连词的 问题 。 这可能会解决这个问题。

经过多次战斗,这对我来说是有效的:

 .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缩进。

在这个评论中重新使用正则expression式,这是很好的,但是它只在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中处理这个过程非常简单,开销很低,但是当它们做的时候,你无法控制什么地方出现中断。 如果你不在乎,或者你的数据有很长的字母数字运行而没有任何自然的中断,那就好了。 我们有很多很长的文件path,URL和电话号码,所有这些地方都有比其他地方更好的地方。

我们的解决scheme是,首先使用正则expression式replace,在每个15个不是空白的字符或者我们更喜欢中断的特殊字符之后放置一个零宽度空间(&#8203;)。 然后我们再做一个replace,在这些特殊字符之后放置一个零宽度空间。

零宽度的空间很好,因为它们在屏幕上不可见; 害羞的连字符显示时很混乱,因为这些数据有明显的连字符。 当你从浏览器中复制文本时,零宽度空间也不包括在内。

我们目前使用的特殊中断字符是句号,正斜杠,反斜杠,逗号,下划线,@,|和连字符。 你不会认为你需要做任何事情来鼓励打破连字符后,但火狐(至less3.6和4)不会在数字(如电话号码)包围的连字符自行破坏。

我们还希望根据可用的布局空间来控制人造中断之间的字符数量。 这意味着匹配long non-breaking运行的正则expression式需要是dynamic的。 这被称为很多,我们不希望反复创build相同的正则expression式出于性能的原因,所以我们使用了一个简单的正则expression式caching,由正则expression式和它的标志键入。

这是代码; 你可能命名空间在实用程序包中的function:

 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 = {}; 

像这样testing:

 makeWrappable('12345678901234567890 12345678901234567890 1234567890/1234567890') 

更新2:至less在某些情况下,似乎零宽度的空间实际上已经包含在复制的文本中,您看不到它们。 显然,鼓励人们将隐藏的文字复制到文本中,就是邀请其他程序或系统中input的数据,甚至是自己的数据,这可能会导致问题。 例如,如果它在数据库中结束,对它的search可能会失败,search这样的string也可能会失败。 使用箭头键移动数据就像这样需要(正确)一个额外的按键来移动字符,你看不到,有点怪异的用户,如果他们注意到。

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

总而言之,这种技术运作良好,但我不确定什么是最好的select造成破坏的字符。

更新3:让这个angular色最终成为数据不再是一个理论上的可能性,这是一个观察到的问题。 用户提交从屏幕上复制的数据,它被保存在数据库中,search中断,事情古怪sorting等。

我们做了两件事:

  1. 写了一个实用程序,将它们从所有数据源中的所有表中的所有列中移除,以供此应用程序使用。
  2. 增加了filter,将其移除到我们的标准stringinput处理器,所以当代码看到它时,它就消失了。

这个效果很好,就像技术本身一样,但这是一个警示的故事。

更新4:我们正在使用这种情况下,数据可能会被HTML转义。 在正确的情况下,它可以在HTML实体的中间插入零宽度的空格,结果很奇怪。

修正是为我们不打破的字符列表添加&符号,如下所示:

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

我通常用于解决这个问题的解决scheme是为IE和其他浏览器设置2个不同的CSS规则:

 word-wrap: break-word; 

在IE浏览器完美的炒作,但文字包装不是一个标准的CSS属性。 这是一个微软的特定属性,不适用于Firefox。

对于Firefox来说,最好只使用CSS来设置规则

 overflow: hidden; 

包含要包装的文本的元素。 它不包裹文本,但是隐藏超过容器限制的文本部分 。 如果不是显示所有文本(例如,文本在<a>标签内),这可能是一个很好的解决scheme。

对于我没有固定大小和dynamic内容的工作使用:

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

需要设置“table-layout:fixed”来换行

HYPHENATOR是正确的答案(如上所述)。 你的问题背后的真正问题是,Web浏览器仍然(2008年)是非常原始的,他们没有连字符function。 看,我们还处在计算机使用的早期阶段 – 我们必须耐心等待。 只要devise师统治networking世界,我们将很难等待一些真正有用的新function。

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

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

我已经做了一些基本的testing,并且似乎适用于最新版本的Mobile Safari和Safari 5.1.1。

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

为了与IE 8+兼容使用:

 -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容器的样式中,并设置宽度。

用这个

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

如果你有这个 –

  <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而不是宽度使用最小宽度 –

  <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/> 

当然,如果您正在显示真正的表格数据,则可以使用真实的表格,因为它在语义上是正确的,并且会通知使用应该在表格中的屏幕阅读器的人员。 它正在使用它们来进行总体布局或图像切片,人们会欺骗你。

我不得不做下面的事情,因为如果属性没有按照正确的顺序被声明的话,它会在错误的地方随意地打破单词而不加连字符。

  -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

是的,如果可能的话,设置绝对宽度和设置overflow : auto运行良好。

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

“word-wrap:break-word”适用于Firefox 3.5 http://hacks.mozilla.org/2009/06/word-wrap/

一个简单的函数(需要underscore.js) – 基于@porneL的答案

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

把这个添加到你的div的cssword-wrap: break-word;

毕竟这个词包装和打破,保持你的溢出,看看这是否解决了你的问题。 只需将您的div的显示更改为: display: inline;