If you want icons for buttons, links, info text or something else on your website the best way is to use an icon sprite as background image. So just one image for all is needed. But sometimes it’s a mess to handle all the different pixel positions. Lets get SASS do the work.
1. Step: The icon sprite
Important for the sprite are the grid and the alignment of every single icon. At this example the grid is 20x20px.
2. Step: Get the right icon position
To get the position of every icon a SASS function is used.
@function get_icn_bg_pos ($pos-x: 0, $state: default) {
$pos-y: 0;
$raster-x: 20;
$raster-y: 20;
@if $state == default {
$pos-y: 0;
} @else if $state == link {
$pos-y: 0;
} @else if $state == visited {
$pos-y: 0;
} @else if $state == focus {
$pos-y: 1;
} @else if $state == hover {
$pos-y: 1;
} @else if $state == active {
$pos-y: 2;
} @else if $state == current {
$pos-y: 2;
} @else if $state == primary {
$pos-y: 2;
}
@return (-$raster-x * $pos-x) + px (-$raster-y * $pos-y) + px;
}
This function returns the pixel for the background position dependent on the icon position in the sprite and the state of the element (link for example). Possible states are link, visited, focus, hover, active and current for links and default and primary for non active elements. The grid is defined in the function. With icon position and grid it’s easy to calculate the top / left pixel position.
3. Step: The main CSS
Just two classes for icons before or after the element content.
.icn_before:before, .icn_after:after {
content: '';
height: 20px;
width: 20px;
display: inline-block;
vertical-align: middle;
background: url('images/icon_sprite.png') no-repeat;
}
4. Step: Generate the single icon CSS
At first a list of all icons in the right order:
$icons: like, comments, love, message;
Finally just a little loop to generate the CSS for all states:
$i: 0;
@each $type in $icons {
.icn_before.#{$type}:before, .icn_after.#{$type}:after {
background-position: get_icn_bg_pos($i);
}
a.icn_before.#{$type}:link:before, a.icn_after.#{$type}:link:after {
background-position: get_icn_bg_pos($i, link);
}
a.icn_before.#{$type}:visited:before, a.icn_after.#{$type}:visited:after {
background-position: get_icn_bg_pos($i, hover);
}
a.icn_before.#{$type}:focus:before, a.icn_after.#{$type}:focus:after {
background-position: get_icn_bg_pos($i, focus);
}
a.icn_before.#{$type}:hover:before, a.icn_after.#{$type}:hover:after {
background-position: get_icn_bg_pos($i, hover);
}
a.icn_before.#{$type}:active:before, a.icn_after.#{$type}:active:after {
background-position: get_icn_bg_pos($i, active);
}
.current.icn_before.#{$type}:before, .current.icn_after.#{$type}:after {
background-position: get_icn_bg_pos($i, current);
}
.primary.icn_before.#{$type}:before, .primary.icn_after.#{$type}:after {
background-position: get_icn_bg_pos($i, primary);
}
$i: $i + 1;
}
$i is the position of the icon in the list as a number.
5. Step: The HTML markup
<span class="icn_before message primary">100</span>
Now, if a new icon is needed, just replace the icon sprite and change the $icons list.
That’s all!
Again thanx to Kosmar for brainstorming.