Skip to content

Instantly share code, notes, and snippets.

@Undistraction
Created October 11, 2014 17:37
Show Gist options
  • Save Undistraction/1b71b0776b34cd98533f to your computer and use it in GitHub Desktop.
Save Undistraction/1b71b0776b34cd98533f to your computer and use it in GitHub Desktop.
Generated by SassMeister.com.
// ----
// Sass (v3.4.4)
// Compass (v1.0.1)
// ----
/*! Position - v0.2.5 - 2014-10-11 */
/**
* @author Pedr Browne
* @access private
* @group Support
**/
// Support
// -------------------------------------------------------------------------------------------------
/**
* Values accepted for `position`.
*/
$pos-accepted-position-values: fixed absolute relative static;
/**
* Keywords that are never followed by a value
*/
$pos-always-valueless: fill fill-h fill-v;
/**
* Keywords that are always followed by a value
*/
$pos-always-value: offset offset-h offset-v all;
/**
* Keywords that are sometimes followed by a value
*/
$pos-support-valueless: left right top bottom;
/**
* All Keywords
*/
$pos-keywords: join($pos-support-valueless, join($pos-always-valueless, $pos-always-value));
/**
* Values without a unit that are accepted without being parsed
*/
$pos-valid-unitless-values: auto initial inherit 0;
/**
* Error thrown when an item that needs a value has no following value
*/
$pos-missing-value-error: "Missing Value Error";
/**
* Error thrown when an item which doesn't support a value has a value following it
*/
$pos-unsupported-value-error: "Unsupported Value Error";
/**
* Error thrown when an unsupported keyword is used
*/
$pos-invalid-keyword-error: "Invalid Keyword Error";
/**
* This is the workhorse function, taking a list of offset keywords and values and parsing them
* to an object of offset values.
*
* @param {List} $args
* A list of offset keywords and values
*
* @returns {Map}
* A map of offsets to be rendered as CSS properties
*
* @throws $pos-unsupported-value-error
* @throws $pos-invalid-value-error
* @throws $pos-missing-value-error
* @throws $pos-invalid-keyword-error
*/
@function pos-parse-offsets($args) {
// Offsets acts as our model. We use the args to adjust its
// values and untimately use it to render.
$offsets: (
top: null,
right: null,
bottom: null,
left: null
);
// If a keyword accepted a value and it was present $skip will be set to true so
// that we don't parse that value as a keyword and skip on to the next item
$skip: false;
// Run through each item, checking its validity and setting any offsets it
// effects.
@each $item in $args {
@if not $skip {
// Setup for this iteration
$index: index($args, $item);
$is-last-item: $index == length($args);
$next-item: null;
@if not $is-last-item {
$next-item: nth($args, $index + 1);
}
// Handle keyword that doesn't accept a value
@if index($pos-always-valueless, $item) {
@if $is-last-item or pos-is-keyword($next-item) {
$offsets: pos-parse-offsets-for-always-valueless($offsets, $item);
} @else {
$error: pos-throw-error( $pos-unsupported-value-error, "`#{$item}` doesn't support a value but found: `#{$next-item}`.");
}
// Handle keyword that must have a value
} @else if index($pos-always-value, $item) {
// Do we have a united next item?
@if not ( $is-last-item or pos-is-keyword($next-item) ) {
$skip: true;
$offsets: pos-parse-offsets-for-always-value($offsets, $item, $next-item);
} @else {
// Handle errors
@if $next-item {
$error: pos-throw-error( $pos-invalid-value-error, "`#{$item}` should be followed by a valid value, yet it was `#{$next-item}`.");
} @else {
$error: pos-throw-error( $pos-missing-value-error, "`#{$item}` should be followed by a valid value, but none was supplied.");
}
}
// Handle keyword that might have a value
} @else if index($pos-support-valueless, $item) {
// Is the next item is a valid value?
$value: null;
@if $is-last-item or pos-is-keyword($next-item) {
// Value is unitless
$value: 0;
} @else {
// Value is valid unit
$skip: true;
@if not pos-is-valid-value($next-item) {
$orientation: pos-orientation-for-support-valueless($item);
$next-item: pos-parse-value-filter($next-item, $orientation)
}
$value: $next-item;
} @else {
$error: pos-throw-error( $pos-invalid-value-error, "`#{$item}` was followed by an invalid value; `{$value}`");
}
$offsets: map-merge($offsets, ($item: $value));
} @else {
$error: pos-throw-error( $pos-invalid-keyword-error, "`#{$item}` is not a valid keyword.");
}
} @else {
// We skipped this item, so reset for next iteration
$skip: false;
}
}
// Build and return a map containing non-null offsets
$non-null-offsets:();
@each $key, $value in $offsets {
@if $value {
$non-null-offsets: map-merge($non-null-offsets, ($key: $value));
}
}
@return $non-null-offsets;
}
/**
* Determine if the value is a valid value for position
*
* @param {String} $value
* Value to use for $position.
*
* @returns {Bool}
* Was the position valid?
*/
@function pos-position-is-valid($value){
@return not not index($pos-accepted-position-values, $value);
}
/**
* Determine if the value is a supported keyword.
*
* @param {String} $value
* Item to be checked
*
* @returns {Bool}
* Was the item a supported keyword?
*/
@function pos-is-keyword($value) {
@return not not index($pos-keywords, $value);
}
/**
* Parse keyword that is always valueless to offset values.
*
* @param {Map} $offsets
* Map of offsets to adjust for the given keyword.
*
* @param {String} $item
* Offset keyword.
*
* @returns {Map}
* Adjusted Offsets
*/
@function pos-parse-offsets-for-always-valueless($offsets, $item) {
// Horizontal Fill
@if $item == fill-h or $item == fill {
$offsets: map-merge($offsets, (
left: 0,
right: 0
));
}
// Vertical Fill
@if $item == fill-v or $item == fill {
$offsets: map-merge($offsets, (
top: 0,
bottom: 0
));
}
@return $offsets;
}
/**
* Parse keyword that always has a value and its value to offset values.
*
* @param {Map} $offsets
* Map of offsets to adjust for the given keyword and value.
*
* @param {String} $item
* Offset keyword.
*
* @param {String} $item Offset value.
*
* @returns {Map}
* Adjusted Offsets
*/
@function pos-parse-offsets-for-always-value($offsets, $item, $value) {
// Do we need to parse each value?
$parse-value: not pos-is-valid-value($value);
@if $item == offset-h or $item == offset or $item == all {
@if $parse-value {
$value: pos-parse-value-filter($value, horizontal);
}
$offsets: map-merge($offsets, (
left: $value,
right: $value
));
}
@if $item == offset-v or $item == offset or $item == all {
@if $parse-value {
$value: pos-parse-value-filter($next-item, vertical);
}
$offsets: map-merge($offsets, (
top: $value,
bottom: $value
));
}
@return $offsets;
}
/**
* Get the orientation for a valueless keyword
*
* @param {String} $item
* An item from $pos-support-valueless list
*
* @returns {String}
* The keyword's orientation (vertical | horizontal)
*/
@function pos-orientation-for-support-valueless($item) {
@if $item == left or $item == right {
@return horizontal;
} @else {
@return vertical;
}
}
/**
* Render offsets to CSS properties.
*
* @param {String} $position
* The position - One of absolute | fixed | relative | static
*.
* @param {List} $args
* A map of offset keywords and values.
*/
@mixin pos-render($position, $offsets) {
// Render position
position: $position;
// Render offsets
@each $offset, $offset-value in $offsets {
#{$offset}: #{$offset-value};
}
}
// Common
// TODO: Extract to Glue
// -------------------------------------------------------------------------------------------------
/**
* Error thrown when an item is followed by an invalid value
*/
$pos-invalid-value-error: "Invalid Value Error";
// These items are used in test only
$pos-last-error: null;
$pos-under-test: false;
$pos-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 `$pos-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 pos-throw-error($error, $message) {
@if $pos-under-test {
@if not $pos-error-thrown {
$pos-error-thrown: true !global;
$pos-last-error: $error !global;
}
} @else {
@error "#{$error} #{$message}";
}
@return null;
}
/**
* 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 value's keyword (horizontal | vertical)
*
* @throws $pos-unsupported-value-error
*/
@function pos-parse-value-filter($value, $orientation) {
@return pos-throw-error($pos-invalid-value-error, "Invalid value #{$value}");
}
/**
* Was the value a valid one; either united, supported unitless or calc
*
* @param {String} $value
* The value to be checked
*
* @returns {Bool}
* Was the value valid?
*/
@function pos-is-valid-value($value) {
@return pos-is-number-with-unit($value)
or pos-is-valid-unitless($value)
or pos-is-calc($value);
}
/**
* Determine if the value is a valid number with a unit
*
* @param {String} $value
* Value to be checked
*
* @returns {Bool}
* Was the value number with a unit?
*/
@function pos-is-number-with-unit($value) {
@return (type-of($value) == number and not unitless($value));
}
/**
* Determine if the value is a valid unitless value.
*
* @param {String} $value
* Value to be checked
*
* @returns {Bool}
* Was the value unitless?
*/
@function pos-is-valid-unitless($value) {
@return not not index($pos-valid-unitless-values, $value);
}
/**
* Determine if the value is a `calc()` expression.
*
* @param {String} $value
* Value to be checked
*
* @returns {Bool}
* Was the value a `calc` expression?
*/
@function pos-is-calc($value) {
@return str-slice($value + "", 1, 4) == calc;
}
/**
* @author Pedr Browne
* @access public
* @group API
**/
// API
// -------------------------------------------------------------------------------------------------
/**
* @param {String} $position
* One of absolute | relative | fixed
*
* @param {List} $args (())
* A list of offset keywords and values. Some keywords require a following value, some do not
* accept a following value, and for some the value is optional. The possible values are:
*
* - `top`, `bottom`, `left`, and `right` If one of these keywords is followed by a value, the
* offset will be set to that value. If no value follows, the offset will be set to zero.
* - `offset | all | offset-h | offset-v` All these values require a value. `offset` and `all`
* (which is just an alias of `offset`) will set all four offsets ('top', 'bottom', 'left'
* and `right`) to the following value. `offset-h` will set the `left` and `right` offsets to the
* following value, and `offset-v` will set the `top` and `bottom` offsets to the following
* value.
* - `fill`, `fill-h` and `fill-v` do not take a following value. `fill` will set all offsets to
* zero. `fill-h` will set the `left` and `right` offsets to zero, and `fill-v` will set the
* `top` and `bottom` offsets to zero.
*
* Values are evaluated LTR with later values overriding earlier values.
*
* @example scss - Usage
* .element {
* @include position(absolute, left top 10px);
* }
*
* @example css - CSS Output
* .element {
* position: absolute;
* left: 0;
* top: 10px;
* }
*
* @throws
* Argument Error
*
* @output
* Outputs the position property and any supplied offset properties
*/
@mixin position($position, $args:null) {
$offsets: ();
// Check position is a supported value
@if not pos-position-is-valid($position) {
$error: pos-throw-error( $pos-error-invalid-position, "#{$position} is not a valid value for `position`" );
}
// Parse offsets if preset
@if $args {
$offsets: pos-parse-offsets($args);
}
@include pos-render($position, $offsets);
}
// Shorthand Mixins
/**
* Shorthand for `@include position(absolute, args)`.
*
* @param {List} $args
* A list of offset keywords and values.
*
* @output
* Outputs the position property and any given offset properties
*
* @see {mixin} position
*/
@mixin absolute($args: ()) {
@include position(absolute, $args);
}
/**
* Shorthand for `@include position(absolute, args)`.
*
* @param {List} $args
* A list of offset keywords and values.
*
* @output
* Outputs the position property and any given offset properties
*
* @see {mixin} position
*/
@mixin fixed($args: ()) {
@include position(fixed, $args);
}
/**
* Shorthand for `@include position(absolute, args)`.
*
* @param {List} $args
* A list of offset keywords and values.
*
* @output
* Outputs the position property and any given offset properties
*
* @see {mixin} position
*/
@mixin relative($args: ()) {
@include position(relative, $args);
}
/**
* Shorthand for `@include position(static)`.
*
* @output Outputs the position property
*
* @see {mixin} position
*/
@mixin static() {
@include position(relative, $args);
}
// Examples
//-----------------------------------------------------------------------------------
.Example-without-value {
@include absolute(top left);
}
.Example-with-value {
@include absolute(top 1rem left 2rem);
}
.Example-with-offset {
@include absolute(offset 2rem);
}
.Example-with-all {
@include absolute(offset 2rem);
}
.Example-with-offset-h {
@include absolute(offset-h 2rem);
}
.Example-with-offset-v {
@include absolute(offset-v 2rem);
}
.Example-with-fill {
@include absolute(fill);
}
.Example-with-fill-h {
@include absolute(fill-h);
}
.Example-with-fill-v {
@include absolute(fill-v);
}
// Examples (Custom Units)
//-----------------------------------------------------------------------------------
$custom-units-map: (
single: 10px,
double: 20px,
triple: 30px
);
@function pos-parse-value-filter($value, $orientation){
@if map-has-key($custom-units-map, $value) {
@return map-get($custom-units-map, $value);
} @else {
@return pos-throw-error($pos-invalid-value-error, "Invalid value #{$value}");
}
}
.Example-custom-units {
@include absolute(top single bottom double offset-h triple);
}
/*! Position - v0.2.5 - 2014-10-11 */
/**
* @author Pedr Browne
* @access private
* @group Support
**/
/**
* Values accepted for `position`.
*/
/**
* Keywords that are never followed by a value
*/
/**
* Keywords that are always followed by a value
*/
/**
* Keywords that are sometimes followed by a value
*/
/**
* All Keywords
*/
/**
* Values without a unit that are accepted without being parsed
*/
/**
* Error thrown when an item that needs a value has no following value
*/
/**
* Error thrown when an item which doesn't support a value has a value following it
*/
/**
* Error thrown when an unsupported keyword is used
*/
/**
* This is the workhorse function, taking a list of offset keywords and values and parsing them
* to an object of offset values.
*
* @param {List} $args
* A list of offset keywords and values
*
* @returns {Map}
* A map of offsets to be rendered as CSS properties
*
* @throws $pos-unsupported-value-error
* @throws $pos-invalid-value-error
* @throws $pos-missing-value-error
* @throws $pos-invalid-keyword-error
*/
/**
* Determine if the value is a valid value for position
*
* @param {String} $value
* Value to use for $position.
*
* @returns {Bool}
* Was the position valid?
*/
/**
* Determine if the value is a supported keyword.
*
* @param {String} $value
* Item to be checked
*
* @returns {Bool}
* Was the item a supported keyword?
*/
/**
* Parse keyword that is always valueless to offset values.
*
* @param {Map} $offsets
* Map of offsets to adjust for the given keyword.
*
* @param {String} $item
* Offset keyword.
*
* @returns {Map}
* Adjusted Offsets
*/
/**
* Parse keyword that always has a value and its value to offset values.
*
* @param {Map} $offsets
* Map of offsets to adjust for the given keyword and value.
*
* @param {String} $item
* Offset keyword.
*
* @param {String} $item Offset value.
*
* @returns {Map}
* Adjusted Offsets
*/
/**
* Get the orientation for a valueless keyword
*
* @param {String} $item
* An item from $pos-support-valueless list
*
* @returns {String}
* The keyword's orientation (vertical | horizontal)
*/
/**
* Render offsets to CSS properties.
*
* @param {String} $position
* The position - One of absolute | fixed | relative | static
*.
* @param {List} $args
* A map of offset keywords and values.
*/
/**
* Error thrown when an item is followed by an invalid value
*/
/**
* By default, this function will throw a Sass error, but allows errors to be stopped during testing,
* with the error saved to `$pos-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
*/
/**
* 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 value's keyword (horizontal | vertical)
*
* @throws $pos-unsupported-value-error
*/
/**
* Was the value a valid one; either united, supported unitless or calc
*
* @param {String} $value
* The value to be checked
*
* @returns {Bool}
* Was the value valid?
*/
/**
* Determine if the value is a valid number with a unit
*
* @param {String} $value
* Value to be checked
*
* @returns {Bool}
* Was the value number with a unit?
*/
/**
* Determine if the value is a valid unitless value.
*
* @param {String} $value
* Value to be checked
*
* @returns {Bool}
* Was the value unitless?
*/
/**
* Determine if the value is a `calc()` expression.
*
* @param {String} $value
* Value to be checked
*
* @returns {Bool}
* Was the value a `calc` expression?
*/
/**
* @author Pedr Browne
* @access public
* @group API
**/
/**
* @param {String} $position
* One of absolute | relative | fixed
*
* @param {List} $args (())
* A list of offset keywords and values. Some keywords require a following value, some do not
* accept a following value, and for some the value is optional. The possible values are:
*
* - `top`, `bottom`, `left`, and `right` If one of these keywords is followed by a value, the
* offset will be set to that value. If no value follows, the offset will be set to zero.
* - `offset | all | offset-h | offset-v` All these values require a value. `offset` and `all`
* (which is just an alias of `offset`) will set all four offsets ('top', 'bottom', 'left'
* and `right`) to the following value. `offset-h` will set the `left` and `right` offsets to the
* following value, and `offset-v` will set the `top` and `bottom` offsets to the following
* value.
* - `fill`, `fill-h` and `fill-v` do not take a following value. `fill` will set all offsets to
* zero. `fill-h` will set the `left` and `right` offsets to zero, and `fill-v` will set the
* `top` and `bottom` offsets to zero.
*
* Values are evaluated LTR with later values overriding earlier values.
*
* @example scss - Usage
* .element {
* @include position(absolute, left top 10px);
* }
*
* @example css - CSS Output
* .element {
* position: absolute;
* left: 0;
* top: 10px;
* }
*
* @throws
* Argument Error
*
* @output
* Outputs the position property and any supplied offset properties
*/
/**
* Shorthand for `@include position(absolute, args)`.
*
* @param {List} $args
* A list of offset keywords and values.
*
* @output
* Outputs the position property and any given offset properties
*
* @see {mixin} position
*/
/**
* Shorthand for `@include position(absolute, args)`.
*
* @param {List} $args
* A list of offset keywords and values.
*
* @output
* Outputs the position property and any given offset properties
*
* @see {mixin} position
*/
/**
* Shorthand for `@include position(absolute, args)`.
*
* @param {List} $args
* A list of offset keywords and values.
*
* @output
* Outputs the position property and any given offset properties
*
* @see {mixin} position
*/
/**
* Shorthand for `@include position(static)`.
*
* @output Outputs the position property
*
* @see {mixin} position
*/
.Example-without-value {
position: absolute;
top: 0;
left: 0;
}
.Example-with-value {
position: absolute;
top: 1rem;
left: 2rem;
}
.Example-with-offset {
position: absolute;
top: 2rem;
right: 2rem;
bottom: 2rem;
left: 2rem;
}
.Example-with-all {
position: absolute;
top: 2rem;
right: 2rem;
bottom: 2rem;
left: 2rem;
}
.Example-with-offset-h {
position: absolute;
right: 2rem;
left: 2rem;
}
.Example-with-offset-v {
position: absolute;
top: 2rem;
bottom: 2rem;
}
.Example-with-fill {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.Example-with-fill-h {
position: absolute;
right: 0;
left: 0;
}
.Example-with-fill-v {
position: absolute;
top: 0;
bottom: 0;
}
.Example-custom-units {
position: absolute;
top: 10px;
right: 30px;
bottom: 20px;
left: 30px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment