Created
September 17, 2014 19:00
-
-
Save maxbeatty/f5ad269ff8a920e3ad24 to your computer and use it in GitHub Desktop.
Adventures in Spriting
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$lowRes: sprite-map("chat/sprites/*.png") | |
$highRes: sprite-map("chat/sprites-retina/*.png") | |
.chat-icon | |
margin-right: 10px | |
cursor: pointer | |
+sprite-background(message-icon, $lowRes, $highRes) | |
&:hover | |
+sprite-background(message-icon_hover, $lowRes, $highRes) | |
&.unread | |
+sprite-background(unread-message-icon, $lowRes, $highRes) | |
&:hover | |
+sprite-background(unread-message-icon_hover, $lowRes, $highRes) | |
&:active, | |
&.active | |
+sprite-background(unread-message-icon_active, $lowRes, $highRes) | |
tr | |
&.chat-open | |
outline: 1px $pale-blue solid | |
.chat-icon | |
+sprite-background(unread-message-icon, $lowRes, $highRes) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Sprites with retina support | |
// needs to be passed in the name of the class you are trying to grab | |
// and the sprite location for low and retina res | |
=sprite-background($name, $sprites, $sprites-retina) | |
background-repeat: no-repeat | |
display: block | |
height: image-height(sprite-file($sprites, $name)) | |
width: image-width(sprite-file($sprites, $name)) | |
$width: image-width(sprite-file($sprites, $name)) | |
// LOW RES | |
// Media Query: wrapping both sprite maps in a query ensures only one is downloaded | |
@media only screen and ( -webkit-max-device-pixel-ratio: 1), only screen and ( max__moz-device-pixel-ratio: 1), only screen and ( -o-max-device-pixel-ratio: 1/1), only screen and ( max-device-pixel-ratio: 1), only screen and ( max-resolution: 96dpi), only screen and ( max-resolution: 1.0dppx) | |
background-image: sprite-url($sprites) | |
background-position: sprite-position($sprites, $name) | |
// RETINA RES | |
// Media Query: wrapping both sprite maps in a query ensures only one is downloaded | |
@media only screen and ( -webkit-min-device-pixel-ratio: 1.1), only screen and ( min__moz-device-pixel-ratio: 1.1), only screen and ( -o-min-device-pixel-ratio: 11/10), only screen and ( min-device-pixel-ratio: 1.1), only screen and ( min-resolution: 97dpi), only screen and ( min-resolution: 1.1dppx) | |
// 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 | |
+background-size($width auto) | |
background-image: sprite-url($sprites-retina) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.chat-icon { | |
margin-right: 10px; | |
cursor: pointer; | |
background-repeat: no-repeat; | |
display: block; | |
height: 20px; | |
width: 21px | |
} | |
@media only screen and (-webkit-max-device-pixel-ratio: 1), only screen and (max__moz-device-pixel-ratio: 1), only screen and (-o-max-device-pixel-ratio: 1 / 1), only screen and (max-device-pixel-ratio: 1), only screen and (max-resolution: 96dpi), only screen and (max-resolution: 1dppx) { | |
.chat-icon { | |
background-image: url('/images/chat/sprites-s41fc7c6c72.png'); | |
background-position: 0 0 | |
} | |
} | |
@media only screen and (-webkit-min-device-pixel-ratio: 1.1), only screen and (min__moz-device-pixel-ratio: 1.1), only screen and (-o-min-device-pixel-ratio: 11 / 10), only screen and (min-device-pixel-ratio: 1.1), only screen and (min-resolution: 97dpi), only screen and (min-resolution: 1.1dppx) { | |
.chat-icon { | |
-moz-background-size: 21px auto; | |
-o-background-size: 21px auto; | |
-webkit-background-size: 21px auto; | |
background-size: 21px auto; | |
background-image: url('/images/chat/sprites-retina-s0be810e70a.png') | |
} | |
} | |
.chat-icon:hover { | |
background-repeat: no-repeat; | |
display: block; | |
height: 20px; | |
width: 21px | |
} | |
@media only screen and (-webkit-max-device-pixel-ratio: 1), only screen and (max__moz-device-pixel-ratio: 1), only screen and (-o-max-device-pixel-ratio: 1 / 1), only screen and (max-device-pixel-ratio: 1), only screen and (max-resolution: 96dpi), only screen and (max-resolution: 1dppx) { | |
.chat-icon:hover { | |
background-image: url('/images/chat/sprites-s41fc7c6c72.png'); | |
background-position: 0 -20px | |
} | |
} | |
@media only screen and (-webkit-min-device-pixel-ratio: 1.1), only screen and (min__moz-device-pixel-ratio: 1.1), only screen and (-o-min-device-pixel-ratio: 11 / 10), only screen and (min-device-pixel-ratio: 1.1), only screen and (min-resolution: 97dpi), only screen and (min-resolution: 1.1dppx) { | |
.chat-icon:hover { | |
background-position: 0 -20px; | |
-moz-background-size: 21px auto; | |
-o-background-size: 21px auto; | |
-webkit-background-size: 21px auto; | |
background-size: 21px auto; | |
background-image: url('/images/chat/sprites-retina-s0be810e70a.png') | |
} | |
} | |
.chat-icon.unread { | |
background-repeat: no-repeat; | |
display: block; | |
height: 20px; | |
width: 21px | |
} | |
@media only screen and (-webkit-max-device-pixel-ratio: 1), only screen and (max__moz-device-pixel-ratio: 1), only screen and (-o-max-device-pixel-ratio: 1 / 1), only screen and (max-device-pixel-ratio: 1), only screen and (max-resolution: 96dpi), only screen and (max-resolution: 1dppx) { | |
.chat-icon.unread { | |
background-image: url('/images/chat/sprites-s41fc7c6c72.png'); | |
background-position: 0 -40px | |
} | |
} | |
@media only screen and (-webkit-min-device-pixel-ratio: 1.1), only screen and (min__moz-device-pixel-ratio: 1.1), only screen and (-o-min-device-pixel-ratio: 11 / 10), only screen and (min-device-pixel-ratio: 1.1), only screen and (min-resolution: 97dpi), only screen and (min-resolution: 1.1dppx) { | |
.chat-icon.unread { | |
background-position: 0 -40px; | |
-moz-background-size: 21px auto; | |
-o-background-size: 21px auto; | |
-webkit-background-size: 21px auto; | |
background-size: 21px auto; | |
background-image: url('/images/chat/sprites-retina-s0be810e70a.png') | |
} | |
} | |
.chat-icon.unread:hover { | |
background-repeat: no-repeat; | |
display: block; | |
height: 20px; | |
width: 21px | |
} | |
@media only screen and (-webkit-max-device-pixel-ratio: 1), only screen and (max__moz-device-pixel-ratio: 1), only screen and (-o-max-device-pixel-ratio: 1 / 1), only screen and (max-device-pixel-ratio: 1), only screen and (max-resolution: 96dpi), only screen and (max-resolution: 1dppx) { | |
.chat-icon.unread:hover { | |
background-image: url('/images/chat/sprites-s41fc7c6c72.png'); | |
background-position: 0 -80px | |
} | |
} | |
@media only screen and (-webkit-min-device-pixel-ratio: 1.1), only screen and (min__moz-device-pixel-ratio: 1.1), only screen and (-o-min-device-pixel-ratio: 11 / 10), only screen and (min-device-pixel-ratio: 1.1), only screen and (min-resolution: 97dpi), only screen and (min-resolution: 1.1dppx) { | |
.chat-icon.unread:hover { | |
background-position: 0 -80px; | |
-moz-background-size: 21px auto; | |
-o-background-size: 21px auto; | |
-webkit-background-size: 21px auto; | |
background-size: 21px auto; | |
background-image: url('/images/chat/sprites-retina-s0be810e70a.png') | |
} | |
} | |
.chat-icon.unread:active,.chat-icon.unread.active { | |
background-repeat: no-repeat; | |
display: block; | |
height: 20px; | |
width: 21px | |
} | |
@media only screen and (-webkit-max-device-pixel-ratio: 1), only screen and (max__moz-device-pixel-ratio: 1), only screen and (-o-max-device-pixel-ratio: 1 / 1), only screen and (max-device-pixel-ratio: 1), only screen and (max-resolution: 96dpi), only screen and (max-resolution: 1dppx) { | |
.chat-icon.unread:active,.chat-icon.unread.active { | |
background-image: url('/images/chat/sprites-s41fc7c6c72.png'); | |
background-position: 0 -60px | |
} | |
} | |
@media only screen and (-webkit-min-device-pixel-ratio: 1.1), only screen and (min__moz-device-pixel-ratio: 1.1), only screen and (-o-min-device-pixel-ratio: 11 / 10), only screen and (min-device-pixel-ratio: 1.1), only screen and (min-resolution: 97dpi), only screen and (min-resolution: 1.1dppx) { | |
.chat-icon.unread:active,.chat-icon.unread.active { | |
background-position: 0 -60px; | |
-moz-background-size: 21px auto; | |
-o-background-size: 21px auto; | |
-webkit-background-size: 21px auto; | |
background-size: 21px auto; | |
background-image: url('/images/chat/sprites-retina-s0be810e70a.png') | |
} | |
} | |
tr.chat-open { | |
outline: 1px #7ab9f9 solid | |
} | |
tr.chat-open .chat-icon { | |
background-repeat: no-repeat; | |
display: block; | |
height: 20px; | |
width: 21px | |
} | |
@media only screen and (-webkit-max-device-pixel-ratio: 1), only screen and (max__moz-device-pixel-ratio: 1), only screen and (-o-max-device-pixel-ratio: 1 / 1), only screen and (max-device-pixel-ratio: 1), only screen and (max-resolution: 96dpi), only screen and (max-resolution: 1dppx) { | |
tr.chat-open .chat-icon { | |
background-image: url('/images/chat/sprites-s41fc7c6c72.png'); | |
background-position: 0 -40px | |
} | |
} | |
@media only screen and (-webkit-min-device-pixel-ratio: 1.1), only screen and (min__moz-device-pixel-ratio: 1.1), only screen and (-o-min-device-pixel-ratio: 11 / 10), only screen and (min-device-pixel-ratio: 1.1), only screen and (min-resolution: 97dpi), only screen and (min-resolution: 1.1dppx) { | |
tr.chat-open .chat-icon { | |
background-position: 0 -40px; | |
-moz-background-size: 21px auto; | |
-o-background-size: 21px auto; | |
-webkit-background-size: 21px auto; | |
background-size: 21px auto; | |
background-image: url('/images/chat/sprites-retina-s0be810e70a.png') | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$icon: 20px | |
%productNavSprite | |
display: block | |
background-repeat: no-repeat | |
background-size: sprite-width($sprite-product-nav) sprite-height($sprite-product-nav) | |
@include lodpi | |
background-image: sprite-url($sprite-product-nav) | |
@include hidpi | |
background-image: sprite-url($sprite-product-nav_2x) | |
@mixin soup($product) | |
$p: bell- + $product | |
background-position: sprite-position($sprite-product-nav, $p) | |
&:hover | |
background-position: sprite-position($sprite-product-nav, $p + _hover) | |
.mProductNav-notifications-trigger | |
width: $icon | |
height: $icon | |
cursor: pointer | |
@extend %productNavSprite | |
background-position: sprite-position($sprite-product-nav, bell) | |
&:hover | |
background-position: sprite-position($sprite-product-nav, bell_hover) | |
// TODO: verify this psuedo-code soup | |
.mProductNav--advertisers &.is-unread | |
@include soup(ifa) | |
.mProductNav--publishers &.is-unread | |
@include soup(ifp) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@mixin _dpi($ratio: 1) | |
@media (-webkit-min-device-pixel-ratio: $ratio), (min--moz-device-pixel-ratio: $ratio), (-o-min-device-pixel-ratio: $ratio), (min-device-pixel-ratio: $ratio), (min-resolution: $ratio * 96dpi), (min-resolution: $ratio * 1dppx) | |
@content | |
// "retina" aka "2x" | |
@mixin hidpi | |
// Default pixel ratio: 1.3 to support Nexus 7 | |
// Depending on your target, you may want to set a | |
// more suitable minimum pixel ratio here: | |
// http://bjango.com/articles/min-device-pixel-ratio/ | |
$hidpi-min-pixel-ratio: 1.3 !default | |
@include _dpi($hidpi-min-pixel-ratio) | |
@content | |
// everyday resolution useful to avoid downloading both normal and retina assets | |
@mixin lodpi | |
@include _dpi() | |
@content |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.mProductNav-brand,.mProductNav-notifications-trigger { | |
display: block; | |
background-repeat: no-repeat; | |
background-size: 69px 204px | |
} | |
@media (-webkit-min-device-pixel-ratio: 1), (min--moz-device-pixel-ratio: 1), (-o-min-device-pixel-ratio: 1), (min-device-pixel-ratio: 1), (min-resolution: 96dpi), (min-resolution: 1dppx) { | |
.mProductNav-brand,.mProductNav-notifications-trigger { | |
background-image: url('images/sprite/product-nav-sedc09af347.png') | |
} | |
} | |
@media (-webkit-min-device-pixel-ratio: 1.3), (min--moz-device-pixel-ratio: 1.3), (-o-min-device-pixel-ratio: 1.3), (min-device-pixel-ratio: 1.3), (min-resolution: 124.8dpi), (min-resolution: 1.3dppx) { | |
.mProductNav-brand,.mProductNav-notifications-trigger { | |
background-image: url('images/sprite/product-nav_2x-sdfb2de34c3.png') | |
} | |
} | |
.mProductNav-notifications-trigger { | |
width: 20px; | |
height: 20px; | |
cursor: pointer; | |
background-position: 0 -84px | |
} | |
.mProductNav-notifications-trigger:hover { | |
background-position: 0 -104px | |
} | |
.mProductNav--advertisers .mProductNav-notifications-trigger.is-unread { | |
background-position: 0 0 | |
} | |
.mProductNav--advertisers .mProductNav-notifications-trigger.is-unread:hover { | |
background-position: 0 -21px | |
} | |
.mProductNav--publishers .mProductNav-notifications-trigger.is-unread { | |
background-position: 0 -42px | |
} | |
.mProductNav--publishers .mProductNav-notifications-trigger.is-unread:hover { | |
background-position: 0 -63px | |
} |
One of the benefits of my approach vs Max's approach is my approach is entirely reusable without a bunch of extra boilerplate code. Simply use the mixin with a sprite map. The extra CSS bloat is something that I would like to fix, and is partially due to how I am reusing the mixin.
Max's approach obviously saves on css output and is going to be more performant. I think if Max's can be made a bit more reusable as a single line mixin, it'd be the best of both worlds.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It's been awhile since I've worked with sprites in Compass and retina supports is a new twist. The two implementations aren't apples to apples, but I think fair enough. Jeff had to support an active state. I had to support two brand variations. Ultimately, from a quick eyeballing, it looks like more or less the same amount of Sass produced 1/3 the CSS.
What's good from both approaches?
What isn't great from both approaches?
Is it fine they both do things differently?
Is there a pattern we want to take forward and reuse?
Learn. Learn. Learn.