├── LICENSE.txt ├── README.textile ├── bower.json ├── css └── slabtext.css ├── index.html ├── js ├── jquery.slabtext.js └── jquery.slabtext.min.js └── slabtext.jquery.json /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) Brian McAllister 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. -------------------------------------------------------------------------------- /README.textile: -------------------------------------------------------------------------------- 1 | h1. slabText – a jQuery plugin for producing big, bold & responsive headlines 2 | 3 | All is explained on the "demo page":http://freqdec.github.io/slabText/. 4 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "slabText", 3 | "version": "2.4.0", 4 | "main": [ 5 | "js/jquery.slabtext.js", 6 | "css/slabtext.css" 7 | ], 8 | "dependencies": { 9 | "jquery": ">=1.4.2" 10 | }, 11 | "homepage": "https://github.com/freqdec/slabText", 12 | "authors": [ 13 | "Brian McAllister" 14 | ], 15 | "description": "A jQuery plugin for producing big, bold & responsive headlines.", 16 | "keywords": [ 17 | "text", 18 | "headlines" 19 | ], 20 | "license": "MIT", 21 | "ignore": [ 22 | "node_modules", 23 | "bower_components" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /css/slabtext.css: -------------------------------------------------------------------------------- 1 | .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:normal !important;*word-spacing:normal !important}.slabtextdone .slabtext{display:block} 2 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | slabText — a jQuery plugin for creating big, bold & responsive headlines 6 | 7 | 8 | 9 | 232 | 241 | 244 | 245 | 246 |

slabText – a jQuery plugin for producing big, bold & responsive headlines

247 |
248 |

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.

249 |

So what does the script do again?

250 |

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 pixel 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, many more examples can be viewed further down the page.

251 |

Calculated and preset word combinations

252 |

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.

253 |

This can be achieved by presetting the word combinations (using <span class="slabtext"> 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.

254 |

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).

255 |

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.

256 |

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).

257 |
258 |
259 |

The following word combinations have been calculated by the script

260 |

For one night only Jackie Mittoo with special Studio One guests Dillinger & Lone Ranger

261 |
262 |
263 |

The following word combinations have been preset within the markup

264 |

For one night only Jackie Mittoo with special Studio One guests Dillinger & Lone Ranger

265 |
266 |
267 |

Headers containing links

268 |

If the original header contains a link (or should itself have an href set), the generated spans will be wrapped in a link that uses the same href.

269 |

Being responsibly responsive

270 |

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.

271 |

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.

272 |

Behind the scenes

273 |

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.

274 |
    275 |
  1. The headlines pixel width is calculated.
  2. 276 |
  3. The headlines pixel font-size is then calculated.
  4. 277 |
  5. The ideal number of “characters per line” is derived by dividing the width (calculated in step 1) by the 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.
  6. 278 |
  7. The headline text is then split into words (by splitting on the space character) and these words arranged into combinations containing <= the number of ideal characters per line (calculated in step 3).
  8. 279 |
  9. Each word combination is then wrapped in a <span class="slabtext"> element and the headline markup updated with the new content.
  10. 280 |
  11. Each individual 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.
  12. 281 |
  13. If required, each individual 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.
  14. 282 |
283 |

Plugin options

284 |

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 <span class="slabtext"> elements are not already present within the markup.

285 |
286 |
fontRatio
287 |
A floating point value that is used when calculating the ideal number of “characters per line”. Defaults to 0.78.
288 |
forceNewCharCount
289 |
A Boolean value that instructs the script to recalculate the ideal number of “characters per line” and reinsert the spans every time the resize event fires (TRUE) or only whenever the parent containers 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. Defaults to TRUE.
290 |
wrapAmpersand
291 |
A Boolean value that instructs the script to wrap ampersands (&) in a <span class="amp"> (TRUE) or not (FALSE). Defaults to TRUE.
292 |
maxFontSize
293 |
An Integer value that indicates the maximum pixel font-size that the script can set. Defaults to 999.
294 |
viewportBreakpoint
295 |
An Integer value that indicates the minimum pixel width the viewport may have before the slabtext treatment is removed. There is no default value.
296 |
headerBreakpoint
297 |
An Integer value that indicates the minimum pixel width the header may have before the slabtext treatment is removed. There is no default value.
298 |
noResizeEvent
299 |
A Boolean value that instructs the script to ignore the window.resize event (TRUE) or not (FALSE). Useful for those of you using a fixed width layout. Defaults to FALSE.
300 |
resizeThrottleTime
301 |
An Integer value that indicates the number of milliseconds the window.resize will be throttled to. Defaults to 300.
302 |
precision
303 |
An Integer value that indicates the decimal precision to use when setting the CSS values line-height, word-spacing and font-size. Defaults to 3.
304 |
postTweak
305 |
A Boolean value that instructs the script to tweak the line-height or word-spacing after the font-size calculation has been ran (TRUE) or not (FALSE). Defaults to TRUE.
306 |
minCharsPerLine
307 |
An optional Integer value that indicates the minimum number of characters to set per line. Headlines that have a character count smaller than this value are not given the slabText treatment.
308 |
onRender
309 |
An optional function that is called every time the script recalculates the headline.
310 |
311 |

A note on the CSS

312 |

The plugin requires the following CSS rules are made available:

313 |
.slabtexted .slabtext
314 |     {
315 |     display: -moz-inline-box;
316 |     display: inline-block;
317 |     white-space: nowrap;
318 |     }
319 | .slabtextinactive .slabtext
320 |     {
321 |     display: inline;
322 |     white-space: normal;
323 |     font-size: 1em !important;
324 |     letter-spacing: inherit !important;
325 |     word-spacing: inherit !important;
326 |     *letter-spacing: normal !important;
327 |     *word-spacing: normal !important;
328 |     }
329 | .slabtextdone .slabtext
330 |     {
331 |     display: block;
332 |     }
333 |

The span elements added to the headline are given the class slabtext and the document body given the class slabtexted.

334 |

Using a double-whammy className inheritance trick like this means that you can safely add the <span class="slabtext"> elements into the markup but they won’t actually get styled until the script gets called and the slabtexted classname added to the body.

335 |

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.

336 |

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.

337 |

Legacy Internet Explorer

338 |

Sharp-eyed readers may have noticed that the value of normal is passed to legacy Internet Explorer versions using the star-hack. This is because IE < 8 doesn’t understand the inherit property and so we reset to normal as a failsafe.

339 |

Save an HTTP request

340 |

The CSS file is miniscule and you may wish to set-up a task runner to concatenate it into your main CSS file during the build process.

341 |

Tweaking line-height

342 |

Each span element is also given a classname of the form slabtext-linesize-[N] (where N is an Integer value representing the floored result of dividing the character count by ten) and a classname of the form slabtext-linelength-[N] (where N is an Integer value representing the character count). This enables you to target shorter lines that will be rendered at a larger font-size and adjust their line-height accordingly.

343 |

Widowed words within headlines

344 |

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.

345 |

Buyer beware

346 |

Here are a few things to remember when using the plug-in:

347 |
    348 |
  1. Headlines with lots of horizontal space to fill are more gracefully displayed across browsers.
  2. 349 |
  3. Headlines with little horizontal space tend to have jagged right edges, especially if the rows have been preset within the markup and each row has a wildly varying letter-count. Firefox appears to be the best at resizing-to-fit the word combinations and some fonts tend to be better than others at being resized-to-fit.
  4. 350 |
  5. The element to be given the slabText treatment has its (inner)HTML replaced entirely (by using the jQuery .html method), which means that all images and links contained within will disappear without a trace.
  6. 351 |
  7. Unlike the original slabtype algorithm, vertical space is not taken into consideration at all.
  8. 352 |
  9. If the header contains multiple links, only the first link located is taken into account.
  10. 353 |
  11. Internet Explorer 6, due to its non-support of inline-block, cannot scale down the text when the browser viewport is reduced in width. This will not be an issue if you serve a fixed width design to IE6 and fluid width design to other, more capable browsers.
  12. 354 |
  13. Internet Explorer < 8 does not support the CSS value of 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.
  14. 355 |
  15. Always call the script after all fontface fonts have downloaded. I’ve used the google fontloader fontactive() and fontinactive() callbacks to launch the slabText treatment in the demo.
  16. 356 |
357 |

Credit where credit’s due

358 |

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.

359 |

Grab the code

360 |

The code can be downloaded from github. 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.

361 |

A few more examples

362 |

As way of example, here’s a random assortment of book titles (Note: I’ve left widowed words in all of them).

363 |
364 |

The Sisters Brothers

365 |
366 |

Sometimes a Great Notion

367 |
368 |

The Peculiar Memories of Thomas Penman

369 |
370 |

The curious incident of the dog in the night

371 |
372 |

Something Happened

373 |
374 |

The sad tale of the brothers Grossbart

375 |
376 |

The Windup Girl

377 |
378 |

When Gravity Fails

379 |
380 |

Psychotic Reactions and Carburetor Dung

381 |
382 |

Mortal Engines

383 |
384 |

Tales of Ordinary Madness

385 |
386 |

Mansfield Park

387 |
388 |

The Importance of being Earnest

389 |
390 |

The Scarlet Letter

391 |
392 |

I Know This Much is True

393 |
394 |

Dracula

395 | 407 | 408 | 409 | 434 | 435 | 436 | -------------------------------------------------------------------------------- /js/jquery.slabtext.js: -------------------------------------------------------------------------------- 1 | /*! jQuery slabtext plugin v2.4.0 MIT/GPL2 @freqdec */ 2 | (function( $ ){ 3 | 4 | $.fn.slabText = function(options) { 5 | 6 | // Add the slabtexted classname to the body to initiate the styling of 7 | // the injected spans 8 | $("body").addClass("slabtexted"); 9 | 10 | return this.each(function(){ 11 | 12 | if(options) { 13 | $.extend(settings, options); 14 | }; 15 | 16 | var $this = $(this), 17 | self = this, 18 | settings = $.extend({}, $.fn.slabText.defaults, options), 19 | keepSpans = $("span.slabtext", $this).length, 20 | words = keepSpans ? [] : String($.trim($this.text())).replace(/\s{2,}/g, " ").split(" "), 21 | origFontSize = null, 22 | idealCharPerLine = null, 23 | resizeThrottle = null, 24 | viewportWidth = $(window).width(), 25 | headLink = $this.find("a:first").attr("href") || $this.attr("href"), 26 | linkTitle = headLink ? $this.find("a:first").attr("title") : ""; 27 | 28 | if(!keepSpans && settings.minCharsPerLine && words.join(" ").length < settings.minCharsPerLine) { 29 | return; 30 | }; 31 | 32 | // Calculates the pixel equivalent of 1em within the current header 33 | var grabPixelFontSize = function() { 34 | var dummy = jQuery('
 
').appendTo($this), 35 | emH = dummy.height(); 36 | dummy.remove(); 37 | return emH; 38 | }; 39 | 40 | // Most of this function is a (very) stripped down AS3 to JS port of 41 | // the slabtype algorithm by Eric Loyer with the original comments 42 | // left intact 43 | // http://erikloyer.com/index.php/blog/the_slabtype_algorithm_part_1_background/ 44 | var resizeSlabs = function resizeSlabs() { 45 | 46 | // Cache the parent containers width 47 | var parentWidth = $this.width(), 48 | fs; 49 | 50 | // Sanity check to prevent infinite loop 51 | if(parentWidth == 0) { 52 | return; 53 | }; 54 | 55 | // Remove the slabtextdone and slabtextinactive classnames to enable the inline-block shrink-wrap effect 56 | $this.removeClass("slabtextdone slabtextinactive"); 57 | 58 | if(settings.viewportBreakpoint && settings.viewportBreakpoint > viewportWidth 59 | || 60 | settings.headerBreakpoint && settings.headerBreakpoint > parentWidth) { 61 | // Add the slabtextinactive classname to set the spans as inline 62 | // and to reset the font-size to 1em (inherit won't work in IE6/7) 63 | $this.addClass("slabtextinactive"); 64 | return; 65 | }; 66 | 67 | fs = grabPixelFontSize(); 68 | // If the parent containers font-size has changed or the "forceNewCharCount" option is true (the default), 69 | // then recalculate the "characters per line" count and re-render the inner spans 70 | // Setting "forceNewCharCount" to false will save CPU cycles... 71 | if(!keepSpans && (settings.forceNewCharCount || fs != origFontSize)) { 72 | 73 | origFontSize = fs; 74 | 75 | var newCharPerLine = Math.min(60, Math.floor(parentWidth / (origFontSize * settings.fontRatio))), 76 | wordIndex = 0, 77 | lineText = [], 78 | counter = 0, 79 | preText = "", 80 | postText = "", 81 | finalText = "", 82 | lineLength, 83 | slice, 84 | preDiff, 85 | postDiff; 86 | 87 | if(newCharPerLine != 0 && newCharPerLine != idealCharPerLine) { 88 | idealCharPerLine = newCharPerLine; 89 | 90 | while (wordIndex < words.length) { 91 | 92 | postText = ""; 93 | 94 | // build two strings (preText and postText) word by word, with one 95 | // string always one word behind the other, until 96 | // the length of one string is less than the ideal number of characters 97 | // per line, while the length of the other is greater than that ideal 98 | while (postText.length < idealCharPerLine) { 99 | preText = postText; 100 | postText += words[wordIndex] + " "; 101 | if(++wordIndex >= words.length) { 102 | break; 103 | }; 104 | }; 105 | 106 | // This bit hacks in a minimum characters per line test 107 | // on the last line 108 | if(settings.minCharsPerLine) { 109 | slice = words.slice(wordIndex).join(" "); 110 | if(slice.length < settings.minCharsPerLine) { 111 | postText += slice; 112 | preText = postText; 113 | wordIndex = words.length + 2; 114 | }; 115 | }; 116 | 117 | // calculate the character difference between the two strings and the 118 | // ideal number of characters per line 119 | preDiff = idealCharPerLine - preText.length; 120 | postDiff = postText.length - idealCharPerLine; 121 | 122 | // if the smaller string is closer to the length of the ideal than 123 | // the longer string, and doesn’t contain less than minCharsPerLine 124 | // characters, then use that one for the line 125 | if((preDiff < postDiff) && (preText.length >= (settings.minCharsPerLine || 2))) { 126 | finalText = preText; 127 | wordIndex--; 128 | // otherwise, use the longer string for the line 129 | } else { 130 | finalText = postText; 131 | }; 132 | 133 | lineLength = $.trim(finalText).length; 134 | 135 | // HTML-escape the text 136 | finalText = $('
').text(finalText).html() 137 | 138 | // Wrap ampersands in spans with class `amp` for specific styling 139 | if(settings.wrapAmpersand) { 140 | finalText = finalText.replace(/&/g, '&'); 141 | }; 142 | 143 | finalText = $.trim(finalText); 144 | 145 | lineText.push('' + finalText + ""); 146 | }; 147 | 148 | $this.html(lineText.join(" ")); 149 | // If we have a headLink, add it back just inside our target, around all the slabText spans 150 | if(headLink) { 151 | $this.wrapInner(''); 152 | }; 153 | }; 154 | } else { 155 | // We only need the font-size for the resize-to-fit functionality 156 | // if not injecting the spans 157 | origFontSize = fs; 158 | }; 159 | 160 | $("span.slabtext", $this).each(function() { 161 | var $span = $(this), 162 | innerText = $span.text(), 163 | wordSpacing = innerText.split(" ").length > 1, 164 | diff, 165 | ratio, 166 | fontSize; 167 | 168 | if(settings.postTweak) { 169 | $span.css({ 170 | "word-spacing":0, 171 | "letter-spacing":0 172 | }); 173 | }; 174 | 175 | ratio = parentWidth / $span.width(); 176 | fontSize = parseFloat(this.style.fontSize) || origFontSize; 177 | 178 | $span.css("font-size", Math.min((fontSize * ratio).toFixed(settings.precision), settings.maxFontSize) + "px"); 179 | 180 | // Do we still have space to try to fill or crop 181 | diff = !!settings.postTweak ? parentWidth - $span.width() : false; 182 | 183 | // A "dumb" tweak in the blind hope that the browser will 184 | // resize the text to better fit the available space. 185 | // Better "dumb" and fast... 186 | if(diff) { 187 | $span.css((wordSpacing ? 'word' : 'letter') + '-spacing', (diff / (wordSpacing ? innerText.split(" ").length - 1 : innerText.length)).toFixed(settings.precision) + "px"); 188 | }; 189 | }); 190 | 191 | // Add the class slabtextdone to set a display:block on the child spans 192 | // and avoid styling & layout issues associated with inline-block 193 | $this.addClass("slabtextdone"); 194 | 195 | // Fire the callback if required 196 | if(typeof settings.onRender == 'function') { 197 | settings.onRender.call(self); 198 | }; 199 | }; 200 | 201 | // Immediate resize 202 | resizeSlabs(); 203 | 204 | if(!settings.noResizeEvent) { 205 | $(window).resize(function() { 206 | // Only run the resize code if the viewport width has changed. 207 | // we ignore the viewport height as it will be constantly changing. 208 | if($(window).width() == viewportWidth) { 209 | return; 210 | }; 211 | 212 | viewportWidth = $(window).width(); 213 | 214 | clearTimeout(resizeThrottle); 215 | resizeThrottle = setTimeout(resizeSlabs, settings.resizeThrottleTime); 216 | }); 217 | }; 218 | }); 219 | }; 220 | 221 | $.fn.slabText.defaults = { 222 | // The ratio used when calculating the characters per line 223 | // (parent width / (font-size * fontRatio)). 224 | "fontRatio" : 0.78, 225 | // Always recalculate the characters per line, not just when the 226 | // font-size changes? Defaults to true (CPU intensive) 227 | "forceNewCharCount" : true, 228 | // Do we wrap ampersands in 229 | "wrapAmpersand" : true, 230 | // Under what pixel width do we remove the slabtext styling? 231 | "headerBreakpoint" : null, 232 | "viewportBreakpoint" : null, 233 | // Don't attach a resize event 234 | "noResizeEvent" : false, 235 | // By many milliseconds do we throttle the resize event 236 | "resizeThrottleTime" : 300, 237 | // The maximum pixel font size the script can set 238 | "maxFontSize" : 999, 239 | // Do we try to tweak the letter-spacing or word-spacing? 240 | "postTweak" : true, 241 | // Decimal precision to use when setting CSS values 242 | "precision" : 3, 243 | // The min num of chars a line has to contain 244 | "minCharsPerLine" : 0, 245 | // Callback function fired after the headline is redrawn 246 | "onRender" : null 247 | }; 248 | 249 | })(jQuery); 250 | -------------------------------------------------------------------------------- /js/jquery.slabtext.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery slabtext plugin v2.4.0 MIT/GPL2 @freqdec */ 2 | !function(a){a.fn.slabText=function(b){return a("body").addClass("slabtexted"),this.each(function(){b&&a.extend(e,b);var c=a(this),d=this,e=a.extend({},a.fn.slabText.defaults,b),f=a("span.slabtext",c).length,g=f?[]:String(a.trim(c.text())).replace(/\s{2,}/g," ").split(" "),h=null,i=null,j=null,k=a(window).width(),l=c.find("a:first").attr("href")||c.attr("href"),m=l?c.find("a:first").attr("title"):"";if(!(!f&&e.minCharsPerLine&&g.join(" ").length 
').appendTo(c),b=a.height();return a.remove(),b},o=function(){var j,b=c.width();if(0!=b){if(c.removeClass("slabtextdone slabtextinactive"),e.viewportBreakpoint&&e.viewportBreakpoint>k||e.headerBreakpoint&&e.headerBreakpoint>b)return void c.addClass("slabtextinactive");if(j=n(),f||!e.forceNewCharCount&&j==h)h=j;else{h=j;var v,w,x,y,o=Math.min(60,Math.floor(b/(h*e.fontRatio))),p=0,q=[],s="",t="",u="";if(0!=o&&o!=i){for(i=o;p=g.length)););e.minCharsPerLine&&(w=g.slice(p).join(" "),w.lengthx&&s.length>=(e.minCharsPerLine||2)?(u=s,p--):u=t,v=a.trim(u).length,u=a("
").text(u).html(),e.wrapAmpersand&&(u=u.replace(/&/g,'&')),u=a.trim(u),q.push(''+u+"")}c.html(q.join(" ")),l&&c.wrapInner('")}}a("span.slabtext",c).each(function(){var g,i,j,c=a(this),d=c.text(),f=d.split(" ").length>1;e.postTweak&&c.css({"word-spacing":0,"letter-spacing":0}),i=b/c.width(),j=parseFloat(this.style.fontSize)||h,c.css("font-size",Math.min((j*i).toFixed(e.precision),e.maxFontSize)+"px"),g=e.postTweak?b-c.width():!1,g&&c.css((f?"word":"letter")+"-spacing",(g/(f?d.split(" ").length-1:d.length)).toFixed(e.precision)+"px")}),c.addClass("slabtextdone"),"function"==typeof e.onRender&&e.onRender.call(d)}};o(),e.noResizeEvent||a(window).resize(function(){a(window).width()!=k&&(k=a(window).width(),clearTimeout(j),j=setTimeout(o,e.resizeThrottleTime))})}})},a.fn.slabText.defaults={fontRatio:.78,forceNewCharCount:!0,wrapAmpersand:!0,headerBreakpoint:null,viewportBreakpoint:null,noResizeEvent:!1,resizeThrottleTime:300,maxFontSize:999,postTweak:!0,precision:3,minCharsPerLine:0,onRender:null}}(jQuery); 3 | -------------------------------------------------------------------------------- /slabtext.jquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "slabtext", 3 | "title": "slabText", 4 | "description": "slabText – a jQuery plugin for producing big, bold & responsive headlines", 5 | "keywords": [ 6 | "typography" 7 | ], 8 | "version": "2.4.0", 9 | "author": { 10 | "name": "Brian McAllister", 11 | "url": "https://twitter.com/freqdec" 12 | }, 13 | "licenses": [ 14 | { 15 | "type": "MIT", 16 | "url": "https://github.com/freqdec/slabText/blob/master/LICENSE.txt" 17 | } 18 | ], 19 | "bugs": "https://github.com/freqdec/slabText/issues", 20 | "homepage": "http://freqdec.github.io/slabText/", 21 | "docs": "http://freqdec.github.io/slabText/", 22 | "download": "https://github.com/freqdec/slabText", 23 | "dependencies": { 24 | "jquery": ">=1.4.2" 25 | } 26 | } 27 | --------------------------------------------------------------------------------