Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Retina sprites #19

mmhd opened this issue Aug 14, 2012 · 9 comments

Add support for Retina sprites #19

mmhd opened this issue Aug 14, 2012 · 9 comments


Copy link

@mmhd mmhd commented Aug 14, 2012

It would be amazing if we could add @2x to icons which are the Retina counterparts of their non-Retina versions. Doing would create a new rule in the same stylesheet but only for @2x versions. Some JavaScript would be needed to handle when the @2x version is used.

Copy link

@joeylomanto joeylomanto commented Nov 13, 2012

I agree. This would be great. Glue does something similar to what you're describing.

Copy link

@matsuodesign matsuodesign commented Dec 19, 2012

I'm close to coming up with a solution by using sprite-factory's "Customizing the entire CSS output" method. I'm passing variables into a SASS mixin that then writes most of the necessary css/media query. I'm also using this as a general mixin for use in my stylesheets, so all the variables that'd come from sprite factory are optional and come after the $sprite: false declaration.

The only real issue I'm running into is trying to figure out a way to access the width and height of the final output image (necessary to set the correct background size on retina). I feel like I'm probably overlooking something simple... have tried using :cssw, :cssh. Any suggestions?

The code assumes you're starting with your highest resolution assets; I may try to integrate some sort of image processor after the sprite-factory call to create the second image scaled at 50%.

Again any suggestions on accessing the final output size, or code improvements would be greatly appreciated!
And if you're curious I'm using retina.js for images outside the stylesheet.

@mixin retina_url($path, $filetype, $repeat: no-repeat, $rwidth: auto, $rheight: auto, $sprite: false, $sprite-posx: 0, $sprite-posy: 0, $sprite-width: 0, $sprite-height: 0)
  display: inline-block
  background-image: image-url('#{$path}.#{$filetype}')
  background-repeat: $repeat
  width: $rwidth
  height: $rheight
  @if $sprite
    background-position-x: -($sprite-posx / 2)
    background-position-y: -($sprite-posy / 2)
  @media all and (-webkit-min-device-pixel-ratio : 1.5)
    background-image: image-url('#{$path}@2x.#{$filetype}')
    background-repeat: $repeat
    @if $sprite
      background-position-x: -($sprite-posx)
      background-position-y: -($sprite-posy)
      background-size: ($sprite-width / 2) ($sprite-width / 2)
      background-size: $rwidth $rheight

Here's my custom css output:!('app/assets/images/us_sprite', :nocomments => 'true', :output_style => 'app/assets/stylesheets/sprites/us_sprite.css.sass', :output_image => "app/assets/images/compiled/us_sprite@2x.png") do |images|
      #Writing SASS, mostly done with mixin retina_url() do |image_name, image_data|
      ".#{image_name}\n\t@include retina_url(compiled/us_sprite, png, no-repeat, #{image_data[:width] / 2}px, #{image_data[:height] / 2}px, true, #{images[:cssx]}px, #{images[:cssy]}px)"
Copy link

@ANTON072 ANTON072 commented Jun 1, 2013

It's great!!!!!!

Copy link

@ryana ryana commented May 2, 2014

Any thoughts on this? I'm surprised this thread has been stale for so long. I would have it would be taken care of, or a reason to not do it would have been discovered

Copy link

@keithchu keithchu commented May 3, 2014

@matsuodesign I'm using to grab the image width of the 2x sprite.

After that, it's just background-size: (image-width("compiled/us_sprite@2x.png") / 2) auto.

Copy link

@keithchu keithchu commented May 3, 2014

FYI, @matsuodesign's workaround is working for me.

Here's my configuration if it helps. I'm using to grab the width of the output 2x sprite. Also, the +respond-to($hidpi) is just a helper for targeting @media screen and (-webkit-max-device-pixel-ratio: 1.5), screen and (max-resolution: 1.5dppx).

                         :output_style => 'app/assets/stylesheets/_sprites-2x.sass.erb',
                         :output_image => 'app/assets/images/sprites/sprites@2x.png',
                         :selector => '.icon-2x-') do |images| do |image_name, image_data|
    ".icon-2x-#{image_name}\n\t@include hidpi-sprite(" +
    "'sprites/sprites@2x.png', " +
    "#{image_data[:cssw]}px, " +
    "#{image_data[:cssh]}px, " +
    "#{image_data[:cssx]}px, " +


// _icons.sass
=icon($sprite-name: null, $image-name: null)
    @extend .icon-2x-#{$sprite-name}_#{$image-name}
=hidpi-sprite($path, $width: 0, $height: 0, $x: auto, $y: auto)
  background-image: image-url('#{$path}')
  background-repeat: no-repeat
  background-position: ($x / -2) ($y / -2)
  background-size: (image-width("sprites/sprites@2x.png") / 2) auto
  height: $height / 2
  width: $width / 2

// usage:
    +icon("social", "facebook-hover")
Copy link

@sethjeffery sethjeffery commented Apr 21, 2016

Hi guys, I understand this thread is 2 years old but it's still open so in case others are searching like me, here is the method I am using that doesn't rely on rails-sass-images. It makes an assumption (seems to be correct) that the generated sprite file won't have extra padding around the sprites.!('app/assets/images/sprites/2x') do |images|

  # Find the max right-most point of any sprite in the list.
  # This must therefore be the image width.
  image_width  ={|data| data[:x] + data[:width]}.max

  # The rest is standard issue, now that we know the background size. do |name, data|
      .icon-2x-#{name} {
        width: #{data[:width] / 2}px #{data[:height] / 2}px;
        background: image-url(sprites/sprites@2x.png) #{data[:x] / -2}px #{data[:y] / -2}px no-repeat;
        background-size: #{image_width / 2}px auto;

Updated 18th April 2017

Copy link

@masterkain masterkain commented Feb 12, 2017

hello, in the proposed solution I find that data[:w] is nil, both with chunkypng and rmagick. any solution to that?

Copy link

@nburwell nburwell commented Apr 14, 2017

@masterkain looks like the data is now data[:width] and data[:height]

@sethjeffery any chance you could update your example block of code with the updated keys from the images hash?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
9 participants