2011-09-16 154 views
18

在HTML/CSS中使用印刷术时常见的问题是我们在瑞典语中称为“horunge”(英语为“widow”)。JavaScript避免寡妇

它是什么:

假设你有一个盒子的200像素的宽度和与文本“我爱typograpy非常”。现在的文本休息和变成:

我爱印刷术很

作为一名设计师,我不想一个字私生子(单字/行)。如果这是一个文件/ PDF等我会很前打破字,看起来像这样:

我爱印刷术
非常

看起来好多了。

我可以用CSS规则或javascript解决这个问题吗?这条规则应该是永远不要让一个字在一行中空虚。

我知道它可以通过添加<br />来解决,但是这不是动态的宽度,进料的内容,不同的翻译, 我解决了浏览器字体渲染问题等

更新(解决方案)有效的解决方案我的问题与此jquery插件:http://matthewlein.com/widowfix/

+0

寡妇......单词混蛋......我爱瑞典! :) – rybo111

回答

0

也有CSS寡妇和孤儿属性:请参阅about.com article

不知道有关浏览器支持...

编辑:https://bugs.webkit.org/buglist.cgi?quicksearch=orphans:约WebKit的执行此处了解更多信息。

+0

这两个只适用于打印http://www.w3.org/TR/CSS21/page.html#break-inside – c69

+0

@ c69你是对的。任何人都知道有任何计划将这个添加到非分页媒体?在网路上找不到任何东西。很高兴看到更多类似于屏幕媒体的排版工具(以及流程和周转)。 –

+0

http://www.w3.org/TR/css3-regions/#best-region-breaks - 这些东西的一些工作在IE10 pp3中,并且也将在新的WebKit中工作。 – c69

0

我做了一点script here,在this function的帮助下找到线高。

这只是一种方法,它可能工作也可能不工作,没有时间进行彻底测试。

截至目前,text_element必须是jQuery对象。

function avoidBastardWord(text_element) 
{ 
    var string = text_element.text(); 
    var parent = text_element.parent(); 
    var parent_width = parent.width(); 
    var parent_height = parent.height(); 

    // determine how many lines the text is split into 
    var lines = parent_height/getLineHeight(text_element.parent()[0]); 

    // if the text element width is less than the parent width, 
    // there may be a widow 
    if (text_element.width() < parent_width) 
    { 
     // find the last word of the entire text 
     var last_word = text_element.text().split(' ').pop(); 

     // remove it from our text, creating a temporary string 
     var temp_string = string.substring(0, string.length - last_word.length - 1); 

     // set the new one-word-less text string into our element 
     text_element.text(temp_string); 

     // check lines again with this new text with one word less 
     var new_lines = parent.height()/getLineHeight(text_element.parent()[0]); 

     // if now there are less lines, it means that word was a widow 
     if (new_lines != lines) 
     { 
      // separate each word 
      temp_string = string.split(' '); 

      // put a space before the second word from the last 
      // (the one before the widow word) 
      temp_string[ temp_string.length - 2 ] = '<br>' + temp_string[ temp_string.length - 2 ] ; 

      // recreate the string again 
      temp_string = temp_string.join(' '); 

      // our element html becomes the string 
      text_element.html(temp_string); 
     } 
     else 
     { 
      // put back the original text into the element 
      text_element.text(string); 
     } 

    } 

} 

不同的浏览器有不同的字体设置。尝试发挥一点,以查看差异。我测试了它在IE8和Opera上,每次修改字符串,它似乎工作正常。

我希望听到一些反馈意见并加以改进,因为我认为它可能派上用场。

只是玩它! :)

0

手动,你可以在之间,&nbsp;

替代空间我一直在寻找各种方法来在动态地添加它。我发现了一些,但一直无法让它自己工作。

+0

应与“&n b s p;” (没有空格,没有空格) – matt

+0

在两个'符号之间包装代码以允许正确的格式化 – Luca

6

一个简单的jQuery/regrex解决方案可能如下所示,如果您将类“noWidows”添加到包含您担心的文本的任何元素的标记中。

如:

<p class="noWidows">This is a very important body of text.</p> 

然后使用这个脚本:

$('.noWidows').each(function(i,d){ 
    $(d).html($(d).text().replace(/\s(?=[^\s]*$)/g, "&nbsp;")) 
}); 

它使用正则表达式来查找和使用非中断字符替换字符串中的最后一个空格。这意味着最后两个单词将被强制在同一行上。这是一个很好的解决方案,如果在行尾有空格,这可能会导致文本在具有固定宽度的元素之外运行,或者如果不固定,则会导致元素变大。

+0

如果这不会在所述元素内部破坏html,那将会很好。 – ShayneStatzell

2

只是想添加到此页面,因为它帮助了我很多。

如果你有(寡妇)实际上应该是孤儿,因为寡妇是在下一页登陆的单个单词而不是新单行的单个单词。

使用像“N12 5GG”这样的邮政编码会导致整个邮政编码在一个新行上,但仍然归类为孤儿,所以解决这个问题。 (改变了类“noWidow2”这样你就可以使用这两个版本。

123 Some_road,Some_town,N12 5GG

$('.noWidows2').each(function(i,d){ 
    var value="&nbsp;" 
    $(d).html($(d).text().replace(/\s(?=[^\s]*$)/g, value).replace(/\s(?=[^\s]*$)/g, value)); 
}); 

这将导致是最后的3个白色空间是一个新行一起使邮政编码问题的工作。

最终结果

123 Some_road, 
Some_town, N12 5GG 
0

$('span').each(function() { 
 
    var w = this.textContent.split(" "); 
 
    if (w.length > 1) { 
 
    w[w.length - 2] += "&nbsp;" + w[w.length - 1]; 
 
    w.pop(); 
 
    this.innerHTML = (w.join(" ")); 
 
    } 
 
});
#foo { 
 
    width: 124px; 
 
    border: 1px solid #ccc; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="foo"> 
 
    <span class="orphan">hello there I am a string really really long, I wonder how many lines I have</span> 
 
</div>