$sprites: sprite-map("sprites/*.png"); | |
$sprites-retina: sprite-map("sprites-retina/*.png"); | |
@mixin sprite-background($name) { | |
background-image: sprite-url($sprites); | |
background-position: sprite-position($sprites, $name); | |
background-repeat: no-repeat; | |
display: block; | |
height: image-height(sprite-file($sprites, $name)); | |
width: image-width(sprite-file($sprites, $name)); | |
@media (-webkit-min-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 3/2), (min-device-pixel-ratio: 2) { | |
// Workaround for https://gist.github.com/2140082 | |
@if (sprite-position($sprites, $name) != sprite-position($sprites-retina, $name)) { | |
$ypos: round(nth(sprite-position($sprites-retina, $name), 2) / 2); | |
background-position: 0 $ypos; | |
} | |
// Hard coded width of the normal sprite image. There must be a smarter way to do this. | |
@include background-size(444px auto); | |
background-image: sprite-url($sprites-retina); | |
} | |
} | |
// Usage. | |
.mail-icon { | |
@include sprite-background(mail); | |
} |
This comment has been minimized.
This comment has been minimized.
You know what, I missed something. Nevermind. |
This comment has been minimized.
This comment has been minimized.
I came here trying to look for a way to do "smarter background size", alas, I haven't found it yet myself. |
This comment has been minimized.
This comment has been minimized.
We’ll get there! There are some smart people working on Compass extensions to do this kinda stuff automatically. |
This comment has been minimized.
This comment has been minimized.
Instead of hard coded width for the retina background-size, you can define
|
This comment has been minimized.
This comment has been minimized.
No it wont work on all cases @emfeha, the background-size has to use the width of the entire sprite image, not just the single sprite. This should also take sprite padding into account. I've dug into the Compass source to figure out how to achieve it. .mail-button
@include sprite(mail) @import compass/utilities/sprites
@import compass/css3/background-size
// Define the sprites here. Notice that I've added an optional spacing.
$sprites: sprite-map("sprite/*.png", $spacing: 20px)
$sprites2x: sprite-map("sprite2x/*.png", $spacing: 40px)
// Now let's define the sprite mixin.
// This delegates to the reusable retina-sprite mixin.
@mixin sprite($name)
@include retina-sprite($name, $sprites, $sprites2x) // 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, $sprites, $sprites2x, $dimensions: true, $pad: 0)
@if $dimensions == true
+sprite-dimensions($sprites, $name)
background-image: sprite-url($sprites)
background-position: sprite-position($sprites, $name, -$pad, -$pad)
background-repeat: no-repeat
@if $pad > 0
padding: $pad
@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)
&
$pos: sprite-position($sprites2x, $name, -$pad*2, -$pad*2)
background-image: sprite-url($sprites2x)
background-position: nth($pos, 1) nth($pos, 2)/2
+background-size(ceil(image-width(sprite-path($sprites2x)) / 2), auto)
// ^-- this is the "smarter" way to do this.
// 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 (which
// you shouldn't in the first place) |
This comment has been minimized.
This comment has been minimized.
@rstacruz - Thanks so much for your reply. I was banging my head against a wall trying to figure that out! |
This comment has been minimized.
This comment has been minimized.
Is there any way we can not add media queries on each individual icon class on compiling? Not sure if there's a different way to go about this fix. @media (-webkit-min-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 3/2), (min-device-pixel-ratio: 2) {
// Workaround for https://gist.github.com/2140082
@if (sprite-position($sprites, $name) != sprite-position($sprites-retina, $name)) {
$ypos: round(nth(sprite-position($sprites-retina, $name), 2) / 2);
background-position: 0 $ypos;
}
} Ideally, the output would be something like this: .i-rss-black {
background-position: 0 -200px;
height: 50px;
width: 50px;
}
.i-alerts-black {
background-position: 0 -800px;
height: 50px;
width: 50px;
}
.i-refresh-black {
background-position: 0 0;
height: 50px;
width: 50px;
}
.icon {
background-image: url('../images/sd-scdd529308d.png');
background-repeat: no-repeat;
display: inline-block;
}
@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 1.5/1), (min-device-pixel-ratio: 1.5) {
.icon {
-webkit-background-size: 50px auto;
-moz-background-size: 50px auto;
-o-background-size: 50px auto;
background-size: 50px auto;
background-image: url('../images/hd-s40d93ee0fe.png'); } } Then you can just add an additional icon class: <span class="icon i-refresh-black"></span> |
This comment has been minimized.
This comment has been minimized.
@Aetherpoint see my solution: $sprites: sprite-map("sprites/*.png", $spacing: 20px); $sprites2x: sprite-map("sprites2x/*.png", $spacing: 40px); @mixin sprite-retina($name, $sprites, $sprites2x, $dimensions: true, $pad: 0) { background-position: sprite-position($sprites, $name, -$pad, -$pad); background-repeat: no-repeat; @if ($dimensions == true) { @include sprite-dimensions($sprites, $name); } @if ($pad > 0) { padding: $pad } } Can I create a class for sprite or improve this: @mixin sprite-retina-class($className: sprt-bg) { .#{$className} { background-image: sprite-url($sprites); @media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3/2), (min-device-pixel-ratio: 2) { // $pos: sprite-position($sprites2x, $name, -$pad*2, -$pad*2); background-image: sprite-url($sprites2x); // background-position: nth($pos, 1) nth($pos, 2)/2; @include background-size(ceil(image-width(sprite-path($sprites2x)) / 2) auto); } } } It would be interesting to create a selector [class^="sprite-"] for all classes begin with .sprite- Abs, |
This comment has been minimized.
This comment has been minimized.
One of the above solution works really well. I have slightly modified it to have a placeholder selector : %sprites {
display: inline-block;
background-repeat: no-repeat;
background-image: sprite-url($sprites);
}
@mixin sprite($name, $dimensions: true, $pad: 0) {
@if ($dimensions == true) {
@include sprite-dimensions($sprites, $name);
}
@extend %sprites;
background-position: sprite-position($sprites, $name, -$pad, -$pad);
@if $pad > 0 {
padding: $pad;
}
@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) {
& {
$pos: sprite-position($sprites2x, $name, -$pad * 2, -$pad * 2);
background-image: sprite-url($sprites2x);
background-position: nth($pos, 1) nth($pos, 2) / 2;
@include background-size(ceil(image-width(sprite-path($sprites2x)) / 2), auto);
}
}
} The problem is that it the background-image: sprite-url($sprites2x); makes compile time a lot longer as soon as you have a few images (as it does this for every images in retina, while it just extend for the "basic" version). Is there a solution to that ? |
This comment has been minimized.
This comment has been minimized.
Just an FYI for anyone else looking to use this with a hover state, I've forked a version of this from @rstacruz and added hover and active states.
|
This comment has been minimized.
This comment has been minimized.
I wondered the same thing. This is what i came up with: https://gist.github.com/3837343 |
This comment has been minimized.
This comment has been minimized.
Do somebody have a fix for the long compile time mentioned by @bakura10? I'm using compass on a Sencha project with about 30 sprites, and while the "compass compile" takes from 15 to 20 seconds to finish – and I can see it trying to generate sprites multiple times – Sencha's build command takes forever. |
This comment has been minimized.
This comment has been minimized.
@tegola , not sure it this is related but you may want to checkout this issue. |
This comment has been minimized.
This comment has been minimized.
I've had issues with the retina sprite when using smart layout. I tried to use smart layouts as follows: $sprites-retina: sprite-map("double/*.png", $layout: smart); This resulted in two identical sprite images as expected, but SASS wasn't calculating the distances properly at all. |
This comment has been minimized.
This comment has been minimized.
I am having issues with |
This comment has been minimized.
This comment has been minimized.
Anyone get '$layout: smart' working? Also, is anyone using this with images of varying sizes/dimensions? I want to create a sprite that contains all of my site's ui elements, but they aren't all square shaped. |
This comment has been minimized.
This comment has been minimized.
We prefer using the compass helpers for sprite map and style class generation. This is a bit more future proof than manually setting |
This comment has been minimized.
This comment has been minimized.
@thulstrup Can you include an open source license in this gist? |
This comment has been minimized.
This comment has been minimized.
here is my take on retina sprites. i wanted a way to use it within the @media directive as well... https://gist.github.com/brewster1134/13162e2cb0220e87b017 I would love some feedback... |
This comment has been minimized.
This comment has been minimized.
Here is my try to make it little short and for best practice. I wanted to use background-image property for once instead of using it in every class to minimise my code. I make this
|
This comment has been minimized.
This comment has been minimized.
My smaller contribution: https://gist.github.com/tomasdev/56bc62e86ab0700f8298 works right out of the box if you're planning to save only the biggest assets and not the pixelated (non-retina) ones. |
This comment has been minimized.
This comment has been minimized.
@mbilalsiddique1 - thanks for this bit above. Working well for my usage thus far. Maybe i missed it, but any way to have the css for all icons in the folder automatically render with their unique file names as classes, instead of defining each one again ( as you show in your example ) ?
|
This comment has been minimized.
This comment has been minimized.
I believe i figured it out how to declare all the sprites in the map. Works well on top of whats above.
|
This comment has been minimized.
This comment has been minimized.
How to combine this mixin to get the image height of the sprite? |
This comment has been minimized.
I think this would be the "smarter way to do [background-size]": https://gist.github.com/2878758