Skip to content

Instantly share code, notes, and snippets.

@Undistraction
Last active August 29, 2015 14:07
Show Gist options
  • Save Undistraction/24ca9b9922aee1f248bb to your computer and use it in GitHub Desktop.
Save Undistraction/24ca9b9922aee1f248bb to your computer and use it in GitHub Desktop.
Generated by SassMeister.com.
// ----
// Sass (v3.4.5)
// Compass (v1.0.1)
// ----
// Vars
// -------------------------------------------------------------------------------------------------
/// Default font size for all text in pixels
$rhythm-base-font-size: 16px !default;
/// Distance between text baselines in pixels.
$rhythm-base-line-height: 21px !default;
/// The length unit in which to output rhythm values. Supported values: px, em, rem.
/// Percent units can't be used since they make calculating padding and margins impractical,
/// and percentage borders are not valid or supported in css.
$rhythm-unit: rem !default;
/// Allows the `adjust-font-size-to` mixin and the `rhythm-lines-for-font-size` function
/// to round the line height to the nearest half line height instead of the
/// nearest integral line height to avoid large spacing between lines.
$rhythm-round-to-nearest-half-line: false !default;
/// Ensure minimum leading above / below text. Number of lines will be increased if necessary.
$rhythm-min-line-leading: 2px !default;
/// Default font-size for all browsers (don't change)
$rhythm-browser-default-font-size: 16px;
/// Amount of leading per line (above + below)
$rhythm-base-leading: convert-length($rhythm-base-line-height - $rhythm-base-font-size, $rhythm-unit, $rhythm-base-font-size);
/// CSS spreads leading out evenly above and below the line. (above | below)
$rhythm-base-half-leader: $rhythm-base-leading / 2;
/// Is the `$rhythm-unit` in absolute units (px) or not (em, rem)
$rhythm-relative-font-sizing: if($rhythm-unit == px, false, true);
/// Error thrown when a value is invalid
$rhythm-invalid-value-error: "Invalid Value Error";
/// Error thrown when a unit is invalid
$rhythm-invalid-unit-error: "Invalid Unit Error";
// Support
// -------------------------------------------------------------------------------------------------
/// Check the given `font-size` and `line-height` to make sure they are valid values.
///
/// @param {String} $font-size
/// The font size
///
/// @param {String} $line-height
/// The line-height
///
@function rhythm-validate($font-size, $line-height) {
@if unit($font-size) != 'px' {
$error: rhythm-throw-error($rhythm-invalid-unit-error, "$rhythm-base-font-size must resolve to a pixel unit.");
}
@if unit($line-height) != 'px' {
$error: rhythm-throw-error($rhythm-invalid-unit-error, "$rhythm-base-line-height must resolve to a pixel unit.");
}
@if $rhythm-unit != 'px' and $rhythm-unit != 'em' and $rhythm-unit != 'rem' {
$error: rhythm-throw-error($rhythm-invalid-unit-error, "$rhythm-unit must be `px`, `em` or `rem`.");
}
@return null;
}
/// Calculate rhythm units.
@function rhythm($lines: 1, $font-size: $rhythm-base-font-size, $offset: 0) {
//@if type-of($lines) != number {
//$lines: rhythm-parse-value-filter($lines);
//}
$rhythm: convert-length($lines * $rhythm-base-line-height - $offset, $rhythm-unit, $font-size);
@if unit($rhythm) == px {
$rhythm: floor($rhythm);
}
@return $rhythm;
}
// Calculate the minimum multiple of rhythm units needed to contain the font-size.
@function rhythm-lines-for-font-size($font-size) {
$lines: if($rhythm-round-to-nearest-half-line,
ceil(2 * $font-size / $rhythm-base-line-height) / 2,
ceil($font-size / $rhythm-base-line-height));
// If lines are cramped include some extra lead.
@if ($lines * $rhythm-base-line-height - $font-size) < ($rhythm-min-line-leading * 2) {
$lines: $lines + if($rhythm-round-to-nearest-half-line, 0.5, 1);
}
@return $lines;
}
@function rhythm-process-base-values($font-size, $line-height) {
// Error if invalid
$is-valid: rhythm-validate($font-size, $line-height);
@if $rhythm-relative-font-sizing {
// Adjust font size if base font-size different from default browser (16px)
$font-size: 100% * ($font-size / $rhythm-browser-default-font-size);
// Use ems instead of rems to avoid Webkit bug. Usage of rems is uneffected as they will use the
// em value of the html element.
$line-height: rhythm-convert-length($line-height, em);
} @else {
// ( Use given font-size )
$line-height: round(line-height);
}
@return ($font-size $line-height);
}
// Convert any CSS length or percentage value to any another.
//
// @param {String} $length
// A css length or percentage value
//
// @param {String} $to-unit
// String matching a css unit keyword, e.g. 'em', '%', etc.
//
// @param {String} $from-context ($rhythm-base-font-size)
// When converting from relative units, the absolute length (in px) to
// which $length refers (e.g. for $lengths in em units, would normally be the
// font-size of the current element).
//
// @param {String} $to-context ($from-context)
// For converting to relative units, the absolute length in px to which the
// output value will refer. Defaults to the same as $from-context, since it is
// rarely needed.
@function rhythm-convert-length(
$length,
$to-unit,
$from-context: $rhythm-base-font-size,
$to-context: $from-context
) {
$from-unit: unit($length);
// Optimize for cases where `from` and `to` units are accidentally the same.
@if $from-unit == $to-unit { @return $length; }
// Context values must be in px so we can determine a conversion ratio for
// relative units.
@if unit($from-context) != 'px' {
$error: rhythm-throw-error($rhythm-invalid-unit-error, "Parameter $from-context must resolve to a value in pixel units.");
}
@if unit($to-context) != 'px' {
$error: rhythm-throw-error($rhythm-invalid-unit-error, "Parameter $to-context must resolve to a value in pixel units.");
}
// Convert input length to pixels
$px-length: $length;
@if $from-unit != 'px' {
// Convert relative units using the from-context parameter.
@if $from-unit == 'em' { $px-length: $length * $from-context / 1em }
@else if $from-unit == 'rem' { $px-length: $length * $base-font-size / 1rem }
@else if $from-unit == '%' { $px-length: $length * $from-context / 100% }
@else if $from-unit == 'ex' { $px-length: $length * $from-context / 2ex }
@else {
$error: rhythm-throw-error($rhythm-invalid-unit-error, "#{$from-unit} unit not supported");
@return $length;
}
}
// Convert length in pixels to the output unit
$output-length: $px-length;
@if $to-unit != 'px' {
// Relative units
@if $to-unit == 'em' { $output-length: $px-length * 1em / $to-context }
@else if $to-unit == 'rem' { $output-length: $px-length * 1rem / $base-font-size }
@else if $to-unit == '%' { $output-length: $px-length * 100% / $to-context }
@else if $to-unit == 'ex' { $output-length: $px-length * 2ex / $to-context }
@else {
$error: rhythm-throw-error($rhythm-invalid-unit-error, "#{$to-unit} unit not supported");
}
}
@return $output-length;
}
/**
* Render rhythm values.
*
* @param {String) $property
* The property to render
*
* @param {String} $values
* The propery values.
*
* @output
* The rendered output.
*/
@mixin render-rhythm($property, $values) {
$output: ();
@each $value in $values {
@if unit($value) == px {
// Ensure all pixel values are rounded to the nearest pixel.
$output: join($output, round($value));
}
@else {
$output: join($output, $value);
}
}
#{$property}: $output;
}
// SUPPORT (GLUE)
// -------------------------------------------------------------------------------------------------
// These items are used in test only
$rhythm-last-error: null;
$rhythm-under-test: false;
$rhythm-error-thrown: false;
/// By default, this function will throw a Sass error, but allows errors to be stopped during testing,
/// with the error saved to `$box-last-error` instead so tests can check it was thrown.
///
/// @param {String} $error
/// The name of the error
///
/// @param {String} $message
/// The error message
///
/// @returns {Map}
/// A map of offsets to be rendered as CSS properties
///
@function rhythm-throw-error($error, $message) {
@if $rhythm-under-test {
@if not $rhythm-error-thrown {
$rhythm-error-thrown: true !global;
$rhythm-last-error: $error !global;
}
} @else {
@error "#{$error} #{$message}";
}
@return null;
}
// API
// -------------------------------------------------------------------------------------------------
/**
* Establish a rhythm throughout the document using a font-size and line-height.
*
* @param {Number} $font-size ($rhythm-base-font-size)
* The font-size to use as base
*
* @output
* Render html element with `font-size` and `line-height` set.
*/
@mixin rhythm-establish($font-size: $rhythm-base-font-size, $line-height: $rhythm-base-line-height) {
$processed-values: rhythm-process-base-values($font-size, $line-height);
// Render HTML element
html {
font-size: nth($processed-values, 1);
line-height: nth($processed-values, 2);
}
}
/**
* Adjust a block to have a different font size and line height to maintain the
* rhythm. `$lines` specifies how many multiples of the baseline rhythm each line
* of this font should use up. It does not have to be an integer, but it
* defaults to the smallest integer that is large enough to fit the font.
* Use `$from-size` to adjust from a font-size other than the base font-size.
*
* @param {String} $to-size
* The font-size for this block
*
* @params {Number} $lines
* The number of rhythm units (lines) each line of text should should fill.
*
* @output
* Output the calculated `font-size` and `line-height`.
*/
@mixin rhythm($to-size, $lines: auto, $from-size: $rhythm-base-font-size) {
$to-size: convert-length($to-size, px, $from-size);
@if $lines == auto {
$lines: rhythm-lines-for-font-size($to-size);
}
@include render-rhythm(font-size, convert-length($to-size, $rhythm-unit, $from-size));
@include rhythm-render-leading($lines, $to-size);
}
/**
* Adjust a block to have different line height to maintain the rhythm.
* `$lines` specifies how many multiples of the baseline rhythm each line of this
* font should use up. It does not have to be an integer, but it defaults to the
* smallest integer that is large enough to fit the font.
*
* @param {String} $lines
* The number of lines each line of text should take up.
*
* @param {String} $font-size ($rhythm-base-font-size)
* The font-size.
*
* @output
* The line-height.
*/
@mixin rhythm-render-leading($lines, $font-size: $rhythm-base-font-size) {
@include render-rhythm(line-height, rhythm($lines, $font-size));
}
// Examples
// ----------------------------------------------------------------------------------------------
/*
* Default
*
* Expect
* font-size: 100%;
* line-height: 1.3125em;
*/
@include rhythm-establish($font-size: 16px );
/*
* 14px font-size
*
* Expect
* font-size: 87.5%;
* line-height: 1.75em; 28/16
*/
@include rhythm-establish($font-size: 14px, $line-height: 28px );
/**
* Render rhythm values.
*
* @param {String) $property
* The property to render
*
* @param {String} $values
* The propery values.
*
* @output
* The rendered output.
*/
/**
* Establish a rhythm throughout the document using a font-size and line-height.
*
* @param {Number} $font-size ($rhythm-base-font-size)
* The font-size to use as base
*
* @output
* Render html element with `font-size` and `line-height` set.
*/
/**
* Adjust a block to have a different font size and line height to maintain the
* rhythm. `$lines` specifies how many multiples of the baseline rhythm each line
* of this font should use up. It does not have to be an integer, but it
* defaults to the smallest integer that is large enough to fit the font.
* Use `$from-size` to adjust from a font-size other than the base font-size.
*
* @param {String} $to-size
* The font-size for this block
*
* @params {Number} $lines
* The number of rhythm units (lines) each line of text should should fill.
*
* @output
* Output the calculated `font-size` and `line-height`.
*/
/**
* Adjust a block to have different line height to maintain the rhythm.
* `$lines` specifies how many multiples of the baseline rhythm each line of this
* font should use up. It does not have to be an integer, but it defaults to the
* smallest integer that is large enough to fit the font.
*
* @param {String} $lines
* The number of lines each line of text should take up.
*
* @param {String} $font-size ($rhythm-base-font-size)
* The font-size.
*
* @output
* The line-height.
*/
/*
* Default
*
* Expect
* font-size: 100%;
* line-height: 1.3125em;
*/
html {
font-size: 100%;
line-height: 1.3125em;
}
/*
* 14px font-size
*
* Expect
* font-size: 87.5%;
* line-height: 1.75em; 28/16
*/
html {
font-size: 87.5%;
line-height: 1.75em;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment