├── .gitignore ├── LICENSE ├── README.md ├── bower.json ├── package.json ├── scss └── typographic.scss └── stylus ├── typographic.js └── typographic.styl /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io 2 | 3 | ### Sass ### 4 | .sass-cache 5 | *.css.map 6 | 7 | 8 | ### Node ### 9 | # Logs 10 | logs 11 | *.log 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | 24 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 25 | .grunt 26 | 27 | # node-waf configuration 28 | .lock-wscript 29 | 30 | # Compiled binary addons (http://nodejs.org/api/addons.html) 31 | build/Release 32 | 33 | # Dependency directory 34 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 35 | node_modules 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Cory Simmons 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 |

6 | 7 | 8 | 9 |

10 | 11 | Typographic is responsive typography made easy. Pick a few font stacks, set a few settings, and you've got **beautiful** responsive typography - it's that easy. 12 | 13 | 14 | ## Installation 15 | - `bower install typographic` 16 | - `@import` Typographic somewhere in your stylesheet 17 | 18 | 19 | ## Usage 20 | It's as easy as setting a few variables in a custom settings file (or letting the defaults do their thing) and then **calling the mixin** `typographic()` with no arguments. 21 | 22 | 23 | ## Settings 24 | ```stylus 25 | $line-height-ratio = 1.75 26 | $heading-ratio = $golden 27 | $body-font = $helvetica 28 | $body-font-weight = 300 29 | $body-color = #666 30 | $heading-font = $helvetica 31 | $heading-font-weight = 500 32 | $heading-color = #111 33 | $min-font = 13px 34 | $max-font = 20px 35 | $min-width = 600px 36 | $max-width = 1000px 37 | $vertical-rhythm = true 38 | ``` 39 | 40 | 41 | ## Ratios 42 | The ratios are based off of the ratios used on [modular scale](http://www.modularscale.com/). 43 | 44 | ```stylus 45 | $minor-second = 1.067 46 | $major-second = 1.125 47 | $minor-third = 1.2 48 | $major-third = 1.25 49 | $perfect-fourth = 1.333 50 | $aug-fourth = 1.414 51 | $perfect-fifth = 1.5 52 | $minor-sixth = 1.6 53 | $golden = 1.618 54 | $major-sixth = 1.667 55 | $minor-seventh = 1.778 56 | $major-seventh = 1.875 57 | $octave = 2 58 | $major-tenth = 2.5 59 | $major-eleventh = 2.667 60 | $major-twelfth = 3 61 | $double-octave = 4 62 | ``` 63 | 64 | 65 | ## Font Stacks 66 | Stacks are picked from A Way Back's [Revised Font Stack](http://www.awayback.com/revised-font-stack/). 67 | 68 | ```stylus 69 | // Sans-serif 70 | 71 | $calibri = 'Calibri', 'Candara', 'Segoe', 'Segoe UI', 'Optima', 'Arial', 'sans-serif' 72 | $candara = 'Candara', 'Calibri', 'Segoe', 'Segoe UI', 'Optima', 'Arial', 'sans-serif' 73 | $courier = 'Courier New', 'Courier', 'Lucida Sans Typewriter', 'Lucida Typewriter', 'monospace' 74 | $franklin = 'Franklin Gothic Medium', 'Arial', 'sans-serif' 75 | $futura = 'Futura', 'Trebuchet MS', 'Arial', 'sans-serif' 76 | $geneva = 'Geneva', 'Tahoma', 'Verdana', 'sans-serif' 77 | $gill-sans = 'Gill Sans', 'Gill Sans MT', 'Calibri', 'sans-serif' 78 | $helvetica = 'Helvetica Neue', 'Helvetica', 'Arial', 'sans-serif' 79 | $lucida-grande = 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', 'Geneva', 'Verdana', 'sans-serif' 80 | $optima = 'Optima', 'Segoe', 'Segoe UI', 'Candara', 'Calibri', 'Arial', 'sans-serif' 81 | $segoe = 'Segoe', 'Segoe UI', 'Helvetica Neue', 'Arial', 'sans-serif' 82 | $tahoma = 'Tahoma', 'Geneva', 'Verdana', 'sans-serif' 83 | $trebuchet = 'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', 'Tahoma', 'sans-serif' 84 | $verdana = 'Verdana', 'Geneva', 'sans-serif' 85 | 86 | 87 | // Serif 88 | 89 | $antiqua = 'Book Antiqua', 'Palatino', 'Palatino Linotype', 'Palatino LT STD', 'Georgia', 'serif' 90 | $baskerville = 'Baskerville', 'Baskerville old face', 'Hoefler Text', 'Garamond', 'Times New Roman', 'serif' 91 | $bodoni = 'Bodoni MT', 'Didot', 'Didot LT STD', 'Hoefler Text', 'Garamond', 'Times New Roman', 'serif' 92 | $cambria = 'Cambria', 'Georgia', 'serif' 93 | $caslon = 'Big Caslon', 'Book Antiqua', 'Palatino Linotype', 'Georgia', 'serif' 94 | $constantia = 'Constantia', 'Palatino', 'Palatino Linotype', 'Palatino LT STD', 'Georgia', 'serif' 95 | $didot = 'Didot', 'Didot LT STD', 'Hoefler Text', 'Garamond', 'Times New Roman', 'serif' 96 | $garamond = 'Garamond', 'Baskerville', 'Baskerville Old Face', 'Hoefler Text', 'Times New Roman', 'serif' 97 | $goudy = 'Goudy Old Style', 'Garamond', 'Big Caslon', 'Times New Roman', 'serif' 98 | $hoefler = 'Hoefler Text', 'Baskerville old face', 'Garamond', 'Times New Roman', 'serif' 99 | $lucida-bright = 'Lucida Bright', 'Georgia', 'serif' 100 | $palatino = 'Palatino', 'Palatino Linotype', 'Palatino LT STD', "Book Antiqua", 'Georgia', 'serif' 101 | ``` 102 | 103 | 104 | ## Helpers 105 | Typographic comes equipped with 2 extremely handy helpers. One for previewing your vertical rhythm grid, and another for sizing and spacing elements so they adhere to your vertical rhythm. 106 | 107 | The preview grid mixin is easy. It accepts a color and a positive or negative pixel offset parameter (for nudging your lines up to the bottom of text). 108 | 109 | ```stylus 110 | grid-overlay(blue, 2) 111 | ``` 112 | 113 | > **Note** `grid-overlay()` behaves somewhat funny in smaller viewports when `$min-font` is set to an odd number. This is due to a floating issue. Just something to keep in mind if your vertical rhythm looks haywire on smaller devices. Fear not, it's fine. 114 | 115 | The other helper is the `vr-block()` function, which returns sizes of your vertical rhythm. For instance, if you want to include an image that takes up `5.25` vertical units `height` and has a `margin-bottom` of `.25` vertical unit (as in [our demo](http://corysimmons.github.io/typographic/)), you could create it like this: 116 | 117 | ```stylus 118 | img 119 | height: vr-block(5.25) 120 | margin-bottom: vr-block(.25) 121 | ``` 122 | 123 | `vr-block()` accepts a second parameter for pixel offsetting to help nudge your elements back onto the vertical rhythm in case they are off by a pixel or two. 124 | 125 | 126 | ## Usage with Node 127 | ```javascript 128 | var fs = require('fs'), 129 | stylus = require('stylus'), 130 | typographic = require('typographic'); 131 | 132 | stylus(fs.readFileSync('./css/style.styl', 'utf8')) 133 | .use(typographic()) 134 | .render(function(err, css){ 135 | if (err) return console.error(err); 136 | console.log(css); 137 | }); 138 | ``` 139 | 140 | ```stylus 141 | @import 'typographic' 142 | 143 | $min-font: 14px 144 | 145 | typographic() 146 | ``` 147 | 148 | 149 | ## Browser Support 150 | - Full support for IE9+ 151 | - IE8 doesn't support [calc](http://caniuse.com/#feat=calc) or [viewport units](http://caniuse.com/#feat=viewport-units) or media queries by default so you shouldn't support it (you will get `$min-font` for all viewport sizes), but if you have a stingy client, you can include these polyfills to at least have it swap between the `$max-font` and `$min-font` at your specified breakpoint. 152 | - [respond.js](https://github.com/scottjehl/Respond) 153 | - [calc-polyfill](https://github.com/closingtag/calc-polyfill) 154 | - [vminpoly](https://github.com/saabi/vminpoly) 155 | 156 | 157 | ### Caveats 158 | - Slow in Sass because Sass doesn't support calculating decimals in exponents by default. Luckily you only have to change a few variables to get your compiled typography stylesheet then you can un-import Typographic. If lack of solid math in native Sass bothers you, please chime in on this [issue](https://github.com/sass/sass/issues/684). 159 | - Vertical rhythm doesn't really work with headings. It looks fine on `h1`, `h2`, and `h3`, but the `line-height` gets out of control on smaller headings. I've added a `$vertical-rhythm` setting to fall back to decent looking typography that isn't focused on vertical rhythm for just this case. 160 | 161 | 162 | ### Credits 163 | - [Mike Riethmuller](http://twitter.com/MikeRiethmuller) came up with the idea of using `calc` with `vw` to create scaling typography [here](http://madebymike.com.au/writing/precise-control-responsive-typography/). 164 | - [Scott Kellum](https://twitter.com/scottkellum) and [Tim Brown](https://twitter.com/timbrown) for [Modular Scale](http://www.modularscale.com/). 165 | - [David Khourshid](https://twitter.com/davidkpiano) for calculating [decimal exponents](https://gist.github.com/davidkpiano/ad6e6771df050ff3727f) in Sass. 166 | - [Petri Pottonen](https://twitter.com/petripottonen) for the `grid-overlay()` helper. 167 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typographic", 3 | "homepage": "https://github.com/corysimmons/typographic", 4 | "authors": [ 5 | "Cory Simmons " 6 | ], 7 | "description": "Responsive typography with modular scale, font stacks, and more.", 8 | "main": [ 9 | "scss/typographic.scss", 10 | "stylus/typographic.styl" 11 | ], 12 | "moduleType": [ 13 | "node" 14 | ], 15 | "keywords": [ 16 | "stylus", 17 | "css", 18 | "typography", 19 | "responsive" 20 | ], 21 | "license": "MIT", 22 | "ignore": [ 23 | "**/.*", 24 | "node_modules", 25 | "bower_components", 26 | "test", 27 | "tests", 28 | "demo" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typographic", 3 | "author": { 4 | "name": "Cory Simmons" 5 | }, 6 | "main": "stylus/typographic.js", 7 | "version": "3.0.0", 8 | "description": "Responsive typography with modular scale, font stacks, and more.", 9 | "keywords": [ 10 | "stylus", 11 | "css", 12 | "typography", 13 | "responsive" 14 | ], 15 | "categories": [ 16 | "css", 17 | "typography", 18 | "stylus" 19 | ], 20 | "github": "http://github.com/corysimmons/typographic", 21 | "repository": { 22 | "type": "git", 23 | "url": "https://github.com/corysimmons/typographic.git" 24 | }, 25 | "bugs": { 26 | "url": "https://github.com/corysimmons/typographic/issues" 27 | }, 28 | "readme": "https://github.com/corysimmons/typographic/blob/master/README.md", 29 | "homepage": "https://github.com/corysimmons/typographic" 30 | } 31 | -------------------------------------------------------------------------------- /scss/typographic.scss: -------------------------------------------------------------------------------- 1 | // Typographic v2.9.2 - https://github.com/corysimmons/typographic 2 | 3 | 4 | // Ratios 5 | 6 | $minor-second : 1.067; 7 | $major-second : 1.125; 8 | $minor-third : 1.2; 9 | $major-third : 1.25; 10 | $perfect-fourth : 1.333; 11 | $aug-fourth : 1.414; 12 | $perfect-fifth : 1.5; 13 | $minor-sixth : 1.6; 14 | $golden : 1.618; 15 | $major-sixth : 1.667; 16 | $minor-seventh : 1.778; 17 | $major-seventh : 1.875; 18 | $octave : 2; 19 | $major-tenth : 2.5; 20 | $major-eleventh : 2.667; 21 | $major-twelfth : 3; 22 | $double-octave : 4; 23 | 24 | 25 | // Sans-serif 26 | 27 | $calibri : 'Calibri', 'Candara', 'Segoe', 'Segoe UI', 'Optima', 'Arial', 'sans-serif'; 28 | $candara : 'Candara', 'Calibri', 'Segoe', 'Segoe UI', 'Optima', 'Arial', 'sans-serif'; 29 | $courier : 'Courier New', 'Courier', 'Lucida Sans Typewriter', 'Lucida Typewriter', 'monospace'; 30 | $franklin : 'Franklin Gothic Medium', 'Arial', 'sans-serif'; 31 | $futura : 'Futura', 'Trebuchet MS', 'Arial', 'sans-serif'; 32 | $geneva : 'Geneva', 'Tahoma', 'Verdana', 'sans-serif'; 33 | $gill-sans : 'Gill Sans', 'Gill Sans MT', 'Calibri', 'sans-serif'; 34 | $helvetica : 'Helvetica Neue', 'Helvetica', 'Arial', 'sans-serif'; 35 | $lucida-grande : 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', 'Geneva', 'Verdana', 'sans-serif'; 36 | $optima : 'Optima', 'Segoe', 'Segoe UI', 'Candara', 'Calibri', 'Arial', 'sans-serif'; 37 | $segoe : 'Segoe', 'Segoe UI', 'Helvetica Neue', 'Arial', 'sans-serif'; 38 | $tahoma : 'Tahoma', 'Geneva', 'Verdana', 'sans-serif'; 39 | $trebuchet : 'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', 'Tahoma', 'sans-serif'; 40 | $verdana : 'Verdana', 'Geneva', 'sans-serif'; 41 | 42 | 43 | // Serif 44 | 45 | $antiqua : 'Book Antiqua', 'Palatino', 'Palatino Linotype', 'Palatino LT STD', 'Georgia', 'serif'; 46 | $baskerville : 'Baskerville', 'Baskerville old face', 'Hoefler Text', 'Garamond', 'Times New Roman', 'serif'; 47 | $bodoni : 'Bodoni MT', 'Didot', 'Didot LT STD', 'Hoefler Text', 'Garamond', 'Times New Roman', 'serif'; 48 | $cambria : 'Cambria', 'Georgia', 'serif'; 49 | $caslon : 'Big Caslon', 'Book Antiqua', 'Palatino Linotype', 'Georgia', 'serif'; 50 | $constantia : 'Constantia', 'Palatino', 'Palatino Linotype', 'Palatino LT STD', 'Georgia', 'serif'; 51 | $didot : 'Didot', 'Didot LT STD', 'Hoefler Text', 'Garamond', 'Times New Roman', 'serif'; 52 | $garamond : 'Garamond', 'Baskerville', 'Baskerville Old Face', 'Hoefler Text', 'Times New Roman', 'serif'; 53 | $goudy : 'Goudy Old Style', 'Garamond', 'Big Caslon', 'Times New Roman', 'serif'; 54 | $hoefler : 'Hoefler Text', 'Baskerville old face', 'Garamond', 'Times New Roman', 'serif'; 55 | $lucida-bright : 'Lucida Bright', 'Georgia', 'serif'; 56 | $palatino : 'Palatino', 'Palatino Linotype', 'Palatino LT STD', "Book Antiqua", 'Georgia', 'serif'; 57 | 58 | 59 | // Settings 60 | 61 | $line-height-ratio : 1.75 !default; 62 | $heading-ratio : $golden !default; 63 | $body-font : $helvetica !default; 64 | $body-font-weight : 300 !default; 65 | $body-color : #666 !default; 66 | $heading-font : $helvetica !default; 67 | $heading-font-weight : 500 !default; 68 | $heading-color : #111 !default; 69 | $min-font : 12px !default; 70 | $max-font : 20px !default; 71 | $min-width : 600px !default; 72 | $max-width : 1140px !default; 73 | $vertical-rhythm : true !default; 74 | 75 | 76 | // Helpers 77 | 78 | /// A function to remove the unit from a number. 79 | /// 80 | /// @param {unit} $unit - A unit with a unit value. 81 | /// 82 | /// @example 83 | /// _strip-units(1px) 84 | /// 85 | /// @access private 86 | 87 | @function _strip-units($unit) { 88 | @return $unit / ($unit * 0 + 1); 89 | } 90 | 91 | 92 | /// Creates a baseline grid based off your $line-height-ratio to help visualize your vertical rhythm grid. You can offset the grid by negative or positive pixels to line it up perfectly with the bottom of your text. 93 | /// 94 | /// @param {color} $color [black] - A color to be lightened and used as the color for the grid. 95 | /// @param {number} $px-offset [false] - A positive or negative number of pixels to offset the grid by. Useful for lining the bottom of the gridlines up with your text. 96 | /// 97 | /// @example 98 | /// @include grid-overlay(blue, 2); 99 | 100 | @mixin grid-overlay($color: black, $px-offset: false) { 101 | body { 102 | background: linear-gradient(to top, rgba($color, .1) 5%, white 5%); 103 | background-size: 100% ($line-height-ratio) + em; 104 | @if($px-offset) { 105 | background-position: 0 $px-offset + px; 106 | } 107 | } 108 | } 109 | 110 | 111 | /// Returns a "vertical unit". Useful for specifying the height and margins of non-text elements like images and such. 112 | /// 113 | /// @param {number} $units [1] - Number of units. Accepts floated numbers as well. 114 | /// @param {number} $px-offset [false] - A positive or negative number of pixels to offset the grid by. Useful for lining the bottom of the gridlines up with your text. Since this doesn't compute a literal pixel you may need to use a floated number (multiples of .25 work well) to keep your rhythm on track. 115 | /// 116 | /// @example 117 | /// img { 118 | /// height: vr-block(5.25); 119 | /// margin-bottom: vr-block(.25); 120 | /// } 121 | 122 | @function vr-block($units: 1, $px-offset: false) { 123 | @if($px-offset) { 124 | @return ( (($line-height-ratio * _strip-units($max-font)) / (_strip-units($max-font) / 2)) * ($units / 2) * (1 + ($px-offset / _strip-units($max-font))) ) + em; 125 | } @else { 126 | @return ( (($line-height-ratio * _strip-units($max-font)) / (_strip-units($max-font) / 2)) * ($units / 2) ) + em; 127 | } 128 | } 129 | 130 | 131 | /// Performs exponent math on floated numbers. 132 | /// 133 | /// @example 134 | /// math-pow(3, 3) 135 | /// 136 | /// @access private 137 | 138 | @function math-pow($number, $exp) { 139 | @if (round($exp) != $exp) { 140 | @return math-exp($exp * math-ln($number)); 141 | } 142 | 143 | $value: 1; 144 | 145 | @if $exp > 0 { 146 | @for $i from 1 through $exp { 147 | $value: $value * $number; 148 | } 149 | } 150 | @else if $exp < 0 { 151 | @for $i from 1 through -$exp { 152 | $value: $value / $number; 153 | } 154 | } 155 | 156 | @return $value; 157 | } 158 | 159 | 160 | /// Helps with math-pow() function 161 | /// 162 | /// @access private 163 | 164 | @function math-factorial($value) { 165 | @if $value == 0 { 166 | @return 1; 167 | } 168 | 169 | $result: 1; 170 | 171 | @for $index from 1 through $value { 172 | $result: $result * $index; 173 | } 174 | 175 | @return $result; 176 | } 177 | 178 | 179 | /// Helps with math-pow() function 180 | /// 181 | /// @access private 182 | 183 | @function math-summation($iteratee, $input, $initial: 0, $limit: 100) { 184 | $sum: 0; 185 | 186 | @for $index from $initial to $limit { 187 | $sum: $sum + call($iteratee, $input, $index); 188 | } 189 | 190 | @return $sum; 191 | } 192 | 193 | 194 | /// Helps with math-pow() function 195 | /// 196 | /// @access private 197 | 198 | @function math-exp-maclaurin($x, $n) { 199 | $result: math-pow($x, $n) / math-factorial($n); 200 | @return $result; 201 | } 202 | 203 | 204 | /// Helps with math-pow() function 205 | /// 206 | /// @access private 207 | 208 | @function math-exp($value) { 209 | $result: math-summation(math-exp-maclaurin, $value, 0, 100); 210 | @return $result; 211 | } 212 | 213 | 214 | /// Helps with math-pow() function 215 | /// 216 | /// @access private 217 | 218 | @function math-ln-maclaurin($x, $n) { 219 | $result: (math-pow(-1, $n + 1) / $n) * (math-pow($x - 1, $n)); 220 | @return $result; 221 | } 222 | 223 | 224 | /// Helps with math-pow() function 225 | /// 226 | /// @access private 227 | 228 | @function math-ln($value) { 229 | $ten-exp: 1; 230 | $ln-ten: 2.30258509; 231 | 232 | @while ($value > math-pow(10, $ten-exp)) { 233 | $ten-exp: $ten-exp + 1; 234 | } 235 | 236 | $value: $value / math-pow(10, $ten-exp); 237 | 238 | $result: math-summation(math-ln-maclaurin, $value, 1, 100); 239 | 240 | @return $result + $ten-exp * $ln-ten; 241 | } 242 | 243 | 244 | // Typography Mixins 245 | 246 | @mixin t-html() { 247 | font-family: $body-font; 248 | font-weight: $body-font-weight; 249 | color: $body-color; 250 | 251 | font-size: $min-font; 252 | line-height: #{$line-height-ratio}em; 253 | 254 | @media (min-width: $min-width) { 255 | font-size: calc( #{$min-font} + (#{_strip-units($max-font)} - #{_strip-units($min-font)}) * ((100vw - #{$min-width}) / (#{_strip-units($max-width)} - #{_strip-units($min-width)})) ); 256 | } 257 | 258 | @media (min-width: $max-width) { 259 | font-size: $max-font; 260 | } 261 | } 262 | 263 | @mixin t-p() { 264 | @include t-html; 265 | } 266 | 267 | @mixin t-reset() { 268 | margin: 0; 269 | padding: 0; 270 | } 271 | 272 | @mixin t-block() { 273 | margin-bottom: #{$line-height-ratio}em; 274 | } 275 | 276 | @mixin t-heading() { 277 | font-family: $heading-font; 278 | font-weight: $heading-font-weight; 279 | color: $heading-color; 280 | clear: both; 281 | } 282 | 283 | @mixin t-h1() { 284 | $local-min-font: $min-font * (math-pow($heading-ratio, 1.75)); 285 | $local-max-font: $max-font * (math-pow($heading-ratio, 1.75)); 286 | 287 | font-size: $local-min-font; 288 | @if ($vertical-rhythm) { 289 | margin-top: (($line-height-ratio * $min-font) / ($local-min-font / 1.25)) + em; 290 | line-height: (($line-height-ratio * $min-font) / ($local-min-font / 1.5)) + em; 291 | margin-bottom: (($line-height-ratio * $min-font) / ($local-min-font / .25)) + em; 292 | } @else { 293 | margin-top: 0; 294 | line-height: 1.1em; 295 | margin-bottom: .25em; 296 | } 297 | 298 | @media (min-width: $min-width) { 299 | font-size: calc( #{$local-min-font} + (#{_strip-units($local-max-font)} - #{_strip-units($local-min-font)}) * ((100vw - #{$min-width}) / (#{_strip-units($max-width)} - #{_strip-units($min-width)})) ); 300 | } 301 | 302 | @media (min-width: $max-width) { 303 | font-size: $local-max-font; 304 | @if ($vertical-rhythm) { 305 | margin-top: (($line-height-ratio * $max-font) / ($local-max-font / 1.25)) + em; 306 | line-height: (($line-height-ratio * $max-font) / ($local-max-font / 1.5)) + em; 307 | margin-bottom: (($line-height-ratio * $max-font) / ($local-max-font / .25)) + em; 308 | } 309 | } 310 | } 311 | 312 | @mixin t-h2() { 313 | $local-min-font: $min-font * (math-pow($heading-ratio, 1.4)); 314 | $local-max-font: $max-font * (math-pow($heading-ratio, 1.4)); 315 | 316 | font-size: $local-min-font; 317 | @if ($vertical-rhythm) { 318 | margin-top: (($line-height-ratio * $min-font) / ($local-min-font / 1.25)) + em; 319 | line-height: (($line-height-ratio * $min-font) / ($local-min-font / 1.5)) + em; 320 | margin-bottom: (($line-height-ratio * _strip-units($min-font)) / (_strip-units($local-min-font) / .25) * (1 + (3 / _strip-units($local-min-font)))) + em; 321 | } @else { 322 | margin-top: 0; 323 | line-height: 1.2em; 324 | margin-bottom: .25em; 325 | } 326 | 327 | @media (min-width: $min-width) { 328 | font-size: calc( #{$local-min-font} + (#{_strip-units($local-max-font)} - #{_strip-units($local-min-font)}) * ((100vw - #{$min-width}) / (#{_strip-units($max-width)} - #{_strip-units($min-width)})) ); 329 | } 330 | 331 | @media (min-width: $max-width) { 332 | font-size: $local-max-font; 333 | @if ($vertical-rhythm) { 334 | margin-top: (($line-height-ratio * $max-font) / ($local-max-font / 1.25)) + em; 335 | line-height: (($line-height-ratio * $max-font) / ($local-max-font / 1.5)) + em; 336 | margin-bottom: (($line-height-ratio * _strip-units($max-font)) / (_strip-units($local-max-font) / .25) * (1 + (3 / _strip-units($local-max-font)))) + em; 337 | } 338 | } 339 | } 340 | 341 | @mixin t-h3() { 342 | $local-min-font: $min-font * (math-pow($heading-ratio, 1.05)); 343 | $local-max-font: $max-font * (math-pow($heading-ratio, 1.05)); 344 | 345 | font-size: $local-min-font; 346 | @if ($vertical-rhythm) { 347 | margin-top: (($line-height-ratio * $min-font) / ($local-min-font / 1.25)) + em; 348 | line-height: (($line-height-ratio * $min-font) / ($local-min-font / 1.5)) + em; 349 | margin-bottom: (($line-height-ratio * _strip-units($min-font)) / (_strip-units($local-min-font) / .25) * (1 + (3 / _strip-units($local-min-font)))) + em; 350 | } @else { 351 | margin-top: 0; 352 | line-height: 1.3em; 353 | margin-bottom: .25em; 354 | } 355 | 356 | @media (min-width: $min-width) { 357 | font-size: calc( #{$local-min-font} + (#{_strip-units($local-max-font)} - #{_strip-units($local-min-font)}) * ((100vw - #{$min-width}) / (#{_strip-units($max-width)} - #{_strip-units($min-width)})) ); 358 | } 359 | 360 | @media (min-width: $max-width) { 361 | font-size: $local-max-font; 362 | @if ($vertical-rhythm) { 363 | margin-top: (($line-height-ratio * $max-font) / ($local-max-font / 1.25)) + em; 364 | line-height: (($line-height-ratio * $max-font) / ($local-max-font / 1.5)) + em; 365 | margin-bottom: (($line-height-ratio * _strip-units($max-font)) / (_strip-units($local-max-font) / .25) * (1 + (3 / _strip-units($local-max-font)))) + em; 366 | } 367 | } 368 | } 369 | 370 | @mixin t-h4() { 371 | $local-min-font: $min-font * (math-pow($heading-ratio, .7)); 372 | $local-max-font: $max-font * (math-pow($heading-ratio, .7)); 373 | 374 | font-size: $local-min-font; 375 | @if ($vertical-rhythm) { 376 | margin-top: (($line-height-ratio * $min-font) / ($local-min-font / 1.25)) + em; 377 | line-height: (($line-height-ratio * $min-font) / ($local-min-font / 1.5)) + em; 378 | margin-bottom: (($line-height-ratio * _strip-units($min-font)) / (_strip-units($local-min-font) / .25) * (1 + (3 / _strip-units($local-min-font)))) + em; 379 | } @else { 380 | margin-top: 0; 381 | line-height: 1.4em; 382 | margin-bottom: .25em; 383 | } 384 | 385 | @media (min-width: $min-width) { 386 | font-size: calc( #{$local-min-font} + (#{_strip-units($local-max-font)} - #{_strip-units($local-min-font)}) * ((100vw - #{$min-width}) / (#{_strip-units($max-width)} - #{_strip-units($min-width)})) ); 387 | } 388 | 389 | @media (min-width: $max-width) { 390 | font-size: $local-max-font; 391 | @if ($vertical-rhythm) { 392 | margin-top: (($line-height-ratio * $max-font) / ($local-max-font / 1.25)) + em; 393 | line-height: (($line-height-ratio * $max-font) / ($local-max-font / 1.5)) + em; 394 | margin-bottom: (($line-height-ratio * _strip-units($max-font)) / (_strip-units($local-max-font) / .25) * (1 + (3 / _strip-units($local-max-font)))) + em; 395 | } 396 | } 397 | } 398 | 399 | @mixin t-h5() { 400 | $local-min-font: $min-font * (math-pow($heading-ratio, .35)); 401 | $local-max-font: $max-font * (math-pow($heading-ratio, .35)); 402 | 403 | font-size: $local-min-font; 404 | @if ($vertical-rhythm) { 405 | margin-top: (($line-height-ratio * $min-font) / ($local-min-font / 1.25)) + em; 406 | line-height: (($line-height-ratio * $min-font) / ($local-min-font / 1.5)) + em; 407 | margin-bottom: (($line-height-ratio * $min-font) / ($local-min-font / .25)) + em; 408 | } @else { 409 | margin-top: 0; 410 | line-height: 1.5em; 411 | margin-bottom: .25em; 412 | } 413 | 414 | @media (min-width: $min-width) { 415 | font-size: calc( #{$local-min-font} + (#{_strip-units($local-max-font)} - #{_strip-units($local-min-font)}) * ((100vw - #{$min-width}) / (#{_strip-units($max-width)} - #{_strip-units($min-width)})) ); 416 | } 417 | 418 | @media (min-width: $max-width) { 419 | font-size: $local-max-font; 420 | @if ($vertical-rhythm) { 421 | margin-top: (($line-height-ratio * $max-font) / ($local-max-font / 1.25)) + em; 422 | line-height: (($line-height-ratio * $max-font) / ($local-max-font / 1.5)) + em; 423 | margin-bottom: (($line-height-ratio * $max-font) / ($local-max-font / .25)) + em; 424 | } 425 | } 426 | } 427 | 428 | @mixin t-h6() { 429 | $local-min-font: $min-font; 430 | $local-max-font: $max-font; 431 | 432 | font-size: $local-min-font; 433 | @if ($vertical-rhythm) { 434 | margin-top: (($line-height-ratio * $min-font) / ($local-min-font / 1.25)) + em; 435 | line-height: (($line-height-ratio * $min-font) / ($local-min-font / 1.5)) + em; 436 | margin-bottom: (($line-height-ratio * _strip-units($min-font)) / (_strip-units($local-min-font) / .25) * (1 + (2 / _strip-units($local-min-font)))) + em; 437 | } @else { 438 | margin-top: 0; 439 | line-height: 1.6em; 440 | margin-bottom: .25em; 441 | } 442 | 443 | @media (min-width: $min-width) { 444 | font-size: calc( #{$local-min-font} + (#{_strip-units($local-max-font)} - #{_strip-units($local-min-font)}) * ((100vw - #{$min-width}) / (#{_strip-units($max-width)} - #{_strip-units($min-width)})) ); 445 | } 446 | 447 | @media (min-width: $max-width) { 448 | font-size: $local-max-font; 449 | @if ($vertical-rhythm) { 450 | margin-top: (($line-height-ratio * $min-font) / ($local-min-font / 1.25)) + em; 451 | line-height: (($line-height-ratio * $min-font) / ($local-min-font / 1.5)) + em; 452 | margin-bottom: (($line-height-ratio * _strip-units($min-font)) / (_strip-units($local-min-font) / .25) * (1 + (1 / _strip-units($local-min-font)))) + em; 453 | } 454 | } 455 | } 456 | 457 | @mixin t-blockquote() { 458 | font-style: italic; 459 | cite { 460 | display: block; 461 | font-style: normal; 462 | } 463 | } 464 | 465 | @mixin t-pre() { 466 | padding: ($line-height-ratio * .5) + em; 467 | margin-bottom: vr-block(1); 468 | code { 469 | padding: 0; 470 | } 471 | } 472 | 473 | @mixin t-code() { 474 | font-family: $courier; 475 | padding: ($line-height-ratio * .05) + em ($line-height-ratio * .15) + em; 476 | line-height: 0; 477 | } 478 | 479 | @mixin t-abbr() { 480 | border-bottom: 1px dotted currentColor; 481 | cursor: help; 482 | } 483 | 484 | @mixin t-dt() { 485 | color: $heading-color; 486 | font-weight: bold; 487 | } 488 | 489 | @mixin t-fieldset() { 490 | padding: vr-block(.5) vr-block() vr-block(); 491 | border-width: 1px; 492 | border-style: solid; 493 | max-width: 100%; 494 | margin-bottom: vr-block(1, 1); 495 | @media (min-width: $max-width) { 496 | margin-bottom: vr-block(1.25, -1); 497 | } 498 | button, input[type="submit"] { 499 | margin-bottom: 0; 500 | } 501 | } 502 | 503 | @mixin t-legend() { 504 | color: $heading-color; 505 | font-weight: bold; 506 | } 507 | 508 | @mixin t-input() { 509 | $local-min-font: $min-font; 510 | $local-max-font: $max-font; 511 | 512 | display: block; 513 | max-width: 100%; 514 | padding: vr-block(.25); 515 | 516 | font-size: $local-min-font; 517 | margin-bottom: vr-block(.5, 7); 518 | 519 | @media (min-width: $min-width) { 520 | font-size: calc( #{$local-min-font} + (#{_strip-units($local-max-font)} - #{_strip-units($local-min-font)}) * ((100vw - #{$min-width}) / (#{_strip-units($max-width)} - #{_strip-units($min-width)})) ); 521 | } 522 | 523 | @media (min-width: $max-width) { 524 | font-size: $local-max-font; 525 | margin-bottom: vr-block(.25, 3.5); 526 | } 527 | } 528 | 529 | @mixin t-button() { 530 | $local-min-font: $min-font; 531 | $local-max-font: $max-font; 532 | 533 | display: block; 534 | cursor: pointer; 535 | 536 | font-size: $local-min-font; 537 | padding: vr-block(.25) vr-block(); 538 | margin-bottom: vr-block(.75, -2); 539 | 540 | @media (min-width: $min-width) { 541 | font-size: calc( #{$local-min-font} + (#{_strip-units($local-max-font)} - #{_strip-units($local-min-font)}) * ((100vw - #{$min-width}) / (#{_strip-units($max-width)} - #{_strip-units($min-width)})) ); 542 | } 543 | 544 | @media (min-width: $max-width) { 545 | font-size: $local-max-font; 546 | margin-bottom: vr-block(.75); 547 | } 548 | } 549 | 550 | @mixin t-label() { 551 | display: block; 552 | padding-bottom: vr-block(.125); 553 | margin-bottom: vr-block(-.25, -10); 554 | } 555 | 556 | @mixin t-table() { 557 | width: 100%; 558 | border-spacing: 0; 559 | border-collapse: collapse; 560 | margin-bottom: vr-block(1, 5); 561 | @media (min-width: $max-width) { 562 | margin-bottom: vr-block(1, 3); 563 | } 564 | } 565 | 566 | @mixin t-th() { 567 | text-align: left; 568 | color: $heading-color; 569 | 570 | padding: vr-block(.125) vr-block(.5); 571 | 572 | @media (min-width: $max-width) { 573 | padding: vr-block(.25) vr-block(.5); 574 | } 575 | } 576 | 577 | @mixin t-td() { 578 | padding: ($line-height-ratio * .5) + em; 579 | padding: vr-block(.125) vr-block(.5); 580 | 581 | @media (min-width: $max-width) { 582 | padding: vr-block(.25) vr-block(.5); 583 | } 584 | } 585 | 586 | 587 | /// The Typographic Reset. This is where Typographic goes through every markup element and styles it to adhere to a vertical rhythm. After you set your variables in a settings file fire this mixin. 588 | /// 589 | /// @example 590 | /// @include typographic; 591 | 592 | @mixin typographic() { 593 | 594 | html { 595 | @include t-html; 596 | } 597 | 598 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 599 | a, abbr, acronym, address, big, cite, code, 600 | del, dfn, em, img, ins, kbd, q, s, samp, 601 | small, strike, strong, sub, sup, tt, var, 602 | b, u, i, center, 603 | dl, dt, dd, ol, ul, li, 604 | fieldset, form, label, legend, 605 | table, caption, tbody, tfoot, thead, tr, th, td { 606 | @include t-reset; 607 | } 608 | 609 | p, blockquote, pre, 610 | address, 611 | dl, ol, ul, 612 | table { 613 | @include t-block; 614 | } 615 | 616 | h1, h2, h3, h4, h5, h6 { 617 | @include t-heading; 618 | } 619 | 620 | h1 { 621 | @include t-h1; 622 | } 623 | 624 | h2 { 625 | @include t-h2; 626 | } 627 | 628 | h3 { 629 | @include t-h3; 630 | } 631 | 632 | h4 { 633 | @include t-h4; 634 | } 635 | 636 | h5 { 637 | @include t-h5; 638 | } 639 | 640 | h6 { 641 | @include t-h6; 642 | } 643 | 644 | blockquote { 645 | @include t-blockquote; 646 | } 647 | 648 | pre { 649 | @include t-pre; 650 | } 651 | 652 | code { 653 | @include t-code; 654 | } 655 | 656 | big, small, sub, sup { 657 | line-height: 0; 658 | } 659 | 660 | abbr, acronym { 661 | @include t-abbr; 662 | } 663 | 664 | address { 665 | font-style: normal; 666 | } 667 | 668 | dt { 669 | @include t-dt; 670 | } 671 | 672 | ul { 673 | padding-left: 1.1em; 674 | } 675 | 676 | ol { 677 | padding-left: 1.4em; 678 | } 679 | 680 | fieldset { 681 | @include t-fieldset; 682 | } 683 | 684 | legend { 685 | @include t-legend; 686 | } 687 | 688 | input[type="text"], input[type="email"], input[type="password"], textarea { 689 | @include t-input; 690 | } 691 | 692 | input[type="submit"], button { 693 | @include t-button; 694 | } 695 | 696 | label { 697 | @include t-label; 698 | } 699 | 700 | table { 701 | @include t-table; 702 | } 703 | 704 | th { 705 | @include t-th; 706 | } 707 | 708 | td { 709 | @include t-td; 710 | } 711 | 712 | } 713 | -------------------------------------------------------------------------------- /stylus/typographic.js: -------------------------------------------------------------------------------- 1 | module.exports = function(opts) { 2 | return function(style) { 3 | style.include(__dirname); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /stylus/typographic.styl: -------------------------------------------------------------------------------- 1 | // Typographic v2.9.2 - https://github.com/corysimmons/typographic 2 | 3 | 4 | // Settings 5 | 6 | $line-height-ratio = 1.75 7 | $heading-ratio = $golden 8 | $body-font = $helvetica 9 | $body-font-weight = 300 10 | $body-color = #666 11 | $heading-font = $helvetica 12 | $heading-font-weight = 500 13 | $heading-color = #111 14 | $min-font = 12px 15 | $max-font = 20px 16 | $min-width = 600px 17 | $max-width = 1140px 18 | $vertical-rhythm = true 19 | 20 | 21 | // Ratios 22 | 23 | $minor-second = 1.067 24 | $major-second = 1.125 25 | $minor-third = 1.2 26 | $major-third = 1.25 27 | $perfect-fourth = 1.333 28 | $aug-fourth = 1.414 29 | $perfect-fifth = 1.5 30 | $minor-sixth = 1.6 31 | $golden = 1.618 32 | $major-sixth = 1.667 33 | $minor-seventh = 1.778 34 | $major-seventh = 1.875 35 | $octave = 2 36 | $major-tenth = 2.5 37 | $major-eleventh = 2.667 38 | $major-twelfth = 3 39 | $double-octave = 4 40 | 41 | 42 | // Sans-serif 43 | 44 | $calibri = 'Calibri', 'Candara', 'Segoe', 'Segoe UI', 'Optima', 'Arial', 'sans-serif' 45 | $candara = 'Candara', 'Calibri', 'Segoe', 'Segoe UI', 'Optima', 'Arial', 'sans-serif' 46 | $courier = 'Courier New', 'Courier', 'Lucida Sans Typewriter', 'Lucida Typewriter', 'monospace' 47 | $franklin = 'Franklin Gothic Medium', 'Arial', 'sans-serif' 48 | $futura = 'Futura', 'Trebuchet MS', 'Arial', 'sans-serif' 49 | $geneva = 'Geneva', 'Tahoma', 'Verdana', 'sans-serif' 50 | $gill-sans = 'Gill Sans', 'Gill Sans MT', 'Calibri', 'sans-serif' 51 | $helvetica = 'Helvetica Neue', 'Helvetica', 'Arial', 'sans-serif' 52 | $lucida-grande = 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', 'Geneva', 'Verdana', 'sans-serif' 53 | $optima = 'Optima', 'Segoe', 'Segoe UI', 'Candara', 'Calibri', 'Arial', 'sans-serif' 54 | $segoe = 'Segoe', 'Segoe UI', 'Helvetica Neue', 'Arial', 'sans-serif' 55 | $tahoma = 'Tahoma', 'Geneva', 'Verdana', 'sans-serif' 56 | $trebuchet = 'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', 'Tahoma', 'sans-serif' 57 | $verdana = 'Verdana', 'Geneva', 'sans-serif' 58 | 59 | 60 | // Serif 61 | 62 | $antiqua = 'Book Antiqua', 'Palatino', 'Palatino Linotype', 'Palatino LT STD', 'Georgia', 'serif' 63 | $baskerville = 'Baskerville', 'Baskerville old face', 'Hoefler Text', 'Garamond', 'Times New Roman', 'serif' 64 | $bodoni = 'Bodoni MT', 'Didot', 'Didot LT STD', 'Hoefler Text', 'Garamond', 'Times New Roman', 'serif' 65 | $cambria = 'Cambria', 'Georgia', 'serif' 66 | $caslon = 'Big Caslon', 'Book Antiqua', 'Palatino Linotype', 'Georgia', 'serif' 67 | $constantia = 'Constantia', 'Palatino', 'Palatino Linotype', 'Palatino LT STD', 'Georgia', 'serif' 68 | $didot = 'Didot', 'Didot LT STD', 'Hoefler Text', 'Garamond', 'Times New Roman', 'serif' 69 | $garamond = 'Garamond', 'Baskerville', 'Baskerville Old Face', 'Hoefler Text', 'Times New Roman', 'serif' 70 | $goudy = 'Goudy Old Style', 'Garamond', 'Big Caslon', 'Times New Roman', 'serif' 71 | $hoefler = 'Hoefler Text', 'Baskerville old face', 'Garamond', 'Times New Roman', 'serif' 72 | $lucida-bright = 'Lucida Bright', 'Georgia', 'serif' 73 | $palatino = 'Palatino', 'Palatino Linotype', 'Palatino LT STD', "Book Antiqua", 'Georgia', 'serif' 74 | 75 | 76 | // Helpers 77 | 78 | /** 79 | * Creates a baseline grid based off your $line-height-ratio to help visualize your vertical rhythm grid. You can offset the grid by negative or positive pixels to line it up perfectly with the bottom of your text. 80 | * 81 | * @param {color} [$color=black] - A color to be lightened and used as the color for the grid. 82 | * @param {number} [$px-offset=false] - A positive or negative number of pixels to offset the grid by. Useful for lining the bottom of the gridlines up with your text. 83 | * 84 | * @example 85 | * grid-overlay(blue, 2) 86 | */ 87 | 88 | grid-overlay($color = black, $px-offset = false) 89 | body 90 | background: linear-gradient(to top, rgba($color, 10%) 5%, white 5%) 91 | background-size: 100% ($line-height-ratio)em 92 | if $px-offset 93 | background-position: 0 unit($px-offset, 'px') 94 | 95 | 96 | /** 97 | * Returns a "vertical unit". Useful for specifying the height and margins of non-text elements like images and such. 98 | * 99 | * @param {number} [$units=1] - Number of units. Accepts floated numbers as well. 100 | * @param {number} [$px-offset=false] - A positive or negative number of pixels to offset the grid by. Useful for lining the bottom of the gridlines up with your text. Since this doesn't compute a literal pixel you may need to use a floated number (multiples of .25 work well) to keep your rhythm on track. 101 | * 102 | * @example 103 | * img 104 | * padding-top vr-block(5.25, .5) 105 | */ 106 | 107 | vr-block($units = 1, $px-offset = false) 108 | if $px-offset 109 | return ( (($line-height-ratio * $max-font) / ($max-font / 2)) * ($units / 2) * (1 + ($px-offset / $max-font)) )em 110 | else 111 | return ( (($line-height-ratio * $max-font) / ($max-font / 2)) * ($units / 2) )em 112 | 113 | 114 | // Typography Mixins 115 | 116 | t-html() 117 | font-family: $body-font 118 | font-weight: $body-font-weight 119 | color: $body-color 120 | 121 | font-size: $min-font 122 | line-height: ($line-height-ratio)em 123 | 124 | @media (min-width: $min-width) 125 | font-size: s('calc( %s + (%s - %s) * ((100vw - %s) / (%s - %s)) )', $min-font, remove-unit($max-font), remove-unit($min-font), $min-width, remove-unit($max-width), remove-unit($min-width)) 126 | 127 | @media (min-width: $max-width) 128 | font-size: $max-font 129 | 130 | t-p = t-html 131 | 132 | t-reset() 133 | margin: 0 134 | padding: 0 135 | 136 | t-block() 137 | margin-bottom: ($line-height-ratio)em 138 | 139 | t-heading() 140 | font-family: $heading-font 141 | font-weight: $heading-font-weight 142 | color: $heading-color 143 | clear: both 144 | 145 | t-h1() 146 | $local-min-font = $min-font * ($heading-ratio ** 1.75) 147 | $local-max-font = $max-font * ($heading-ratio ** 1.75) 148 | 149 | font-size: $local-min-font 150 | if $vertical-rhythm is true 151 | margin-top: (($line-height-ratio * $min-font) / ($local-min-font / 1.25))em 152 | line-height: (($line-height-ratio * $min-font) / ($local-min-font / 1.5))em 153 | margin-bottom: (($line-height-ratio * $min-font) / ($local-min-font / .25))em 154 | else 155 | margin-top: 0 156 | line-height: 1.1em 157 | margin-bottom: .25em 158 | 159 | @media (min-width: $min-width) 160 | font-size: s('calc( %s + (%s - %s) * ((100vw - %s) / (%s - %s)) )', $local-min-font, remove-unit($local-max-font), remove-unit($local-min-font), $min-width, remove-unit($max-width), remove-unit($min-width)) 161 | 162 | @media (min-width: $max-width) 163 | font-size: $local-max-font 164 | if $vertical-rhythm is true 165 | margin-top: (($line-height-ratio * $max-font) / ($local-max-font / 1.25))em 166 | line-height: (($line-height-ratio * $max-font) / ($local-max-font / 1.5))em 167 | margin-bottom: (($line-height-ratio * $max-font) / ($local-max-font / .25))em 168 | 169 | t-h2() 170 | $local-min-font = $min-font * ($heading-ratio ** 1.4) 171 | $local-max-font = $max-font * ($heading-ratio ** 1.4) 172 | 173 | font-size: $local-min-font 174 | if $vertical-rhythm is true 175 | margin-top: (($line-height-ratio * $min-font) / ($local-min-font / 1.25))em 176 | line-height: (($line-height-ratio * $min-font) / ($local-min-font / 1.5))em 177 | margin-bottom: (($line-height-ratio * $min-font) / ($local-min-font / .25) * (1 + (3 / $local-min-font)))em 178 | else 179 | margin-top: 0 180 | line-height: 1.2em 181 | margin-bottom: .25em 182 | 183 | @media (min-width: $min-width) 184 | font-size: s('calc( %s + (%s - %s) * ((100vw - %s) / (%s - %s)) )', $local-min-font, remove-unit($local-max-font), remove-unit($local-min-font), $min-width, remove-unit($max-width), remove-unit($min-width)) 185 | 186 | @media (min-width: $max-width) 187 | font-size: $local-max-font 188 | if $vertical-rhythm is true 189 | margin-top: (($line-height-ratio * $max-font) / ($local-max-font / 1.25))em 190 | line-height: (($line-height-ratio * $max-font) / ($local-max-font / 1.5))em 191 | margin-bottom: (($line-height-ratio * $max-font) / ($local-max-font / .25) * (1 + (3 / $local-max-font)))em 192 | 193 | t-h3() 194 | $local-min-font = $min-font * ($heading-ratio ** 1.05) 195 | $local-max-font = $max-font * ($heading-ratio ** 1.05) 196 | 197 | font-size: $local-min-font 198 | if $vertical-rhythm is true 199 | margin-top: (($line-height-ratio * $min-font) / ($local-min-font / 1.25))em 200 | line-height: (($line-height-ratio * $min-font) / ($local-min-font / 1.5))em 201 | margin-bottom: (($line-height-ratio * $min-font) / ($local-min-font / .25) * (1 + (3 / $local-min-font)))em 202 | else 203 | margin-top: 0 204 | line-height: 1.3em 205 | margin-bottom: .25em 206 | 207 | @media (min-width: $min-width) 208 | font-size: s('calc( %s + (%s - %s) * ((100vw - %s) / (%s - %s)) )', $local-min-font, remove-unit($local-max-font), remove-unit($local-min-font), $min-width, remove-unit($max-width), remove-unit($min-width)) 209 | 210 | @media (min-width: $max-width) 211 | font-size: $local-max-font 212 | if $vertical-rhythm is true 213 | margin-top: (($line-height-ratio * $max-font) / ($local-max-font / 1.25))em 214 | line-height: (($line-height-ratio * $max-font) / ($local-max-font / 1.5))em 215 | margin-bottom: (($line-height-ratio * $max-font) / ($local-max-font / .25) * (1 + (3 / $local-max-font)))em 216 | 217 | t-h4() 218 | $local-min-font = $min-font * ($heading-ratio ** .7) 219 | $local-max-font = $max-font * ($heading-ratio ** .7) 220 | 221 | font-size: $local-min-font 222 | if $vertical-rhythm is true 223 | margin-top: (($line-height-ratio * $min-font) / ($local-min-font / 1.25))em 224 | line-height: (($line-height-ratio * $min-font) / ($local-min-font / 1.5))em 225 | margin-bottom: (($line-height-ratio * $min-font) / ($local-min-font / .25) * (1 + (3 / $local-min-font)))em 226 | else 227 | margin-top: 0 228 | line-height: 1.4em 229 | margin-bottom: .25em 230 | 231 | @media (min-width: $min-width) 232 | font-size: s('calc( %s + (%s - %s) * ((100vw - %s) / (%s - %s)) )', $local-min-font, remove-unit($local-max-font), remove-unit($local-min-font), $min-width, remove-unit($max-width), remove-unit($min-width)) 233 | 234 | @media (min-width: $max-width) 235 | font-size: $local-max-font 236 | if $vertical-rhythm is true 237 | margin-top: (($line-height-ratio * $max-font) / ($local-max-font / 1.25))em 238 | line-height: (($line-height-ratio * $max-font) / ($local-max-font / 1.5))em 239 | margin-bottom: (($line-height-ratio * $max-font) / ($local-max-font / .25) * (1 + (3 / $local-max-font)))em 240 | 241 | t-h5() 242 | $local-min-font = $min-font * ($heading-ratio ** .35) 243 | $local-max-font = $max-font * ($heading-ratio ** .35) 244 | 245 | font-size: $local-min-font 246 | if $vertical-rhythm is true 247 | margin-top: (($line-height-ratio * $min-font) / ($local-min-font / 1.25))em 248 | line-height: (($line-height-ratio * $min-font) / ($local-min-font / 1.5))em 249 | margin-bottom: (($line-height-ratio * $min-font) / ($local-min-font / .25))em 250 | else 251 | margin-top: 0 252 | line-height: 1.5em 253 | margin-bottom: .25em 254 | 255 | @media (min-width: $min-width) 256 | font-size: s('calc( %s + (%s - %s) * ((100vw - %s) / (%s - %s)) )', $local-min-font, remove-unit($local-max-font), remove-unit($local-min-font), $min-width, remove-unit($max-width), remove-unit($min-width)) 257 | 258 | @media (min-width: $max-width) 259 | font-size: $local-max-font 260 | if $vertical-rhythm is true 261 | margin-top: (($line-height-ratio * $max-font) / ($local-max-font / 1.25))em 262 | line-height: (($line-height-ratio * $max-font) / ($local-max-font / 1.5))em 263 | margin-bottom: (($line-height-ratio * $max-font) / ($local-max-font / .25))em 264 | 265 | t-h6() 266 | $local-min-font = $min-font 267 | $local-max-font = $max-font 268 | 269 | font-size: $local-min-font 270 | if $vertical-rhythm is true 271 | margin-top: (($line-height-ratio * $min-font) / ($local-min-font / 1.25))em 272 | line-height: (($line-height-ratio * $min-font) / ($local-min-font / 1.5))em 273 | margin-bottom: (($line-height-ratio * $min-font) / ($local-min-font / .25) * (1 + (5 / $local-min-font)))em 274 | else 275 | margin-top: 0 276 | line-height: 1.6em 277 | margin-bottom: .25em 278 | 279 | @media (min-width: $min-width) 280 | font-size: s('calc( %s + (%s - %s) * ((100vw - %s) / (%s - %s)) )', $local-min-font, remove-unit($local-max-font), remove-unit($local-min-font), $min-width, remove-unit($max-width), remove-unit($min-width)) 281 | 282 | @media (min-width: $max-width) 283 | font-size: $local-max-font 284 | if $vertical-rhythm is true 285 | margin-top: (($line-height-ratio * $min-font) / ($local-min-font / 1.25))em 286 | line-height: (($line-height-ratio * $min-font) / ($local-min-font / 1.5))em 287 | margin-bottom: (($line-height-ratio * $min-font) / ($local-min-font / .25) * (1 + (1 / $local-min-font)))em 288 | 289 | t-blockquote() 290 | font-style: italic 291 | cite 292 | display: block 293 | font-style: normal 294 | 295 | t-pre() 296 | padding: vr-block(.5) 297 | margin-bottom: vr-block(1) 298 | code 299 | padding: 0 300 | 301 | t-code() 302 | font-family: $courier 303 | padding: ($line-height-ratio * .05)em ($line-height-ratio * .15)em 304 | line-height: 0 305 | 306 | t-abbr() 307 | border-bottom: 1px dotted currentColor 308 | cursor: help 309 | 310 | t-dt() 311 | color: $heading-color 312 | font-weight: bold 313 | 314 | t-fieldset() 315 | padding: vr-block(.5) vr-block() vr-block() 316 | border-width: 1px 317 | border-style: solid 318 | max-width: 100% 319 | margin-bottom: vr-block(1, 1) 320 | 321 | @media (min-width: $max-width) 322 | margin-bottom: vr-block(1.25, -1) 323 | 324 | button, input[type="submit"] 325 | margin-bottom: 0 326 | 327 | t-legend() 328 | color: $heading-color 329 | font-weight: bold 330 | 331 | t-label() 332 | display: block 333 | padding-bottom: vr-block(.125) 334 | margin-bottom: vr-block(-.25, -10) 335 | 336 | t-input() 337 | $local-min-font = $min-font 338 | $local-max-font = $max-font 339 | 340 | display: block 341 | max-width: 100% 342 | padding: vr-block(.25) 343 | 344 | font-size: $local-min-font 345 | margin-bottom: vr-block(.5, 7) 346 | 347 | @media (min-width: $min-width) 348 | font-size: s('calc( %s + (%s - %s) * ((100vw - %s) / (%s - %s)) )', $local-min-font, remove-unit($local-max-font), remove-unit($local-min-font), $min-width, remove-unit($max-width), remove-unit($min-width)) 349 | 350 | @media (min-width: $max-width) 351 | font-size: $local-max-font 352 | margin-bottom: vr-block(.25, 3.5) 353 | 354 | t-button() 355 | $local-min-font = $min-font 356 | $local-max-font = $max-font 357 | 358 | display: block 359 | cursor: pointer 360 | 361 | font-size: $local-min-font 362 | padding: vr-block(.25) vr-block() 363 | margin-bottom: vr-block(.75, -2) 364 | 365 | @media (min-width: $min-width) 366 | font-size: s('calc( %s + (%s - %s) * ((100vw - %s) / (%s - %s)) )', $local-min-font, remove-unit($local-max-font), remove-unit($local-min-font), $min-width, remove-unit($max-width), remove-unit($min-width)) 367 | 368 | @media (min-width: $max-width) 369 | font-size: $local-max-font 370 | margin-bottom: vr-block(.75) 371 | 372 | t-table() 373 | width: 100% 374 | border-spacing: 0 375 | border-collapse: collapse 376 | margin-bottom: vr-block(1, 5) 377 | 378 | @media (min-width: $max-width) 379 | margin-bottom: vr-block(1, 3.5) 380 | 381 | t-th() 382 | text-align: left 383 | color: $heading-color 384 | 385 | padding: vr-block(.125) vr-block(.5) 386 | 387 | @media (min-width: $max-width) 388 | padding: vr-block(.25) vr-block(.5) 389 | 390 | t-td() 391 | padding: vr-block(.125) vr-block(.5) 392 | 393 | @media (min-width: $max-width) 394 | padding: vr-block(.25) vr-block(.5) 395 | 396 | /** 397 | * The Typographic Reset. This is where Typographic goes through every markup element and styles it to adhere to a vertical rhythm. After you set your variables in a settings file fire this mixin. 398 | * 399 | * @example 400 | * typographic() 401 | */ 402 | 403 | typographic() 404 | 405 | html 406 | t-html() 407 | 408 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 409 | a, abbr, acronym, address, big, cite, code, 410 | del, dfn, em, img, ins, kbd, q, s, samp, 411 | small, strike, strong, sub, sup, tt, var, 412 | b, u, i, center, 413 | dl, dt, dd, ol, ul, li, 414 | fieldset, form, label, legend, 415 | table, caption, tbody, tfoot, thead, tr, th, td 416 | t-reset() 417 | 418 | p, blockquote, pre, 419 | address, 420 | dl, ol, ul, 421 | table 422 | t-block() 423 | 424 | h1, h2, h3, h4, h5, h6 425 | t-heading() 426 | 427 | h1 428 | t-h1() 429 | 430 | h2 431 | t-h2() 432 | 433 | h3 434 | t-h3() 435 | 436 | h4 437 | t-h4() 438 | 439 | h5 440 | t-h5() 441 | 442 | h6 443 | t-h6() 444 | 445 | blockquote 446 | t-blockquote() 447 | 448 | pre 449 | t-pre() 450 | 451 | code 452 | t-code() 453 | 454 | big, small, sub, sup 455 | line-height: 0 456 | 457 | abbr, acronym 458 | t-abbr() 459 | 460 | address 461 | font-style: normal 462 | 463 | dt 464 | t-dt() 465 | 466 | ul 467 | padding-left: 1.1em 468 | 469 | ol 470 | padding-left: 1.4em 471 | 472 | fieldset 473 | t-fieldset() 474 | 475 | legend 476 | t-legend() 477 | 478 | label 479 | t-label() 480 | 481 | input[type="text"], input[type="email"], input[type="password"], textarea 482 | t-input() 483 | 484 | input[type="submit"], button 485 | t-button() 486 | 487 | table 488 | t-table() 489 | 490 | th 491 | t-th() 492 | 493 | td 494 | t-td() 495 | --------------------------------------------------------------------------------