Recently Dan asked me to get new icons for Raleigh, New York City, and Austin added to some of our landing pages.
Once I created the icons, I checked out the site to put them in below the offices that have already been on the marketing pages. It looked like this:
&#boston:after {
background: url('/img/icon_boston.png') no-repeat center top;
}
&#denver:after {
background: url('/img/icon_denver.png') no-repeat center 42px;
}
&#sanfran:after {
background: url('/img/icon_sf.png') no-repeat center 54px;
}
&#philly:after {
background: url('/img/icon_philly.png') no-repeat center 42px;
}
&#stockholm:after {
background: url('/img/icon_stockholm.png') no-repeat center 45px;
}
@media
(-webkit-min-device-pixel-ratio: 2),
(min-resolution: 192dpi) {
&#boston:after {
background: url('/img/icon_boston@2x.png') no-repeat center top;
background-size: 97px 112px;
}
&#denver:after {
background: url('/img/icon_denver@2x.png') no-repeat center 42px;
background-size: 160px 71px;
}
&#sanfran:after {
background: url('/img/icon_sf@2x.png') no-repeat center 54px;
background-size: 210px 59px;
}
&#philly:after {
background: url('/img/icon_philly@2x.png') no-repeat center 42px;
background-size: 66px 85px;
}
&#stockholm:after {
background: url('/img/icon_stockholm@2x.png') no-repeat center 45px;
background-size: 93px 67px;
}
}
Look at all that repetition! That’s almost 50 lines of Sass. Adding new offices to that list would add even more to the repetition. I wanted to get rid of all the repetition and make it really easy to add new offices if we need to in the future. I started off by putting all our offices in a variable then looped through them and used some interpolation to assign the right icon to the right city.
$offices: boston, denver, sanfran, philly, stockholm, new-york, raleigh, austin;
@each $city in $offices {
&##{$city}:after {
background-image: url('/img/icon_#{$city}.png');
background-position: center 42px;
background-repeat: no-repeat;
@if $city == 'boston' {
background-position: center top;
}
@if $city == 'new-york' {
background-position: center top;
}
@if $city == 'sanfran' {
background-position: center 54px;
}
@if $city == 'austin' {
background-position: center 24px;
}
@if $city == 'raleigh' {
background-position: center 28px;
}
}
@include hirez-screen {
&##{$city}:after {
background-image: url('/img/icon_#{$city}@2x.png');
background-size: 97px 112px;
}
}
}
There’s still some repetition in that loop with different positioning for each of the icons. Each of the cities that I am overriding the position is getting two lines of positioning when one will do. I figured that there had to be a better way to handle to the differing positions in Sass too.
Luckily for me, Sass 3.3 was released with Sass maps while I was designing the new icons. Connie suggested I try putting the offices into a map with their respective y-position. I went back to my list of offices and converted it to a map.
$offices: (boston: top, denver: 42px, sanfran: 54px, philly: 42px, stockholm: 42px, new-york: top, raleigh: 28px, austin: 24px);
Then went back to my @each loop and changed it around to account for the map.
@each $city, $y-position in $offices {
&##{$city}:after {
background-image: url('/img/icon_#{$city}.png');
background-position: center $y-position;
background-repeat: no-repeat;
}
@include hirez-screen {
&##{$city}:after {
background-image: url('/img/icon_#{$city}@2x.png');
background-size: 97px 112px;
}
}
}
Now we’re talking. It’s really compact and there’s no repetition.