@import "settings"; // --------------------------------------------------------------------------- // Sprites // Making good use of http://compass-style.org/reference/compass/helpers/sprites/ // // If you are concerned about the amount of "unchanged" and "created" statuses // when compiling your SCSS, read this thread: // https://github.com/chriseppstein/compass/issues/897 // --------------------------------------------------------------------------- // Global variable for device pixel ratio $min-device-pixel-ratio: 2 !default; // --------------------------------------------------------------------------- // Sprite map store $sprite-maps: (); // --------------------------------------------------------------------------- // @function return-sprite-map // // Helper function to return a sprite setting stored in the sprite map variable @function return-sprite-setting( $name, $pos ) { $sprite: false; $setting: false; @if type-of(nth($sprite-maps, 1)) == list { @each $item in $sprite-maps { @if nth( $item, 1 ) == $name { $sprite: $item; } } } @else { $sprite: $sprite-maps; // List has collapsed because it only has 1 item } @if (not $sprite) { @warn "Couldn't find any sprite named '#{$name}'. Please check your sprite settings."; } @else { $setting: nth( $sprite, $pos ); } @return $setting; } // --------------------------------------------------------------------------- // @function return-sprite-map // // Helper function to return a sprite map stored in the sprite map variable @function return-sprite-map( $name, $retina: false ) { $map: false; $sprite: false; @if $retina { $map: return-sprite-setting( $name, 3 ); // @if (not $map) { // @warn "The sprite '#{$name}' doesn't appear to have a retina version. Please check your sprite settings."; // } } @else { $map: return-sprite-setting( $name, 2 ); } @return $map; } // --------------------------------------------------------------------------- // @function return-sprite-position // // Helper function to return a sprite's horizontal position @function return-sprite-position( $name, $retina: false ) { @if $retina { @return return-sprite-setting( $name, 5 ); } @else { @return return-sprite-setting( $name, 4 ); } } // --------------------------------------------------------------------------- // @function return-sprite-repeat // // Helper function to return a sprite's css repeat @function return-sprite-position( $name, $retina: false ) { @if $retina { @return return-sprite-setting( $name, 7 ); } @else { @return return-sprite-setting( $name, 6 ); } } // --------------------------------------------------------------------------- // @function return-sprite-repeat // // Helper function to return a sprite's css repeat @function return-offset( $reference, $adjustment, $fail-msg ) { @if unit($adjustment) == "%" { @return $adjustment; } @else if unit($adjustment) == "px" or unit($adjustment) == "" { @return ( $reference + $adjustment ); } @else { @warn $fail-msg; @return $reference; } } // --------------------------------------------------------------------------- // @function sprite-image-width // // Returns width of image in sprite @function sprite-image-width( $name, $image, $use-retina: false ) { $map: return-sprite-map( $name, $use-retina ); @return image-width( sprite-file( $map, $image ) ); } // --------------------------------------------------------------------------- // @function sprite-image-height // // Returns height of image in sprite @function sprite-image-height( $name, $image, $use-retina: false ) { $map: return-sprite-map( $name, $use-retina ); @return image-height( sprite-file( $map, $image ) ); } // --------------------------------------------------------------------------- // @mixin sprite-image-dimensions // // Sets height and width from a sprite image's dimensions @mixin sprite-image-dimensions( $name, $image, $use-retina: false ) { width: sprite-image-width( $name, $image, $use-retina ); height: sprite-image-height( $name, $image, $use-retina ); } // --------------------------------------------------------------------------- // @function sprite-width // // Returns width of compiled sprite @function sprite-width( $name, $use-retina: false ) { $map: return-sprite-map( $name, $use-retina ); @return image-width( sprite-path( $map ) ); } // --------------------------------------------------------------------------- // @function sprite-height // // Returns height of compiled sprite @function sprite-height( $name, $use-retina: false ) { $map: return-sprite-map( $name, $use-retina ); @return image-height( sprite-path( $map ) ); } // --------------------------------------------------------------------------- // @mixin at-retina // // Retina media query mixin @mixin at-retina( $ratio: 2 ) { @media only screen and (-webkit-min-device-pixel-ratio: #{ $ratio }), only screen and ( min--moz-device-pixel-ratio: #{ $ratio }), only screen and ( -moz-min-device-pixel-ratio: #{ $ratio }), only screen and ( -ms-min-device-pixel-ratio: #{ $ratio }), only screen and ( -o-min-device-pixel-ratio: #{ $ratio }/1), only screen and ( min-device-pixel-ratio: #{ $ratio }), only screen and ( min-resolution: #{ $ratio * 96 }dpi), only screen and ( min-resolution: #{ $ratio }dppx) { @content; } } // --------------------------------------------------------------------------- // @mixin make-sprite // // Creates new sprite map and stores it for later use @mixin make-sprite( $name: null, $folder: null, $folder-retina: null, $position: 0%, $spacing: 0px, $repeat: no-repeat, // no-repeat or repeat-x !! WARNING: it can take ages to compile because it repeats until the images meet at both ends $layout: vertical, // vertical, horizontal, diagonal $clean-up: true, // wether or not to remove old compiled sprites $position-retina: null, $spacing-retina: null, $repeat-retina: null, $layout-retina: null, $clean-up-retina: null ) { @if $position-retina == null { $position-retina: $position; } @if $spacing-retina == null { $spacing-retina: $spacing*2; } @if $repeat-retina == null { $repeat-retina: $repeat; } @if $layout-retina == null { $layout-retina: $layout; } @if $clean-up-retina == null { $clean-up-retina: $clean-up; } @if $name { $sprite: false; $sprite-retina: false; @if $folder { $sprite: sprite-map( $folder +"/*.png", $position: $position, $spacing: $spacing, $repeat: $repeat, $layout: $layout, $clean-up: $clean-up ); } @if $folder-retina { $sprite-retina: sprite-map( $folder-retina +"/*.png", $position: $position-retina, $spacing: $spacing-retina, $repeat: $repeat-retina, $layout: $layout-retina, $clean-up: $clean-up-retina ); } $sprite-maps: append( $sprite-maps, ( $name $sprite $sprite-retina $position $position-retina $repeat $repeat-retina ), comma ); %sprite-placeholder-#{ $name } { background-image: sprite-url( $sprite ); background-repeat: $repeat; // background-position-x: $position; } %sprite-placeholder-#{ $name }-retina { @if $sprite-retina { @include at-retina( $min-device-pixel-ratio ) { /* Retina sprite */ background-image: sprite-url( $sprite-retina ); background-size: image-width( sprite-path( $sprite-retina ) )/2 auto; @if $repeat-retina != $repeat { background-repeat: $repeat-retina; } // @if $position-retina != $position { // background-position-x: $position-retina; // } } } } } } // --------------------------------------------------------------------------- // @mixin background-sprite // // Mixin for using sprites stored in the sprite map variable @mixin background-sprite( $name, // sprite name $image, // image to use $offset-x: 0, // background offset x (optional) $offset-y: 0, // background offset y (optional) $use-retina: true, // wether to use retina on hi-res screens (optional) $offset-x-retina: null, // background offset x on retina (optional) $offset-y-retina: null // background offset y on retina (optional) ) { @if $offset-x-retina == null { $offset-x-retina: $offset-x; } @if $offset-y-retina == null { $offset-y-retina: $offset-y; } $map: return-sprite-map( $name ); $retina-map: $use-retina; @if $use-retina { $retina-map: return-sprite-map( $name, $retina: true ); } @if $map and $image { $pos: sprite-position($map, $image); $pos-x: return-offset( nth( $pos, 1 ), $offset-x, "$offset-x must be a number, a pixel value or a percentage!" ); $pos-y: return-offset( nth( $pos, 2 ), $offset-y, "$offset-y must be a number, a pixel value or a percentage!" ); background-position: $pos-x $pos-y; @if $retina-map { @include at-retina( $min-device-pixel-ratio ) { /* Retina sprite */ $pos: sprite-position($retina-map, $image); $pos-x: return-offset( nth( $pos, 1 )/2, $offset-x-retina, "$offset-x-retina must be a number, a pixel value or a percentage!" ); $pos-y: return-offset( nth( $pos, 2 )/2, $offset-y-retina, "$offset-y-retina must be a number, a pixel value or a percentage!" ); background-position: $pos-x $pos-y; } } } @extend %sprite-placeholder-#{ $name }; @if $use-retina { // Set to optional because placeholder only exists if a retina sprite is set @extend %sprite-placeholder-#{ $name }-retina !optional; } }