aderaaij
5/16/2014 - 3:37 PM

Generated by SassMeister.com.

Generated by SassMeister.com.

.root {
  position: relative;
  z-index: 100;
}

.above-root {
  position: relative;
  z-index: 200;
}
.above-root .above-parent {
  position: relative;
  z-index: 300;
}

.below-child {
  position: relative;
  z-index: 200;
}

.top {
  position: relative;
  z-index: 400;
}

.match {
  position: relative;
  z-index: 200;
}

.always-on-top {
  position: relative;
  z-index: 900000;
}

.absolute-context {
  position: absolute;
  z-index: 100;
}

.fixed-context {
  position: fixed;
  z-index: 100;
}
// ----
// Sass (v3.3.7)
// Compass (v1.0.0.alpha.18)
// Flint (v1.2.0)
// ----

// This is an extension of the Flint grid system
// -------------------------------------------------------------------------------
// it uses custom functions and SassScript that is packaged with Flint. 
// Yes, this is a little ridiculous... but you gotta admit, it's pretty freaking nifty.

@import "flint";

// Stack configuration
// -------------------------------------------------------------------------------

$stack: (
    "root-index": 100,
    "increment-by": 100,
    "debug-mode": false,
) !default;

// Global variables
// -------------------------------------------------------------------------------

$stack__z-indexes: () !global;
$stack__increment: map-get($stack, "increment-by") !global;
$stack__root: map-get($stack, "root-index") !global;
$stack__debug: map-get($stack, "debug-mode") !global;

// Saves selectors z-index to map
// -------------------------------------------------------------------------------
// @param $i [integer] : creates new instance with passed index
// -------------------------------------------------------------------------------

@function stack-new-index($i) {
    // Check if is list of selectors, grab last
    $selector-list: last(string-to-list(selector_string()));
    // Define static selector
    $selector: selector_string();

    // Did the list return false?
    @if $selector-list != false {
        // If not, define selector as the last selector
        $selector: $selector-list;
    }

    // Is this a $stack__root definition?
    @if $i == $stack__root {
        // Save to global variable
        $global___root__selector: $selector !global;
    }

    // Create new map for selector, save z-index
    $z-index: (
        "#{$selector}": (
            "z-index": $i,
        ),
    );

    // Merge into main map
    @return map-merge($stack__z-indexes, $z-index);
}

// Fetch z-index value by selector
// -------------------------------------------------------------------------------
// @param $selector [string] : selector string
// -------------------------------------------------------------------------------

@function stack-get-index($selector) {
    @return map-fetch($stack__z-indexes, $selector "z-index");
}

// Save selectors z-index to map
// -------------------------------------------------------------------------------
// @param $i [integer] : updates $stack__z-indexes variable
// -------------------------------------------------------------------------------

@mixin stack-new-index($i) {
    $stack__z-indexes: stack-new-index($i) !global;
}

// Output debug information onto element
// -------------------------------------------------------------------------------

@mixin stack-debug($context) {
    $selector-list: last(string-to-list(selector_string()));
    $selector: selector_string();

    @if $selector-list != false {
        $selector: $selector-list;
    }

    // Get index of selector
    $index: stack-get-index($selector);

    &:after {
        content: "Selector: #{$selector} \a Index: #{$index} \a Context: #{$context}";
        font: 13px/19px Consolas, 'Liberation Mono', Courier, monospace;
        display: block;
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        padding: 6px 10px;
        background: #F8F8F8;
        border: 1px solid #DDD;
        color: #D14;
    }
}

// Main stacking mixin
// -------------------------------------------------------------------------------
// @param $param [string] : paramaters for stacking order ['always on top' | 'top' | 'above' | 'below' | 'root' | '$selector']
// @param $selector [string] : selector to base paramaters on
// @param $offset [integer] : offset the calculated z-index
// @param $context [value] : context for the stacking order [relative | absolute | fixed]
// -------------------------------------------------------------------------------
// @documentation on stacking context : https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context
// -------------------------------------------------------------------------------

@mixin stack($param, $selector: false, $offset: 0, $context: relative) {
    // Always on top
    @if $param == "always on top" and $selector == false {
        // Create a high number based off of $stack__root
        $new-index: $stack__root * 9000;
        // Create new instance for selector
        @include stack-new-index($new-index);
        // Define context
        position: $context;
        // Output calculated index
        z-index: $new-index;

        // If debug-mode is true, output styles
        @if $stack__debug {
            @include stack-debug($context);
        }
        
    // Place on top of current instances (note the stylesheet cascade, any newer instances could stack higher)
    } @else if $param == "top" and $selector == false {
        // Create temp variable
        $temp: ();

        // Loop over all selectors in map, create temp list of z-index values
        @each $selector, $key in $stack__z-indexes {
            @each $key, $value in $key {
                $temp: append($temp, $value, "comma");
            }
        }

        // Get the highest current z-index
        $max-temp: max($temp...);
        // Create new index variable
        $new-index: (($max-temp + $stack__increment) + $offset);
        // Create new instance for selector
        @include stack-new-index($new-index);
        // Define context
        position: $context;
        // Output calculated index
        z-index: $new-index;

        @if $stack__debug {
            @include stack-debug($context);
        }

    // Match [$param = $selector]
    } @else if exists($stack__z-indexes, $param) {
        // Define $param as the $selector
        $selector: $param;
        // Create new index variable, grab index from passed $selector
        $new-index: (stack-get-index($selector) + $offset);
        // Create new instance for selector
        @include stack-new-index($new-index);
        // Define context
        position: $context;
        // Output calculated index
        z-index: $new-index;

        @if $stack__debug {
            @include stack-debug($context);
        }
    
    // Definition of $stack__root
    } @else if exists($stack__z-indexes, $selector) == false and $param == "root" {

        @if global-variable-exists(root__is__set) {
            // Warn that the root has already been set
            @warn "Your document root has already been set on the selector: '#{$global___root__selector}'. Instead of defining a new root, simply match the root selectors index: stack('#{$global___root__selector}').";
            // Output $stack__root anyways
            z-index: $stack__root;
        } @else {
            // Create global root variable
            $stack__root__is__set: true !global;
            // Define as root
            @include stack-new-index($stack__root);
            // Define context
            position: $context;
            // Output $stack__root
            z-index: $stack__root;

            @if $stack__debug {
                @include stack-debug($context);
            }
        }

    // Above [$selector]
    } @else if $param == "above" {

        $new-index: ((stack-get-index($selector) + $stack__increment) + $offset);
        @include stack-new-index($new-index);
        position: $context;
        z-index: $new-index;

        @if $stack__debug {
            @include stack-debug($context);
        }

    // Below [$selector]
    } @else if $param == "below" {
    
        $new-index: ((stack-get-index($selector) - $stack__increment) + $offset);
        @include stack-new-index($new-index);
        position: $context;
        z-index: $new-index;

        @if $stack__debug {
            @include stack-debug($context);
        }

    } @else {
        // Warn that the arguments were invalid
        @warn "Invalid arguments: #{$param}, #{$selector}, #{$offset}. Either the selector does not exist, or you passed an invalid parameter.";
    }
}

.root {
    @include stack("root");
}
.above-root {
    @include stack("above", ".root");

    .above-parent {
        @include stack("above", ".above-root");
    }
}

.below-child {
    @include stack("below", ".above-parent");
}

.top {
    @include stack("top");
}

.match {
    @include stack(".above-root");
}

.always-on-top {
    @include stack("always on top");
}

.absolute-context {
  @include stack("root", $context: absolute);
}

.fixed-context {
  @include stack("root", $context: fixed);
}