// --------------------------------------------------------------------------- // 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 // --------------------------------------------------------------------------- // 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 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 { @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and ( min--moz-device-pixel-ratio: 2), only screen and ( -moz-min-device-pixel-ratio: 2), only screen and ( -o-min-device-pixel-ratio: 2/1), only screen and ( min-device-pixel-ratio: 2), only screen and ( min-resolution: 192dpi), only screen and ( min-resolution: 2dppx) { @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 ); } @if $sprite-maps == () { $sprite-maps: ($name $sprite $sprite-retina $position $position-retina $repeat $repeat-retina); } @else { $sprite-maps: $sprite-maps, ($name $sprite $sprite-retina $position $position-retina $repeat $repeat-retina); } %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 { /* 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 sprite-base // // Basic mixin for using sprites with retina fallback @mixin sprite-base( $map, // sprite map $image, // image to use $retina-map: false, // retina sprite map (optional) $offset-x: 0, // background offset x (optional) $offset-y: 0 // background offset y (optional) ) { @if $map and $image { $pos: sprite-position($map, $image); $pos-x: nth( $pos, 1 ) + $offset-x*1px; $pos-y: nth( $pos, 2 ) + $offset-y*1px; background-position: $pos-x $pos-y; @if $retina-map { @include at-retina { /* Retina sprite */ $pos: sprite-position($retina-map, $image); $pos-x: nth( $pos, 1 )/2 + $offset-x*1px; $pos-y: nth( $pos, 2 )/2 + $offset-y*1px; background-position: $pos-x $pos-y; } } } } // --------------------------------------------------------------------------- // @mixin background-sprite // // Mixin for using sprites stored in the sprite map variable @mixin background-sprite( $name, // sprite name $image, // image to use $use-retina: true, // wether to use retina on hi-res screens (optional) $offset-x: 0, // background offset x (optional) $offset-y: 0 // background offset y (optional) ) { $map: return-sprite-map( $name ); $retina-map: $use-retina; @if $use-retina { $retina-map: return-sprite-map( $name, $retina: true ); } @include sprite-base( $map: $map, // sprite map $image: $image, // image to use $retina-map: $retina-map, // retina sprite map (optional) $offset-x: $offset-x, // background offset x (optional) $offset-y: $offset-y // background offset y (optional) ); @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; } }