What is the widow problem you might ask?
in typesetting, a widow is a single word on a line by itself at the end of a paragraph and is considered bad style.
![]()
From Shaun Inman.
I'm going to present two methods of avoiding the widow problem on your website, each with it's own advantages and disadvantages.
-
The client side approach
Using Javascript we can manipulate the headings after the page has loaded and add a non breaking space between the last two words of the content. There's a jQuery plugin which does this. I modified it to solve some bugs and created a module which uses it. It applies the transformations to elements which match one of the following rules:
- #content h1.title
- #content h2.node-title a
It's available here: http://drupal.org/project/widont
Advantages: easy to install, most of the time works out of the box.
Disadvantages: it doesn't work when Javascript is disabled, on some themes who use different classes for the title headings it will fail.
-
The server side approach
You'll need to know how to edit the files from the theme you're using. I'm going to assume that you're using Garland, the default Drupal theme, but the instructions can be applied to every Drupal theme out there.
First you'll have to edit the template.php file which is located in your theme directory. Add the following code there:
- function garland_widont($str = '')
- {
- $str = rtrim($str);
- $space = strrpos($str, ' ');
- if ($space !== false)
- {
- $str = substr($str, 0, $space).' '.substr($str, $space + 1);
- }
- return $str;
- }
Replace garland with your theme's name. E.g. k2_widont, bluemarine_widont.
Now we need to edit the files where the titles are printed. First, page.tpl.php. Find the following code and replace it with the one beneath it.
- <?php if ($title): print '<h2'. ($tabs ? ' class="with-tabs"' : '') .'>'. $title .'</h2>'; endif; ?>
- <?php if ($title): print '<h2'. ($tabs ? ' class="with-tabs"' : '') .'>'. garland_widont($title) .'</h2>'; endif; ?>
Next, node.tpl.php:
Find
- <?php if ($page == 0): ?>
- <h2><a href="<?php print $node_url ?>" title="<?php print $title ?>"><?php print $title ?></a></h2>
- <?php endif; ?>
and replace it with:
- <?php if ($page == 0): ?>
- <h2><a href="<?php print $node_url ?>" title="<?php print $title ?>"><?php print garland_widont($title) ?></a></h2>
- <?php endif; ?>
If you have separate template files for each node type (e.g. node-page.tpl.php and node-story.tpl.php) you'll need to edit those as well. Also, you can edit the block template file (block.tpl.php) or the comments one (comment.tpl.php) if you want.
Advantages: works even if Javascript is turned off, works on all themes.
Disadvantages: you have to do it everytime you change your theme, it's harder to implement.


Comments
With regards to accessibility. If a user grows/shrinks their text, due to floating wont this always be an issue no matter what?
If thats the case, and at some point you will get:
The
lonely
life
of
an
unlucky
widow
why bother trying to fix it. The web is not a physical medium, printers and screen will all treat the text differently. The php approach is costly because its a cost served up on every page (even with caching, it must be done once at some time). The JS solution is not guarenteeable (not everyone can run js, whereas php is always on the server).
Post new comment