Skip to content

Instantly share code, notes, and snippets.

@asmithdigital
Created September 27, 2015 03:27
Show Gist options
  • Save asmithdigital/4eea34b6ed39d77f0eed to your computer and use it in GitHub Desktop.
Save asmithdigital/4eea34b6ed39d77f0eed to your computer and use it in GitHub Desktop.
// scss-lint:disable Comment
@import 'retina';
/**
* Mixin for retina backgrounds where you can't use a sprite.
*
* - Make sure you have a [email protected] file additional to your file.png.
* - The mixin prepends $imgPath, which should be set globally at some point. Default is: 'img/'
*
* Examples:
* li {
* @include retina-background(arrow, no-repeat 10px 15px)
* }
*
* a.external {
* @include retina-background(external, no-repeat right)
* }
*
* @param {String} $file Path to file relative to images folder defined in config.rb and without a file extension
* @param {Object} [$attr] Additional attributes like position or repetition. E.g. `no-repeat top right`
* @param {String} [$type] The file type.
*/
@mixin retina-background($file, $attr: '', $type: 'png') {
@if $attr != '' {
background: $attr;
}
$image: $file + '.' + $type;
$image2x: $file + '@2x.' + $type;
background-image: image-url($image);
$width: image-width($image);
$height: image-height($image);
@include retina {
background-image: image-url($image2x);
background-size: $width $height;
}
}
// scss-lint:disable Comment
/**
* Wraps any styles in a retina media query.
*/
@mixin retina {
/**
* Option variable to turn on/off IE8 support.
*
* This requires Modernizr's test for `css-mediaqueries` and RespondJS
*
* Set to `1` to turn on support.
*/
$retina-support-respondjs: 0 !default;
@media (-webkit-min-device-pixel-ratio: 1.5), (min--moz-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3/2), (min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) {
// Note: Respond.js does not support pixel-ratio media queries so older browsers (IE8) will apply styles defined within the query.
// To hide the styles from IE8, add the code within html.mediaqueries
@if ($retina-support-respondjs == 1) {
html.mediaqueries & {
@content;
}
} @else {
@content;
}
}
}
// scss-lint:disable Comment DeclarationOrder
@import 'retina';
/**
* Option variable to define the spacing between images in the generated sprite
*/
$retina-sprite-spacing: 2px !default;
$retina-sprite-names : 0;
$retina-sprite-sprites : 0;
$retina-sprite-urls : 0;
$retina-sprite-sprites2x : 0;
$retina-sprite-urls2x : 0;
/**
* A mixin to create retina sprites with hover & active states
*
* You have to register a pair of sprites using `{@link #retina-sprite-add}` and then you can use this mixin:
*
* @include retina-sprite-add(icons, "icons/*.png", "icons-retina/*.png");
*
* .my-icon {
* @include retina-sprite(icon-name, icons);
* }
*
* @param {String} $name
* @param {String} [$sprite-name]
* @param {Boolean} [$hover=false]
* @param {Boolean} [$active=false]
*/
@mixin retina-sprite($name, $sprite-name: 0, $hover: false, $active: false) {
$index: 2;
$len: length($retina-sprite-names);
@for $i from $index through $len {
@if $sprite-name == nth($retina-sprite-names, $i) {
$index: $i;
}
}
$sprite : nth($retina-sprite-sprites, $index);
$sprite-url : nth($retina-sprite-urls, $index);
$sprite2x : nth($retina-sprite-sprites2x, $index);
$sprite-url2x : nth($retina-sprite-urls2x, $index);
@include _retina-sprite($name, $sprite, $sprite-url, $sprite2x, $sprite-url2x, $hover, $active);
}
@function retina-sprite-width($name, $sprite-name: 0) {
$index: 2;
$len: length($retina-sprite-names);
@for $i from $index through $len {
@if $sprite-name == nth($retina-sprite-names, $i) {
$index: $i;
}
}
$sprite : nth($retina-sprite-sprites, $index);
@return image-width(sprite-file($sprite, $name));
}
@function retina-sprite-height($name, $sprite-name: 0) {
$index: 2;
$len: length($retina-sprite-names);
@for $i from $index through $len {
@if $sprite-name == nth($retina-sprite-names, $i) {
$index: $i;
}
}
$sprite : nth($retina-sprite-sprites, $index);
@return image-height(sprite-file($sprite, $name));
}
/**
* @param {String} $name
* @param {String} $path
* @param {String} $path2x
*/
@mixin retina-sprite-add($name, $path, $path2x) {
$sprite : sprite-map($path, $spacing: $retina-sprite-spacing);
$sprite2x : sprite-map($path2x, $spacing: $retina-sprite-spacing * 2);
@if (feature-exists(global-variable-shadowing)) {
$retina-sprite-names : append($retina-sprite-names, $name) !global;
$retina-sprite-sprites : append($retina-sprite-sprites, $sprite) !global;
$retina-sprite-urls : append($retina-sprite-urls, sprite-url($sprite)) !global;
$retina-sprite-sprites2x : append($retina-sprite-sprites2x, $sprite2x) !global;
$retina-sprite-urls2x : append($retina-sprite-urls2x, sprite-url($sprite2x)) !global;
} @else {
$retina-sprite-names : append($retina-sprite-names, $name);
$retina-sprite-sprites : append($retina-sprite-sprites, $sprite);
$retina-sprite-urls : append($retina-sprite-urls, sprite-url($sprite));
$retina-sprite-sprites2x : append($retina-sprite-sprites2x, $sprite2x);
$retina-sprite-urls2x : append($retina-sprite-urls2x, sprite-url($sprite2x));
}
}
@mixin _retina-sprite-bg-pos($sprite, $name, $pad, $multiplier: 1) {
$pos: sprite-position($sprite, $name, -$pad * $multiplier, -$pad * $multiplier);
background-position: nth($pos, 1) nth($pos, 2) / $multiplier;
}
// The general purpose retina sprite mixin.
//
// @include retina-sprite(name, $spritemap1, $spritemap2)
// @include retina-sprite(name, $spritemap1, $spritemap2[, $dimensions: true, $pad: 0])
//
// If `dimensions` is true, then width/height will also be set.
//
// if `pad` is non-zero, then that's how much padding the element will have (requires
// $spacing on the sprite maps). Great for iPhone interfaces to make hit areas bigger.
//
@mixin _retina-sprite($name, $sprite, $sprite-url, $sprite2x, $sprite-url2x, $hover, $active, $dimensions: true, $pad: 0) {
display: inline-block;
background-image: $sprite-url;
@include _retina-sprite-bg-pos($sprite, $name, $pad);
background-repeat: repeat-y;
@if $dimensions == true {
@include sprite-dimensions($sprite, $name);
}
@if $hover == true {
&:hover { @include _retina-sprite-bg-pos($sprite, $name + _hover, $pad); }
}
@if $active == true {
&:active { @include _retina-sprite-bg-pos($sprite, $name + _active, $pad); }
}
@if $pad > 0 {
padding: $pad;
}
@include retina {
background-image: $sprite-url2x;
// workaround for Chrome rendering bug when zoomed
// see issue: https://code.google.com/p/chromium/issues/detail?id=260319
@include background-size(ceil(image-width(sprite-path($sprite2x)) / 2) ceil(image-height(sprite-path($sprite2x)) / 2));
// sprite-path() returns the path of the generated sprite sheet, which
// image-width() calculates the width of. the ceil() is in place in case
// you have sprites that have an odd-number of pixels in width
@include _retina-sprite-bg-pos($sprite2x, $name, $pad, 2);
@if $hover == true {
&:hover { @include _retina-sprite-bg-pos($sprite2x, $name + _hover, $pad, 2); }
}
@if $active == true {
&:active { @include _retina-sprite-bg-pos($sprite2x, $name + _active, $pad, 2); }
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment