从排版角度来说,“寡妇词”指的是尴尬地独自占据一行的单个单词。 它看起来不舒服,读起来也不舒服。 文章标题由于字体较大/行长较短,特别容易出现这种情况,并且寡妇词看起来异常尴尬。 例如,在这个博客上
很久以前,我曾经使用过一个 WordPress 插件来解决这个问题。 它基于 Typogrify,这是一个帮助简化网络上此类操作的小项目(自动)。 如今,该项目已经发展壮大,现在被称为 WP-Typography。 此插件不仅可以修复寡妇词,还提供各种功能来帮助改进网络排版,例如,自动将你的&符号包装在<span class=”amp”></span> 中,以便你可以 使用最佳的&符号。
出于某种原因,我脑子里一直认为我不喜欢使用这样的插件。 我认为这是因为我曾经有一个“保存到 Delicious”按钮。 此插件用于修复寡妇词的技术是在文本块的最后两个单词之间添加一个&nbsp;(不换行空格),从而使寡妇词无法出现。 但是,当有人使用我的“保存到 Delicious”按钮时,&nbsp; 会直接显示在文章标题中,看起来很丑陋和奇怪。
因此,当我再次开始想要解决这个问题时,我转向 JavaScript 寻求帮助,而不是 PHP,这样我就可以单独定位标题,而不是 WordPress 用于显示标题的功能。(**更新** 2013 年 8 月,AJ Zane 建议测试以确保标题不止一个单词,否则它会被移除。)
$("h2 a").each(function() {
var wordArray = $(this).text().split(" ");
if (wordArray.length > 1) {
wordArray[wordArray.length-2] += " " + wordArray[wordArray.length-1];
wordArray.pop();
$(this).html(wordArray.join(" "));
}
});
- 将标题拆分为一个单词数组
- 使用不换行空格将最后两个单词连接在一起
- 删除数组的最后一个项目(现在已冗余)
- 使用空格将数组重新连接在一起,并替换标题
效果很好! 尽管现在我的博客上不再有“保存到 Delicious”按钮了,但我认为我会恢复使用功能更强大的 WordPress 插件来执行此操作。 我相信你们大多数人都会同意,对于这样的事情,使用服务器端技术是更明智的做法。 顺便说一下,我对这些社交书签按钮的理论是,如果你已经是 Delicious 等社交书签服务的使用者,那么你已经知道如何添加书签了。 你可用的浏览器工具提供了比点击我帖子上的按钮更好的用户体验……
其他技巧
David Walsh 今天与我合作,并提供了如何使用 MooTools 和 PHP 实现这些消除寡妇词的技术。
我认为只要可以,就应该使用服务器端。 这就像你本周早些时候关于使用 Javascript 进行显示内容的文章一样,但你可以使用任何服务器端代码做更多的事情,而不用担心用户是否在浏览器中关闭了任何客户端脚本。
我们称之为“weesje”,翻译成孤儿。
从未想过要研究如何避免它们。 我也一直使用 技术。
网络上的排版真是一个棘手的问题。 要是每天有更多时间来跟上所有事情就好了。
喜欢你的帖子!
你碰巧是荷兰人吗? 荷兰语中有一些与排版相关的很棒/奇怪/有趣的词。 就像脏话。 我最喜欢的是“hoerenjong”和“weeskind”。 每次看到都让我发笑。
太棒了!
已添加到我的脚本中,非常感谢。
我几天前才开始阅读你的博客,我把它添加到我的 Google 阅读器中,我非常喜欢你的提示和技巧。 谢谢! :)
我通过在文章编辑器的标题字段中添加 不换行空格来解决了这个问题。 无需插件。 无需 JS。
并且提交到任何 URL 的 URL 需要 URL 编码的参数,而不是 HTML 编码的参数(即,我使用 html_entity_decode() 将所有内容从 &…; 转换为真实字符,然后使用 urlencode() 获取 %… 编码的文本)
第一行应该是“[…] 通过在文章编辑器的标题字段中添加 不换行空格 […]”
我不认为我喜欢直接在标题中添加它的想法。
1) 如果你不是从一开始就这样做,那么会有太多返工。
2) 如果你有一天决定确实希望它在那里换行怎么办。
我认为这是一个设计决定,应该在内容外部进行处理。
非常棒的技巧!
很棒的主题,而且我在网络博客中从未见过。 我认为寡妇词/孤儿词很重要。 它们真的会打乱布局。 很好地涵盖了它们!
效果很好! 谢谢
我本来想建议使用 CSS widows 属性,我检查了我的 CSS 参考,但遗憾的是,只有 Opera 支持它。 太可惜了! :(
有一个更简单的服务器端解决方案可以解决此问题,你可能可以通过编辑你的 WP-Typography 插件文件来实现。
与其使用不换行空格将最后两个单词连接起来,不如在它们周围添加一个 span 并使用“whitespace: nowrap;”来设置 span 的样式。
这就像&符号修复一样,在你使用共享服务时不会出错。
这是一个可能的解决方案……但我不知道我是否喜欢额外的标记,因为一个简单的 HTML 实体可以完成同样的工作。
对于任何想要尝试此方法的人来说,CSS 属性实际上是“white-space”,而不是“whitespace”。
我明白你的意思,但这就是我看到的
文章标题有两个主要问题:&符号和寡妇词。 因此,我们使用 WP-Typography,它在服务器端处理这两个问题。
但随后我们的修复为共享服务(如 Delicious)创建了一个新问题。 你的答案是对修复进行修复。 在此基础上,它是一个针对服务器端问题的客户端修复。
我不是专家,但我从事 Web 开发已经足够长的时间,知道以下两个最佳实践
1. 不要对另一个修复的负面影响进行修复。 找出原始修复中哪里出了问题并进行纠正。
2. 在可能的情况下,永远不要依赖 Javascript 来纠正可以在服务器端完全避免的事情。
仅供参考。 我很喜欢这个网站和原始主题,继续努力!
嗨
有趣的是,我多次想过这个问题。 而且我发现了这篇文章。
我发现了另一个关于同一主题的有趣内容。 它基本上是 CSS 解决方案。 查看
http://baselinecss.com/
这是一种有趣的技术,但是,它是在页面加载后进行的,因此用户可以注意到变化。 我确实注意到了第二行中单词是如何换行的。
这都很好,但请记住,如果浏览器不支持 Javascript 或禁用了 Javascript(就像我有时会做的那样),它将无法正常工作。
我可以想到两种可能的解决方案。
手动在你的文章标题中插入 nbsp,并防止最后一个单词换行。
使用 PHP 进行搜索和替换,在使用 WordPress 等 PHP 模板时不太容易,如果你自己编写 PHP,则非常简单高效。
调整你的字体大小以使其不换行,或更改 css 以实现 whitespace: nowrap;,这将完全禁用换行(可能会破坏设计)。
每种方法都有其自身的优缺点,Javascript 也是可能的,只需要记住它并非每个人都支持。
P.S. 希望这个网站支持 ol,因为如果不支持的话,这条评论看起来会很奇怪 :P (Chris,我建议添加一个预览按钮或一个支持的 HTML 列表)谢谢 :P
如果你有意禁用 JavaScript,那么如今网络上很多东西都会对你造成困扰,帖子标题中的寡妇词根本算不上什么问题。
我同意 Dor 的观点。在大多数情况下,我都是禁用 JS 浏览网页的,这不仅是为了安全,也是为了加快页面加载速度。我认为如果大量使用网络应用,可能会导致问题。
我喜欢阅读这个博客上的文章。我注意到你对寡妇词的定义存在轻微的误解。
寡妇词是指段落结尾的一行或一个词,出现在下一页或下一列的开头——并且与段落的其余部分隔开。孤儿词是指单独出现在页面/列底部的行/词。
这个定义来自罗伯特·布林赫斯特的《排版风格要素》(第 3.1 版),第 43-44 页。
在 Workbench 杂志实习期间,我合作的艺术总监提醒了我这一点,并让我意识到单字行并没有那么糟糕。
我同意,特别是标题中出现单字行多少有点难看,但这并不算寡妇词或孤儿词。我认为如果这个词足够长,可以超过下一段的缩进,并且不会在段落之间留下太多空白,那么出现单字行也是可以接受的。
感谢你的澄清。那么在谈论标题时,有没有合适的排版术语来描述单独一行上的一个词?我以为寡妇词最接近合适的描述。
我从事书籍出版工作,我们称段落的第一行单独出现在列/段落末尾为孤儿词,称段落的最后一行出现在段落开头为寡妇词。
段落最后一行上的单个单词通常称为段落寡妇词,但(请注意,我使用“段落”来涵盖任何独立的文本单元,例如标题、列表项等)。
我确实喜欢你的想法,但我同时也认为在客户端执行此操作并不实用。这绝对是服务器端的工作。
JavaScript 解决方案是最好的,因为它不会破坏内容。不要用不换行空格替换空格,而是使用带有“white-space: nowrap”样式的 span。这样你就不会修改内容,只是管理它。
叮叮叮!
我们有赢家了!
你可以简单地从一开始就将 white-space 声明应用到你的 H2 规则中,而无需进行任何其他操作。这也无需第二个修改后的解决方案,因为数据没有更改。
具有讽刺意味的是,一个名为 css-tricks 的博客却提倡一个笨拙的 JavaScript 解决方案,而存在一个更简单的纯 CSS 替代方案。;
叮叮叮!
如果你将 white-space 属性应用于 h2 标签,它将根本不会换行,效果会更糟。
为什么用这种粗鲁的方式开头评论?
笑死我了。
P.S.: … <strong 叮叮叮! :D
<nobr> html 标签有什么问题?
我道歉,我将避免使用音效 ;)
至少使用正则表达式来简化这个过程
$("h2 a").each(function() {
//将最后一个“词”之前的空格替换为不换行空格
var newText = $(this).text().replace(/\s(\S+)$/," $1");
$(this).html(newText);
});
你可以在一行代码中完成,但可读性较差。
应该是
var newText = $(this).text().replace(/\s(\S+)$/," $1");
或者更好一点…
$(“h2 a”).each(function() {
var self = $(this);
self.html( self.text().replace(/\s(\S+)$/,” $1″); );
});
* 缓存你的 jQuery
* 不需要变量时不要使用变量
;D
非常感谢各位!
最近才开始阅读这个网站。干得不错!迫不及待地想尝试一下 Typekit。
好技巧!谢谢 :)
那么,接下来呢?
为了避免这种情况,我通常会使用简短的标题并使用
white-space:nowrap;
,当然,还要为标题留出足够的空间。此外,你可以用一个具有
white-space:nowrap;
样式的行内元素/标签来替换最后两个词之间的不换行空格,而不是整个标题。我发现这种方法更经济实惠,也更可靠,以防用户代理禁用 JS。我们能否再添加一个 if 语句来检查最后一个词的长度?如果长度超过一定字符数,则不添加不换行空格?有时最后一个词非常长,添加不换行空格会导致孤儿词。
我在处理大量科学术语的网站上遇到了这个问题。
当然。
扩展我下面的示例
它设置为 20 个字符,但你可以根据需要设置更低或更高的值——如果超过 20 个字符,脚本将不会运行。:-)
或者对于那些老派人士,他们不需要大型 JS 库
var headings = document.getElementsByTagName("h1");
for (var i=0;i<headings.length;i++)
{
var h1s = headings[i].innerHTML.split(" ");
h1s[h1s.length-2] += " " + h1s[h1s.length-1];
h1s.pop();
headings[i].innerHTML = h1s.join(" ");
}
此示例使用 h1,但你可以轻松地将其替换为其他标签。:-)
只是一个简单的建议
不要写成这样
wordArray[wordArray.length-2] += " " + wordArray[wordArray.length-1];
wordArray.pop();
试试这个
wordArray[wordArray.length-2] += " " + wordArray.pop();
pop 方法删除最后一个元素并返回它,因此你只需一行代码即可完成这两件事。
出于某种原因,我无法让它工作,这非常令人沮丧。我似乎无法弄清楚我做错了什么。有人能看出我的错误吗?http://gigabetz.com/jquery-test.php
然后,这里有相应的CodePen 演示 :D
4 年后,哈哈。
Chris 的脚本存在一个小问题:如果你的标题包含任何标记,它们将被删除。
因此,如果你的标题如下所示:
<h1><a href="#">标题文本...</a></h1>
,则<a href="#"></a>
将被遗忘。所以我决定寻求帮助,现在上面的演示考虑到了这个问题,并且不会删除标题内的任何标记 :)
查看一下。