Last Updated: February 25, 2016
·
8.14K
· kkiger

Implementing Glyph Icons with Angular

Read the backstory or jump straight to the goods by scrolling down to "Process of Implementation"…

In my team's latest project, we used a custom glyph icon set for the first time. This was especially cool to me because, back around 2003-2006, I was doing all things branding and web for a snowboard camp, and icons were a big part of our branding efforts. Each year, the camp would run with an entirely new aesthetic, which was awesome because it provided a fast feedback loop. Back then it was hard to use a lot of images on a page because it slowed everything down so much, but we learned that icons were incredibly valuable in an aesthetic. Icons were huge for brand identity. So, I was excited when part of my role in this latest project was to get to work on the implementation of glyph icons.

To see icons at work in branding, check out these resources. The first two are lists of websites where icons are employed as a key component of the business image and really help define the aesthetic. The second two are about glyphs.

First, the answer to the big question - Why would you want to use a glyph icon? Here are a few reasons:

  • Glyph-icons are lightweight and responsive
  • You can use CSS to change an icon’s size, alignment, and color
  • You can just as easily add drop shadows or borders to all your glyph-icons as you can to just one
  • No more opening Photoshop all the time
  • Glyph icons are easy to animate

*** If you want to get a cool idea of all the things you can do with an icon, check out Bootstrap’s FontAwesome:
http://fortawesome.github.io/Font-Awesome/examples/ ***

PROCESS OF IMPLEMENTATION:

What we did and why we did it...

  • First, our designer made us an icon set using http://fontastic.me/
  • The file set included a stylesheet and icon maps for all the browsers.
  • Then we put those files in our project and made sure to import the stylesheet to our main LESS file
  • Then we modified the font stylesheet to have the CSS that we thought would be best for our project. It was mainly just the font size that we changed. We realized it didn't make sense to set line height there because different places needed different line heights for centering.

To get our first glyph showing up on the page, we simply referenced the glyph as a class in our html document. Ex:

<i class="fa fa-whatsapp"></i>

It is best practice to put glyph icons on i-classes versus divs or spans. An i-class is an inline element, just like a span. Really, though, it's just convention. Since using an i-tag for italics has gone out of fashion, the i-tag was appropriated for glyph icons because the "i" conveniently could stand for the "i" in "icon".

Then, if we wanted to style the glyph for the context, all we had to do was add a second classname to the i-class.

<i class="fa fa-whatsapp journal-glyph-icon-round"></i>

More exciting multi-purposing - We wanted the icons to be round and have a colored backdrop, so we wrote a mixin that we could use on multiple icons. The mixin gave us the roundness and alignment, then we set the color differently in different places.

.RoundIcon (@diameter) {
  border-radius: @diameter;
  -moz-border-radius: @diameter;
  -webkit-border-radius: @diameter;
  margin-left: (@diameter /2) * -1px;
  height: @diameter;
  width: @diameter;
  background-position: center center;
  z-index: 100;
  display: inline;
  vertical-align: middle;
  overflow: hidden;
  text-align: center;
  position: absolute;
  top:50%;
  margin-top: (@diameter/2) * -1px;
}

In our case, the next thing that we wanted was to be able to have different icons show up based on what was being pulled from the database. For example, when a user selected "email", we wanted an email icon to show up, and when a user selected "phone", we wanted a phone icon to show up. So, in our database, we assigned a slug to each of the possible communication modes (email, phone, fax, in-person, etc). To create that functionality, we used Angular interpolation. (*see update at bottom)

Here's what that looked like in the view (aka our html template):

<i class="{{ journalEntry.modeIcon() }}"></i>

This inserts the results of the modeIcon function into the CSS tag. Once the function is performed, then the line effectively reads as follows (because the function sends a string to the class).

<i class="rubiconglyph-circle-slug"></i>

This string references the class rule and, hooray, we have the corresponding style!

.mode-icon i:before {
 border-radius: ((@modeIconSize / 2) * 1px);
 border: (@modeIconSize * .07) * 1px solid @border-color-light;
 font-size: (@modeIconSize * .75) * 1px;
 line-height: @modeIconSize;
}

Now we can trace that function back to the model and check out the javascript code:

  modeIcon: function() {
    if (!this.mode || !this.mode.slug) {
      return "";
    }
    return "rubiconglyph-circle" + "-" + this.mode.slug ;
  }
});

Basically this code says, if there isn't a mode, or there isn't a slug for the mode, then return an empty string (that way the class will be blank). Otherwise, attach "this.mode.slug" to the end of "rubiconglyph-circle".

So, what happens if you want the color of the glyph to also change at will based on the data? Ha, we can do that, too. Check out the pro-tip, "Returning Strings to Make Some CSS Happen." You might also enjoy, <a href="https://coderwall.com/p/mxk-gw/if-there-is-no-profile-image-show-a-placeholder-glyph-icon-using-angular?p=1&q=author%3Akkiger">"If There is No Profile Image, Show a Placeholder Glyph-Icon using Angular"</a>

*Angular interpolation is not ideal. Here's a plunker to show why. It falls into a digest cycle error quite rapidly. http://plnkr.co/edit/F7HEX4bybWiHVqMNyVKg?p=preview An alternative - Set up default values within the controller so that at any given time the DOM only has to reference an object as opposed to call a function. From there, user interaction would trigger a function reference that would update the state of that object.