/** Copyright 2013 Colm Delaney * Released under the MIT License: * http://www.opensource.org/licenses/mit-license.php * * To use this file, remove .txt extension, and place it within the appropriate SASS project directory */ // INCLUDE FILE - SPRITES - RWD/MEDIA QUERY COMPATIBLE // NOTE: in SASS @extend calls inside @media directives are deprecated, and are expected to be illegal as of SASS 3.3 // Therefore, this version only uses @extend for the global load-icons directive // All other references to this include are via @include mixins, which are less desirable than @extend-ed placeholders, but are fully legal // For efficiency, sprite sheets are loaded in two calls, with an optional third override step // 1. The sprite image is loaded once, called from a list of all selectors that need it // 2. The layout of the sprite - top, left, width, height, bg position - is called at the appropriate location of each element in the applicable partial // 3. The background position of the sprite - which will display a different image - can be overridden for descendant selectors, e.g. hover states // NOTE // Icons may be hidden on narrower width declarations by e.g. .selector:before { left: -2000px } // PROCEDURE // 1. Create updated sprite sheet, with date embedded in file name to avoid caching problems, e.g. icons-20131222.png // 2. At top of global .scss file, ensure all selectors that need an icon are referenced, and that the file name is up to date // 3. In appropriate .scss partial, under appropriate selector, add any padding etc., and call mixin, e.g. @include icon('main-nav-a','arrow-left-green') // - first arg should be a shorthand for the selector (must be a valid css selector, without '.' or '%'), and should be specified in icon mixin // - second arg should be a shorthand for the bg position of the sprite sheet (must be a valid css selector, without '.' or '%'), and should be specified in icon-bg-position // This will result in 3 calls for each selector // LOAD SPRITE SHEET // 1. load sprite sheet as background to either 'before' or 'after' pseudo element (or to just the element itself) // parent element must have position:relative // This mixin should be used only once per sheet for 'before' and once for 'after' elements (and once for the element itself, if need be) // More detailed layout instructions are specified further down the sheet // Args: path is relative URL to image; position is either empty, ':before', or ':after' // Typical usage: @include load-icons('../images/icons-20131222.png','before'); @mixin load-icons ($path, $position: '') { &:#{$position} { content: ""; position: absolute; background-image: url($path); background-repeat: no-repeat; // set defaults @if ($position == 'before') { top: 2px; left: 4px; } @else { bottom: -4px; left: 48%; } } } // SPECIFY ICON POSITIONS // A set of two-dimensional arrays // The first element of each is a 'key', which must be unique within that array // The remaining elements are space-separated property/value pairs // Note that any values that contains spaces must be wrapped in parentheses // 1. Icon windows // $icon-windows specifies the size and position of the "window" each icon occupies in the sprite sheet // These remain constant irrespective of where the icon is located relative to its selector $icon-windows: (error-icon-basic, background-position (-20px 0), width 14px, height 14px) (error-icon-confirmation, background-position (-20px -20px), width 14px, height 14px) (error-icon-verbose, background-position (0 0), width 20px, height 20px) (arrow-up-white, background-position (-50px -10px), width 10px, height 10px) (arrow-up-blue, background-position (-70px -10px), width 10px, height 10px) ; // 2. Icon positions // For any given icon, these will vary depending on the position of the icon relative to its selector (before, after, etc.) $icon-positions-before: (nav-a, top 20px, left 43%) (nav-a-hover, top 20px, left 43%) (errorsummary-basic, top 5px, left 4px) (errorsummary-confirmation, top 6px, left 4px) (errorsummary-verbose, top 40%, left 0) (backtotop-a, top 2px, left 2px) ; $icon-positions-after: (a, border 1px) ; // ICON POSITION MIXIN // icon name is first; selector key second; position last (defaulting to 'before') // e.g. @include icon('arrow-up-blue', 'backtotop-a'); @mixin icon($icon-id, $selector-id, $position: 'before') { $icon-positions: $icon-positions-before; @if ($position == 'before') { $icon-positions: $icon-positions-before; } &:#{$position} { @include output-declarations-from-list($icon-windows, $icon-id); @include output-declarations-from-list($icon-positions, $selector-id); } } // OUTPUT DECLARATIONS FROM LIST // NOTE: this mixin was created using the list syntax available as of SASS 3.2 // This is likely to be improved in future releases, and this mixin, and code that calls it, should be revisited // Output a single list of one or more declarations, selected via a key from a pseudo-keyed two-dimensional list // list format: // $list: // (declaration-1, top 5px, left 4px) // (declaration-2, top 40%, left 0) // (declaration-nth, top 2px, left 2px) //; // usage: @include output-declarations-from-list($list, 'declaration-2'); @mixin output-declarations-from-list($declaration-list, $declaration-id) { @each $declaration in $declaration-list { @if (nth($declaration, 1) == $declaration-id) { @each $style in $declaration { @if (length($style) == 2) { #{nth($style, 1)}: nth($style, 2); } } } } }