├── .gitignore ├── README.md ├── bower.json ├── package.json ├── Gruntfile.js ├── dist ├── squishy.min.js └── squishy.js ├── tests └── test.html └── src └── squishy.js /.gitignore: -------------------------------------------------------------------------------- 1 | *.rar 2 | *.zip 3 | tests/ 4 | node_modules/ 5 | bower_components/ 6 | Makefile 7 | links/ 8 | .sass-cache -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Squishy.js 2 | ## by Chris Sauvé of [lemon design](http://www.lemondesign.co) 3 | 4 | Squishy is a jQuery plugin that automatically resizes text to exactly fit the container with no extra work on your part. 5 | 6 | You can view a demo on the [project page](http://cmsauve.com/labs/squishy) for this plugin. 7 | 8 | Much thanks to the guys at [Paravel](http://paravelinc.com/) for their work on [FitText](http://fittextjs.com/), on which this script is largely based. This plugin only works for a single line; if you are looking for multiline text fitting, I recommend [SlabText](http://www.frequency-decoder.com/demo/slabText/). -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "squishy", 3 | "main": "src/squishy.js", 4 | "version": "1.0.1", 5 | "homepage": "http://www.cmsauve.com/projects/squishy", 6 | "authors": [ 7 | "Chris Sauve " 8 | ], 9 | "description": "A jQuery plugin to size text such that it completely fills its container.", 10 | "keywords": [ 11 | "jquery", 12 | "plugin", 13 | "squishy", 14 | "text", 15 | "resizing" 16 | ], 17 | "license": "MIT", 18 | "ignore": [ 19 | "**/.*", 20 | "node_modules", 21 | "bower_components", 22 | "test", 23 | "tests" 24 | ], 25 | "dependencies": { 26 | "jquery": ">= 1.9.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "squishy", 3 | "version": "1.0.0", 4 | "main": "dist/squishy.js", 5 | "description": "A jQuery plugin to size text such that it completely fills its container.", 6 | "homepage": "http://www.cmsauve.com/projects/squishy", 7 | "devDependencies": { 8 | "grunt": "~0.4.1", 9 | "grunt-contrib-uglify": "~0.2.7", 10 | "grunt-contrib-watch": "~0.5.3", 11 | "load-grunt-tasks": "~0.2.1", 12 | "grunt-contrib-jshint": "~0.7.2", 13 | "jshint-stylish": "~0.1.4", 14 | "grunt-shell": "~0.6.4" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/pxldot/squishy.git" 19 | }, 20 | "bugs": { 21 | "url": "https://github.com/pxldot/squishy/issues" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | // 1. CONFIG 4 | grunt.initConfig({ 5 | pkg: grunt.file.readJSON("package.json"), 6 | 7 | jshint: { 8 | options: { 9 | reporter: require("jshint-stylish"), 10 | 11 | globals: { 12 | console: true, 13 | $: true, 14 | jQuery: true, 15 | } 16 | }, 17 | 18 | target: ["src/squishy.js"] 19 | }, 20 | 21 | uglify: { 22 | build: { 23 | src: "src/squishy.js", 24 | dest: "dist/squishy.min.js" 25 | } 26 | }, 27 | 28 | shell: { 29 | copyMain: { 30 | command: 'cp src/squishy.js dist/squishy.js' 31 | } 32 | }, 33 | 34 | watch: { 35 | options: { livereload: false }, 36 | 37 | js: { 38 | files: ["src/bigfoot.js"], 39 | tasks: ["uglify", "jshint", "shell:copyMain"], 40 | options: { spawn: false } 41 | } 42 | } 43 | }); 44 | 45 | // 2. TASKS 46 | require("load-grunt-tasks")(grunt); 47 | 48 | // 3. PERFORM 49 | grunt.registerTask("default", ["jshint", "uglify", "shell"]); 50 | 51 | } -------------------------------------------------------------------------------- /dist/squishy.min.js: -------------------------------------------------------------------------------- 1 | !function(a){a.fn.squishy=function(b){var c=a.extend({minSize:-1e4,maxSize:1e4,maxWidth:1e4,minWidth:-1e4,runAutomatically:!0,equalizeSizes:!1,callback:null,condition:null},b),d=this,e=function(b,e){if(!c.condition||c.condition()){var f,g=1e4,h=[],i=0;f=e?d.filter(function(){return a(this).is(e)}):d,f.each(function(){var b=a(this),d=b.html(),e=b.html(""+d+"").children("#checkSizeForSquishing"),f=e.width(),j=Math.max(parseFloat(c.minWidth),Math.min(b.width(),parseFloat(c.maxWidth))),k=parseFloat(b.css("font-size")),l=k*j/f;l=Math.floor(Math.min(Math.max(l,parseFloat(c.minSize)),parseFloat(c.maxSize))),c.equalizeSizes&&(g=g>l?l:g),b.css({"white-space":"nowrap","font-size":l,"text-align":"justify"}).html(d),c.callback&&(h.push(l),i++)}),c.equalizeSizes&&f.each(function(){a(this).css("font-size",g)}),c.callback&&c.callback(h)}};return c.runAutomatically&&(a(document).ready(function(){e()}),a(window).on("resize.squishy orientationchange.squishy",e)),{resize:function(a){return e(null,a)},makeAutomatic:function(){c.runAutomatically||(c.runAutomatically=!0,e(),a(window).on("resize.squishy orientationchange.squishy",e))},unSquish:function(b){c.runAutomatically=!1,a(window).off("resize.squishy orientationchange.squishy"),d.css({"white-space":"","text-align":""}),b||d.css("font-size","")},set:function(a,b){c[a]=b}}}}(jQuery); -------------------------------------------------------------------------------- /tests/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | squishy.js Tests 7 | 8 | 9 | 10 | 23 | 24 | 25 | 26 |

Squish this!

27 |

Squish this!

28 |
29 |

30 | Lorem ipsum dolor sit amet, consectetur adipisicing. 31 |

32 |

33 | Lorem ipsum dolor sit amet, consectetur adipisicing. 34 |

35 |
36 | 37 | 54 | 55 | -------------------------------------------------------------------------------- /src/squishy.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 3 | $.fn.squishy = function(options) { 4 | 5 | // Setup options 6 | var settings = $.extend({ 7 | minSize : -10000, 8 | maxSize : 10000, 9 | maxWidth : 10000, 10 | minWidth : -10000, 11 | runAutomatically : true, 12 | equalizeSizes : false, 13 | callback : null, 14 | condition : null 15 | }, options); 16 | 17 | var that = this; 18 | 19 | // Does the resizing 20 | var resizer = function(e, subsetSelector) { 21 | 22 | if(settings.condition && !settings.condition()) { return; } 23 | 24 | var actOn, 25 | minFontSize = 10000, 26 | finalFontSize = [], 27 | count = 0; 28 | 29 | if(subsetSelector) { 30 | actOn = that.filter(function() { 31 | return $(this).is(subsetSelector); 32 | }); 33 | } else { 34 | actOn = that; 35 | } 36 | 37 | actOn.each(function() { 38 | var $this = $(this); 39 | 40 | // Add the wrapper span 41 | var theText = $this.html(), 42 | $span = $this.html("" + theText + "").children("#checkSizeForSquishing"); 43 | 44 | // Figuring out the relevant widths 45 | var spanWidth = $span.width(), 46 | blockWidth = Math.max(parseFloat(settings.minWidth), 47 | Math.min($this.width(), 48 | parseFloat(settings.maxWidth)) 49 | ), 50 | fontSize = parseFloat($this.css("font-size")); 51 | 52 | // console.log("fontSize: " + fontSize + ", blockWidth: " + blockWidth + ", spanWidth: " + spanWidth); 53 | 54 | // Set the target size (restricted by min/max sizes) 55 | var targetSize = fontSize*blockWidth/spanWidth; 56 | 57 | targetSize = Math.floor(Math.min(Math.max(targetSize, parseFloat(settings.minSize)), parseFloat(settings.maxSize))); 58 | 59 | if(settings.equalizeSizes) { 60 | minFontSize = (targetSize < minFontSize) ? 61 | targetSize : minFontSize; 62 | } 63 | 64 | $this.css({"white-space": "nowrap", "font-size": targetSize, "text-align": "justify"}).html(theText); 65 | 66 | if(settings.callback) { 67 | finalFontSize.push(targetSize); 68 | count++; 69 | } 70 | }); 71 | 72 | if(settings.equalizeSizes) { 73 | actOn.each(function() { 74 | $(this).css("font-size", minFontSize); 75 | }); 76 | } 77 | 78 | if(settings.callback) { 79 | settings.callback(finalFontSize); 80 | } 81 | }; 82 | 83 | if(settings.runAutomatically) { 84 | // Initial will get it bigger but not too big 85 | $(document).ready(function() { 86 | resizer(); 87 | }); 88 | 89 | // Calls the resize on viewport width or orientation change 90 | $(window).on("resize.squishy orientationchange.squishy", resizer); 91 | } 92 | 93 | return { 94 | resize: function(selector) { 95 | return resizer(null, selector); 96 | }, 97 | 98 | makeAutomatic: function() { 99 | if(!settings.runAutomatically) { 100 | settings.runAutomatically = true; 101 | resizer(); 102 | $(window).on("resize.squishy orientationchange.squishy", resizer); 103 | } 104 | }, 105 | 106 | unSquish: function(keepFontSize) { 107 | settings.runAutomatically = false; 108 | $(window).off("resize.squishy orientationchange.squishy"); 109 | that.css({"white-space": "", "text-align": ""}); 110 | if(!keepFontSize) { that.css("font-size", ""); } 111 | }, 112 | 113 | set: function(setting, value) { 114 | settings[setting] = value; 115 | } 116 | }; 117 | }; 118 | 119 | })(jQuery); -------------------------------------------------------------------------------- /dist/squishy.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 3 | $.fn.squishy = function(options) { 4 | 5 | // Setup options 6 | var settings = $.extend({ 7 | minSize : -10000, 8 | maxSize : 10000, 9 | maxWidth : 10000, 10 | minWidth : -10000, 11 | runAutomatically : true, 12 | equalizeSizes : false, 13 | callback : null, 14 | condition : null 15 | }, options); 16 | 17 | var that = this; 18 | 19 | // Does the resizing 20 | var resizer = function(e, subsetSelector) { 21 | 22 | if(settings.condition && !settings.condition()) { return; } 23 | 24 | var actOn, 25 | minFontSize = 10000, 26 | finalFontSize = [], 27 | count = 0; 28 | 29 | if(subsetSelector) { 30 | actOn = that.filter(function() { 31 | return $(this).is(subsetSelector); 32 | }); 33 | } else { 34 | actOn = that; 35 | } 36 | 37 | actOn.each(function() { 38 | var $this = $(this); 39 | 40 | // Add the wrapper span 41 | var theText = $this.html(), 42 | $span = $this.html("" + theText + "").children("#checkSizeForSquishing"); 43 | 44 | // Figuring out the relevant widths 45 | var spanWidth = $span.width(), 46 | blockWidth = Math.max(parseFloat(settings.minWidth), 47 | Math.min($this.width(), 48 | parseFloat(settings.maxWidth)) 49 | ), 50 | fontSize = parseFloat($this.css("font-size")); 51 | 52 | // console.log("fontSize: " + fontSize + ", blockWidth: " + blockWidth + ", spanWidth: " + spanWidth); 53 | 54 | // Set the target size (restricted by min/max sizes) 55 | var targetSize = fontSize*blockWidth/spanWidth; 56 | 57 | targetSize = Math.floor(Math.min(Math.max(targetSize, parseFloat(settings.minSize)), parseFloat(settings.maxSize))); 58 | 59 | if(settings.equalizeSizes) { 60 | minFontSize = (targetSize < minFontSize) ? 61 | targetSize : minFontSize; 62 | } 63 | 64 | $this.css({"white-space": "nowrap", "font-size": targetSize, "text-align": "justify"}).html(theText); 65 | 66 | if(settings.callback) { 67 | finalFontSize.push(targetSize); 68 | count++; 69 | } 70 | }); 71 | 72 | if(settings.equalizeSizes) { 73 | actOn.each(function() { 74 | $(this).css("font-size", minFontSize); 75 | }); 76 | } 77 | 78 | if(settings.callback) { 79 | settings.callback(finalFontSize); 80 | } 81 | }; 82 | 83 | if(settings.runAutomatically) { 84 | // Initial will get it bigger but not too big 85 | $(document).ready(function() { 86 | resizer(); 87 | }); 88 | 89 | // Calls the resize on viewport width or orientation change 90 | $(window).on("resize.squishy orientationchange.squishy", resizer); 91 | } 92 | 93 | return { 94 | resize: function(selector) { 95 | return resizer(null, selector); 96 | }, 97 | 98 | makeAutomatic: function() { 99 | if(!settings.runAutomatically) { 100 | settings.runAutomatically = true; 101 | resizer(); 102 | $(window).on("resize.squishy orientationchange.squishy", resizer); 103 | } 104 | }, 105 | 106 | unSquish: function(keepFontSize) { 107 | settings.runAutomatically = false; 108 | $(window).off("resize.squishy orientationchange.squishy"); 109 | that.css({"white-space": "", "text-align": ""}); 110 | if(!keepFontSize) { that.css("font-size", ""); } 111 | }, 112 | 113 | set: function(setting, value) { 114 | settings[setting] = value; 115 | } 116 | }; 117 | }; 118 | 119 | })(jQuery); --------------------------------------------------------------------------------