Skip to content

Instantly share code, notes, and snippets.

@Undistraction
Last active August 29, 2015 14:07
Show Gist options
  • Save Undistraction/fdf79459c706d7f55d11 to your computer and use it in GitHub Desktop.
Save Undistraction/fdf79459c706d7f55d11 to your computer and use it in GitHub Desktop.
Generated by SassMeister.com.
// ----
// Sass (v3.4.4)
// Compass (v1.0.1)
// ----
// ----- API --------------------------------------------------------------------------------------
// The default font size for all text in pixels
$rhythm-base-font-size: 16px !default;
// The distance between text baselines (vertical rhythm) 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 there is at least this many pixels
// of leading above and below the text.
$rhythm-min-line-leading: 2px !default;
// Establishes a font baseline for the given font-size.
@mixin rhythm-establish($font-size: $rhythm-base-font-size) {
$is-valid: rhythm-validate-config();
$relative-size: 100% * ($font-size / $rhythm-browser-default-font-size);
html {
font-size: if($rhythm-relative-font-sizing, $relative-size, $font-size);
// Webkit has a bug that prevents line-height being set in rem on <html>;
// To work around this and simplify output, we can set initial line-height
// in ems for all relative rhythm units, even when $rhythm-unit is `rem`.
@if $rhythm-relative-font-sizing {
line-height: convert-length($rhythm-base-line-height, em);
}
@else {
line-height: round($rhythm-base-line-height);
}
}
}
// 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.
@mixin font-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-adjust-leading-to($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.
@mixin rhythm-adjust-leading-to($lines, $font-size: $rhythm-base-font-size) {
@include render-rhythm(line-height, rhythm($lines, $font-size));
}
// --------------------------------------------------------------------------------------
// Default font-size for all browsers
$rhythm-browser-default-font-size: 16px;
// The leader is the amount of whitespace in a line.
// It might be useful in your calculations.
$rhythm-base-leading: convert-length($rhythm-base-line-height - $rhythm-base-font-size, $rhythm-unit, $rhythm-base-font-size);
// The half-leader is the amount of whitespace above and below a line.
// It might be useful in your calculations.
$rhythm-base-half-leader: $rhythm-base-leading / 2;
// @private Whether the rhythm output is in absolute units (px) or not (em, rem)
$rhythm-relative-font-sizing: if($rhythm-unit == px, false, true);
$rhythm-invalid-value-error: "Invalid Value Error";
$rhythm-invalid-unit-error: "Invalid Unit Error";
$rhythm-last-error: null;
$rhythm-under-test: false;
$rhythm-error-thrown: false;
@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;
}
@function rhythm-validate-config() {
// Validate units
@if unit($rhythm-base-font-size) != 'px' {
$error: rhythm-throw-error($rhythm-invalid-unit-error, "$rhythm-base-font-size must resolve to a pixel unit.");
}
@if unit($rhythm-base-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;
}
// @private Outputs rhythm values. For rem units, outputs pixel fallbacks
// by default.
@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;
}
/**
* Overridable hook to handle unrecognised values. By default it will throw an error.
* @param {String} $value an unrecognised value
* @param {orientation} The orientation of the keyword
* @throws $pos-unsupported-value-error
* @access private
*/
@function rhythm-parse-value-filter($value) {
@return rhythm-throw-error($rhythm-invalid-value-error, "Invalid value #{$value}");
}
// Convert any CSS <length> or <percentage> value to any another.
//
// @param $length
// A css <length> or <percentage> value
//
// @param $to-unit
// String matching a css unit keyword, e.g. 'em', '%', etc.
//
// @param $from-context
// 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 $to-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 convert-length(
$length,
$to-unit,
$from-context: $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;
}
// ----- END --------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------
$base-font-size: 16px;
$base-line-height: 32px;
$rhythm-unit: rem;
@include rhythm-establish;
.auto {
@include font-rhythm(16px);
}
.lines-1 {
@include font-rhythm(16px, 1);
}
.lines-2 {
@include font-rhythm(16px, 2);
}
.lines-3 {
@include font-rhythm(single, 3);
}
$number: "single" is not a number for `unit'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment