I’ve been wanting to attempt a port of Erik Loyer’s slabtype algorithm for quite some time now and seeing Paravel’s fittext jQuery plugin, in combination with a gloriously hassle-free lunch hour gave me the impetus to attempt it. This is the result – resize the browser viewport to see the effect in action.
Put simply, the script splits headlines into rows before resizing each row to fill the available horizontal space. The ideal number of characters to set on each row is calculated by dividing the available width by the CSS font-size – the script then uses this ideal character count to split the headline into word combinations that are displayed as separate rows of text. Many more examples can be viewed further down the page.
While the script does an admirable job at automating the creation of the individual rows, there are certainly situations in which you would choose to control the word combinations used to split the headline.
This can be achieved by presetting the word combinations (using wrappers) within the markup[1]. Should the script detect that the headline has been preset, it will not attempt to dynamically create the word combinations and simply fallback to resizing the preset rows to fit the available horizontal space.
Adding the span
elements to the page markup in this way gives you absolute control over the word combinations used to split the headline text and also enables the targetting of specific rows within the CSS (in order to tweak the line height, change the font family etc).
Presetting the headline does have its drawbacks though – at smaller sizes and if the rows have wildly varying letter-counts, jagged right edges may be displayed. The script will adjust the word-spacing
or letter-spacing
in an attempt to rectify over-shoots or under-shoots in line length like this.
The following demo showcases two versions of the same headline, the first has rows (word combinations) dynamically calculated by the script while the second has rows preset within the markup (and therefore only resized-to-fit by the script).
The following word combinations are calculated by the script
The following word combinations are preset within the markup
You may wish to remove the slabtext treatment entirely should either the viewport or the header element resize to below a certain, predefined width; for example, if the viewport width drops to below 380 pixels. This can be achievied by using the viewportBreakpoint
and headerBreakpoint
plugin options, detailed below.
This demo page has set viewportBreakpoint
to be 380 pixels. Resizing the browser window to anything below this should remove the slabtext treatment from the headlines altogether.
In an attempt to keep the plugin as fast as possible, a very basic font-size
calculation is ran whenever the window.resize
event fires. Headlines that have been preset only fire steps 1, 2, 6 and, if required, 7 – skipping steps 3 through 5 completely. To save extra cpu cycles, the resize event has been throttled to 300ms.
font-size
is then calculated.font-size
(calculated in step 2) which itself is multiplied by the font scale ratio (which defaults to 0.78) e.g. for a parent container width of 800 pixels and a font-size of 45 pixels the ideal number of characters per line would be calculated using Math.floor(800 / (45 × 0.78)) = 22
.
element and the headline markup updated with the new content.span
then has its font-size
adjusted by multiplying the current font-size
by the ratio difference between the parent containers width (calculated in step 1) and the width of the span
.span
then has either its letter-spacing
(if the line contains only one word) or its word-spacing
(if the line contains multiple words) adjusted in an attempt to prod the browser into rectifying over-shoots or under-shoots in line length caused by the previous font-size
adjustment.The following options can currently be passed to the plugin. The first three listed (fontRatio
, forceNewCharCount
and wrapAmpersand
) are only used whenever the plugin has to dynamically create the word combinations i.e. if elements are not already present within the markup.
font-size
changes (FALSE). Setting this value to FALSE will inevitably save CPU cycles but is only really of use in modern browsers that respond to media queries (or older browsers have been patched to respond to media queries). Defaults to TRUE.
(TRUE) or not (FALSE). Defaults to TRUE.window.resize
event (TRUE). Useful for those of you using a fixed width layout. Defaults to FALSE.It’s also worth noting that any non-breaking space character used to prevent widowed words within the original, non-adjusted headline will also be included within the adjusted headline.
The plugin requires the following CSS rules are made available:
.slabtexted .slabtext
{
display:-moz-inline-box;
display:inline-block
white-space:nowrap;
}
.slabtextinactive .slabtext
{
display:inline;
white-space:normal;
font-size:1em !important;
letter-spacing:inherit !important;
word-spacing:inherit !important;
*letter-spacing:0 !important;
*word-spacing:0 !important;
}
.slabtextdone .slabtext
{
display:block
}
The span
elements added to the headline are given the class slabtext
and the document body
given the class slabtexted
.
Using a double-whammy className inheritance trick like this means that you can safely add the elements into the markup but they won’t actually get styled until the script gets called and the
slabtexted
classname added to the body
.
The span
elements are set as display:inline-block
during the font-size calculation. This is to take advantage of the inline-block
shrink-wrap effect that enables the script to determine the width of each row.
Unfortunately, one side-effect of using inline-block
means that the injected span
elements react to surrounding whitespace (which, amongst other things, augments the vertical spacing between rows) – this is remedied by giving the header a classname of slabtextdone
whenever the font-size
calculation is complete, which sets a display:block
style and avoids the whitespace and styling issues associated with inline-block
.
Sharp-eyed readers may have noticed that the value of zero is passed to Internet Explorer using the star-hack. This is because IE < 8 doesn’t understand the inherit
property and so we reset to zero as a failsafe.
The CSS file is miniscule though and you may be better off pasting the contents of the minified version bundled with the download into your main CSS file to avoid an unnecessary HTTP request.
Here are a few things to remember when using the plug-in:
.html
method), which means that all images and links contained within will disappear without a trace.inline-block
, cannot scale down the text when the browser viewport is reduced in width. This may not be an issue if you serve a fixed width design to IE6 and fluid width design to other browsers.inherit
which means that the letter-spacing
and word-spacing
have to get reset to zero whenever the slabText treatment is removed by the script.fontface
fonts have downloaded (if using). I’ve hacked this for the demo to enable you to see the headline transformation as the script kicks-in but you should always use google WebFont loaders active()
and inactive()
callbacks to launch the slabText treatment (or a similar "font loaded" callback feature from another font provider).Based on the nice, shiny fittext jQuery plugin by Paravel & the wonderful slabtype algorithm by Erik Loyer. Zach Leatherman has also written a jQuery plugin named BigText with similar but not exact functionality which is well worth a visit.
The code can be . Both minified and unminified versions are included within the bundle. The minified version currently clocks-in at 3k – this drops to around 2k when gzipped.
As way of example, here’s a random assortment of book titles (Note: I’ve left widowed words in all of them).