Skip to content

Instantly share code, notes, and snippets.

@danielguillan
Created May 19, 2014 16:12
Show Gist options
  • Save danielguillan/e660f1b1ae7e8f065f5a to your computer and use it in GitHub Desktop.
Save danielguillan/e660f1b1ae7e8f065f5a to your computer and use it in GitHub Desktop.
Generated by SassMeister.com.
// ----
// Sass (v3.3.8)
// Compass (v1.0.0.alpha.19)
// SassyLists (v1.0.0)
// ----
// =============================================================================
// Z-index Manager
// Early exploration for a z-index manager
//
// Goals:
//
// Global z-index management
// Grouped z-index management
// Local z-index management
// Based on relationships between elements
// Source order independent
// Simple API: z($context), z-stacj($position, $target, $context)
//
// =============================================================================
@import "SassyLists";
$z-index-min: 100 !default;
$z-index-max: 900 !default;
$z-index-step: 100 !default;
$z-stack-list: () !global;
@mixin stack($position, $selector, $target: null ) {
$item: (
selector: #{$selector},
target: #{$target},
pos: $position,
index: 0
);
$z-stack-list: append($z-stack-list, $item, comma);
}
@mixin order() {
$everything-ok: true;
// Count items
$item-count: length($z-stack-list);
// Check if z-index max is higher than z-index-min
@if ($z-index-max <= $z-index-min + $z-index-step) {
$everything-ok: false;
@warn '`$z-index-max` (#{$z-index-max}) should be higher than `$z-index-min + $z-index-step` (#{$z-index-min + $z-index-step})';
}
// Check if there are enough stack spots between min and max
@if ($item-count * $z-index-step > $z-index-max - $z-index-min) {
$everything-ok: false;
@warn 'Not enough z-index spots available for `$item-count`. Try reducing the `$z-index-step` or increase `$z-index-max`';
}
@if ($everything-ok) {
// Is there a `above-all` or a `under-all` item?
$first: ();
$last: ();
@each $item in $z-stack-list {
@if (map-get($item, pos) == 'above-all') {
$first: set-index($item, $z-index-max);
} @else if (map-get($item, pos) == 'under-all') {
$last: set-index($item, $z-index-min);
}
}
// Check if all selectors, except `above-all` and `under-all`
// Have a target that existas
$selectors: ();
$targets: ();
@each $item in $z-stack-list {
$selectors: append($selectors, map-get($item, selector));
$targets: append($targets, map-get($item, target));
}
// Order stack
@while (remaining-items()) {
// Go through the remaining `above` items
@each $item in $z-stack-list {
@if (map-get($item, index) == 0 and map-get($item, pos) == above) {
// if target selector is already ordered
$target: find-target(map-get($item, target));
$target-order: map-get($target, index);
@if ($target-order != 0) {
$set-index: set-index($item, $target-order + $z-index-step);
}
}
}
@each $item in $z-stack-list {
@if (map-get($item, index) == 0 and map-get($item, pos) == under) {
// if target selector is already ordered
$target: find-target(map-get($item, target));
$target-order: map-get($target, index);
@if ($target-order != 0) {
$set-index: set-index($item, $target-order - $z-index-step);
}
}
}
}
}
}
@function find-target($target) {
@each $item in $z-stack-list {
@if (map-get($item, selector) == $target) {
@return $item;
}
}
@return false;
}
@function remaining-items() {
@each $item in $z-stack-list {
@if (map-get($item, index) == 0) {
@return true;
}
}
@return false;
}
@function set-index($item, $index) {
$nth: index($z-stack-list, $item);
$updated-item: map-merge($item, (index: $index));
$z-stack-list: set-nth($z-stack-list, $nth, $updated-item);
@return $updated-item;
}
@include stack('above-all', '.top');
@include stack('under','.upper', '.top');
@include stack('under','.middle', '.upper');
@include stack('under','.alien', '.upper');
@include stack('above','.middle-just-above-low', '.middle-low');
@include stack('above','.middle-low', '.lower');
@include stack('above','.lower', '.min');
@include stack('under-all','.min');
@include order();
.debug {
@each $item in $z-stack-list {
item: map-get($item, index) — map-get($item, selector);
}
}
// =============================================================================
// =============================================================================
// =============================================================================
// =============================================================================
// =============================================================================
// =============================================================================
// =============================================================================
// Settings
// =============================================================================
$z-index-min: 100 !default;
$z-index-step: 100 !default;
// =============================================================================
// Define context and order
// =============================================================================
$z-index-contexts:
'main-content',
'navigation',
'ads',
'popups'
;
// =============================================================================
// Definitions
// =============================================================================
@mixin z($context) { }
@mixin z-stack($position, $target, $context) { }
.main-nav { @include z('navigation'); }
.sub-nav { @include z-stack('under', '.main-nav', 'navigation'); }
.modal { @include z('popups'); }
.wrapper { @include z('main-content'); }
.profile { @include z-stack('main-content', over, '.post'); }
.comments { @include z('main-content'); }
.post { @include z-stack('main-content', under, '.profile'); }
.something { @include z('unknown'); }
.something-else { @include z-stack('unknown', under, '.something'); }
.foo { @include z-stack('unknown', above, '.something-else'); }
.bar { @include z-stack('unknown', under, '.something'); }
.something2 { @include z('unknown2'); }
.something-else2 { @include z-stack('unknown2', under, '.something2'); }
.foo2 { @include z-stack('unknown2', above, '.something-else2'); }
.bar2 { @include z-stack('unknown', under, '.something2'); }
// =============================================================================
// Resulting maps
// =============================================================================
$contexts: (
'main-content': (
'.wrapper': (
position: above-all,
related: null
),
'.profile': (
position: over,
related: '.post'
),
'.comments': (
position: above-all,
related: null
),
'.post': (
position: under,
related: '.profile'
),
),
'navigation': (
'.main-nav': (
position: above-all,
related: null
),
'.sub-nav': (
position: under,
related: '.main-nav'
),
'.other-nav': (
position: above-all,
related: null
),
)
);
$local-on-the-fly-contexts: (
'unknown': (
'.something': (
position: above-all,
related: null
),
'.something-else': (
position: under,
related: '.something'
),
'.foo': (
position: above,
related: '.something-else'
),
'.bar': (
position: under,
related: '.something'
),
),
'unknown2': (
'.something2': (
position: above-all,
related: null
),
'.something-else2': (
position: under,
related: '.something2'
),
'.foo2': (
position: above,
related: '.something-else2'
),
'.bar2': (
position: under,
related: '.something2'
),
)
);
// =============================================================================
// Once sorted and indexes assigned
// =============================================================================
/*.debug {
// local contexts
1: .something-else;
2: .foo;
3: .bar;
4: .something;
1: .something-else2;
2: .foo2;
3: .bar2;
4: .something2;
// main-content
100: .wrapper;
200: .post;
300: .profile;
400: .comments;
//navigation
500: .subnav;
600: .main-nav;
700: other-nav;
// ads
800: .banner;
// popups
900: .modal;
}
*/
@charset "UTF-8";
.debug {
item: 900 — .top;
item: 800 — .upper;
item: 700 — .middle;
item: 700 — .alien;
item: 400 — .middle-just-above-low;
item: 300 — .middle-low;
item: 200 — .lower;
item: 100 — .min;
}
/*.debug {
// local contexts
1: .something-else;
2: .foo;
3: .bar;
4: .something;
1: .something-else2;
2: .foo2;
3: .bar2;
4: .something2;
// main-content
100: .wrapper;
200: .post;
300: .profile;
400: .comments;
//navigation
500: .subnav;
600: .main-nav;
700: other-nav;
// ads
800: .banner;
// popups
900: .modal;
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment