Last active
November 23, 2016 18:58
-
-
Save samuel-holt/07eb0aa44a60e3b3be9a to your computer and use it in GitHub Desktop.
Responsive typography
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// STRIP UNIT | |
// It strips the unit of measure and returns it | |
@function strip-unit($num) { | |
@return $num / ($num * 0 + 1); | |
} | |
// Media queries mixin | |
// Default widths | |
$default-medium: 768px !default; | |
$small-max: $default-medium - 1px; | |
$default-large: 960px !default; | |
$medium-max: $default-large - 1px; | |
$default-x-large: 1280px !default; | |
$large-max: $default-x-large - 1px; | |
$default-xx-large: 1920px !default; | |
$x-large-max: $default-xx-large - 1px; | |
//Aliases | |
$default-tablet: $default-medium; | |
$default-desktop: $default-large; | |
$default-query: "only screen" !default; | |
@function get-query($min, $max:false, $dimension:"width", $default:$default-query) { | |
@if not $min and not $max { | |
@warn "Minimum or maximum pixel value required!"; | |
@return false; | |
} | |
$range: ""; | |
@if $min and unitless($min) { | |
$min: $min * 1px; | |
} | |
@if $max and unitless($max) { | |
$max: $max * 1px; | |
} | |
@if $min { | |
$range: "(min-#{$dimension}:#{$min})"; | |
} | |
@if $max { | |
$range: "#{$range} and (max-#{$dimension}:#{$max})"; | |
} | |
@return "#{$default} and #{$range}"; | |
} | |
$small-only: get-query(false, $small-max); | |
$default-medium-up: get-query($default-medium) !default; | |
$default-large-up: get-query($default-large) !default; | |
$default-x-large-up: get-query($default-x-large) !default; | |
$default-xx-large-up: get-query($default-xx-large) !default; | |
@mixin media($query, | |
$medium-up: $default-medium-up, | |
$large-up: $default-large-up, | |
$x-large-up: $default-x-large-up, | |
$xx-large-up: $default-xx-large-up, | |
$min-value: false, | |
$max-value: false | |
) { | |
$query: unquote($query); | |
// Human-friendly media query names :) | |
@if index( (s, small, small-up, mobile-up), $query) { | |
@media only screen { | |
@content; | |
} | |
} | |
@else if index(small-only, mobile-only) { | |
@media #{$small-only} { | |
@content; | |
} | |
} | |
@else if index( (m, medium, medium-up, tablet-up), $query) { | |
@media #{$medium-up} { | |
@content; | |
} | |
} | |
@else if index( (l, large, large-up, desktop-up), $query) { | |
@media #{$large-up} { | |
@content; | |
} | |
} | |
@else if index( (xl, x-large, x-large-up, large-desktop-up), $query) { | |
@media #{$x-large-up} { | |
@content; | |
} | |
} | |
@else if index( (xxl, xx-large, xx-large-up), $query) { | |
@media #{$xx-large-up} { | |
@content; | |
} | |
} | |
@else if custom == $query { | |
$custom-query: get-query($min-value, $max-value); | |
@media #{$custom-query} { | |
@content; | |
} | |
} | |
@else { | |
@error "Invalid media query: #{$query}"; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$global-legacy-support: ie8 ie9 !default; | |
// This is the default html and body font-size for the base rem value. | |
$rem-base: 16px !default; | |
$line-height-base: 1.8 !default; | |
// REM calculation courtesy of Zurb Foundation :) | |
// CONVERT TO REM | |
@function convert-to-rem($value, $base-value: $rem-base) { | |
$value: strip-unit($value) / strip-unit($base-value) * 1rem; | |
@if ($value == 0rem) { $value: 0; } // Turn 0rem into 0 | |
@return $value; | |
} | |
// REM CALC | |
@function rem-calc($values, $base-value: $rem-base) { | |
$max: length($values); | |
@if $max == 1 { @return convert-to-rem(nth($values, 1), $base-value); } | |
$remValues: (); | |
@for $i from 1 through $max { | |
$remValues: append($remValues, convert-to-rem(nth($values, $i), $base-value)); | |
} | |
@return $remValues; | |
} | |
// Simple REM font values | |
// The idea is you put in pixel values (safe, familiar) | |
// and you get rem values (strange, mysterious) | |
@mixin rem-font($pixel-value, $base:$rem-base, $legacy-support: $global-legacy-support) { | |
@if unitless($pixel-value) { | |
$pixel-value: $pixel-value * 1px; | |
} | |
// $legacy-support is set as global variable | |
@if index($legacy-support, ie8) { | |
font-size: $pixel-value; | |
} | |
font-size: rem-calc($pixel-value, $base); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// -------------------------------------------- | |
// Typography generator | |
// -------------------------------------------- | |
// Modular scale, many thanks to Bourbon | |
// See: http://bourbon.io/docs/#modular-scale | |
// Scaling Variables | |
$golden: 1.618; | |
$minor-second: 1.067; | |
$major-second: 1.125; | |
$minor-third: 1.2; | |
$major-third: 1.25; | |
$perfect-fourth: 1.333; | |
$augmented-fourth: 1.414; | |
$perfect-fifth: 1.5; | |
$minor-sixth: 1.6; | |
$major-sixth: 1.667; | |
$minor-seventh: 1.778; | |
$major-seventh: 1.875; | |
$octave: 2; | |
$major-tenth: 2.5; | |
$major-eleventh: 2.667; | |
$major-twelfth: 3; | |
$double-octave: 4; | |
$modular-scale-ratio: $perfect-fourth !default; | |
$modular-scale-base: 16px !default; | |
@function modular-scale($increment, $value: $modular-scale-base, $ratio: $modular-scale-ratio) { | |
$v1: nth($value, 1); | |
$v2: nth($value, length($value)); | |
$value: $v1; | |
// scale $v2 to just above $v1 | |
@while $v2 > $v1 { | |
$v2: ($v2 / $ratio); // will be off-by-1 | |
} | |
@while $v2 < $v1 { | |
$v2: ($v2 * $ratio); // will fix off-by-1 | |
} | |
// check AFTER scaling $v2 to prevent double-counting corner-case | |
$double-stranded: $v2 > $v1; | |
@if $increment > 0 { | |
@for $i from 1 through $increment { | |
@if $double-stranded and ($v1 * $ratio) > $v2 { | |
$value: $v2; | |
$v2: ($v2 * $ratio); | |
} @else { | |
$v1: ($v1 * $ratio); | |
$value: $v1; | |
} | |
} | |
} | |
@if $increment < 0 { | |
// adjust $v2 to just below $v1 | |
@if $double-stranded { | |
$v2: ($v2 / $ratio); | |
} | |
@for $i from $increment through -1 { | |
@if $double-stranded and ($v1 / $ratio) < $v2 { | |
$value: $v2; | |
$v2: ($v2 / $ratio); | |
} @else { | |
$v1: ($v1 / $ratio); | |
$value: $v1; | |
} | |
} | |
} | |
@return $value; | |
} | |
$my-base-font-size: 16px !default; | |
// Set the defaults | |
$default-scale: 0.9 !default; | |
$small-font-factor: 80% !default; | |
// Set minimum readable size | |
$minimum-font-size: 12px !default; | |
$default-base: $my-base-font-size !default; | |
// Desktop first approach :-/ | |
// Smaller sizes | |
$medium-base: $default-base * $default-scale; | |
$small-base: $medium-base * $default-scale; | |
// Larger sizes | |
$x-large-base: $default-base + ( (1 - $default-scale) * $default-base ); | |
$xx-large-base: $x-large-base + ( (1 - $default-scale) * $x-large-base ); | |
$default-ratio: $golden !default; | |
$default-media-queries: (($small-base, small-up), | |
($medium-base, medium-up), | |
($default-base, large-up), | |
($x-large-base, x-large-up), | |
($xx-large-base, xx-large-up)) !default; | |
// Helper functions | |
// Helper function for calculating heading sizes | |
@function minor-heading($size, $base, $scale) { | |
$heading-size: $scale * $size; | |
// Set base as the smallest heading size | |
// Make sure the heading is larger than or equal to the base | |
@return max($heading-size, $base); | |
} | |
@mixin generate-typography( | |
$base:$default-base, | |
$scale:$default-scale, | |
$media-queries:$default-media-queries, | |
$ratio:$default-ratio, | |
$line-height-ratio:$default-ratio | |
) { | |
// Generate base font | |
@each $base, $query in $media-queries { | |
@include media($query) { | |
html, body { | |
@debug max($minimum-font-size, $base); | |
font-size: max($minimum-font-size, $base); | |
} | |
} | |
} | |
// Basic style defaults | |
body { | |
font-family: Helvetica, Arial, sans-serif; | |
} | |
// Set line-height to golden ratio | |
h1, h2, h3, h4, h5, h6, p, li, dt, dd, blockquote, td, th { | |
line-height: $line-height-ratio; | |
} | |
// Inline elements inherit font size from parent | |
a, span, strong, em, b, i, input, select, textarea, button { | |
font-size: inherit; | |
line-height: inherit; | |
} | |
small, figcaption, sup, sub { | |
font-size: $small-font-factor; | |
} | |
// Use the modular scale to generate our main headings | |
$default-heading-1: modular-scale(2, $base, $ratio); | |
$default-heading-2: modular-scale(1, $base, $ratio); | |
// Use a simple linear scale to generate minor headings | |
$default-heading-3: minor-heading($default-heading-2, $base, $scale); | |
$default-heading-4: minor-heading($default-heading-3, $base, $scale); | |
$default-heading-5: minor-heading($default-heading-4, $base, $scale); | |
$default-heading-6: minor-heading($default-heading-5, $base, $scale); | |
blockquote { | |
font-size: $default-heading-2; | |
} | |
h1 { | |
@include rem-font( $default-heading-1, $base ); | |
} | |
h2 { | |
@include rem-font( $default-heading-2, $base ); | |
} | |
h3 { | |
@include rem-font( $default-heading-3, $base ); | |
} | |
h4 { | |
@include rem-font( $default-heading-4, $base ); | |
} | |
h5 { | |
@include rem-font( $default-heading-5, $base ); | |
} | |
h6 { | |
@include rem-font( $default-heading-6, $base ); | |
} | |
} | |
// Call the mixin (example) | |
@include generate-typography(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment