Icons in Rails


While working on the redesign of the SwissICT Salärstudie I came across the challenge of adding the icons used in the figma design into the project. I've looked through various projects of ours to see how Icons usually get implemented. It turns out, that there is no such thing as the "normal" way of adding icons. Here are some of the options I found or came up with:

Adding them as images

Setting them as background images of pseudo-elements

Font Awesome

Glyphicons

Google icons/symbol (the intended way)

Include the google material icons (or symbols for more customizability) using the cdn link. Then either enter the Unicode codepoint or write the icon name inside an element with a specific class: Material Symbols guide  |  Google Fonts  |  Google for Developers

Google icons/symbols (the better way)

First download the Font from the material symbols Github repo
Then write a helper, that inserts the material symbols codepoints. For further customization, use CSS classes:

// _material_symbol.scss

.material-symbol {  
  display: inline-block;  
  width: 1em;  
  height: 1em;  
  
  font-family: "Material Symbols Outlined", sans-serif;  
  font-size: $icon-md;  
  line-height: 1;  
  font-style: normal;  
  font-variation-settings: 'wght' 200, 'opsz' $icon-md;  
  
  &.is-small {  
    font-size: $icon-sm;  
    font-variation-settings: 'wght' 300, 'opsz' $icon-sm;  
  }  
  
  &.has-fill {  
    font-variation-settings: 'FILL' 1;  
  }  
}
# application_helper.rb

module ApplicationHelper
	ICON_CODE_POINTS = {  
	  check: "\ue5ca", close: "\ue5cd", delete: "\ue872", edit: "\ue3c9"
	}.freeze  
  
	def icon(name, config = {class: ""})  
	  class_name = class_names(config[:class], "material-symbol")  
	  tag.i ICON_CODE_POINTS[name], "aria-hidden": true, class: class_name  
	end
end
# example.html.erb
<%= icon :close %>
<%= icon :delete, class_name: "is-small has-fill" %>

This approach has the problem that the whole font has to be loaded...

Using pseudo-elements

It is also quite nice to set the icons in pseudo-elements based on the class, so all the frontend stuff stays completely in the views/css (and also if you want to use it in plain html projects).

<!--index.html-->

<i class="icon icon-edit"></i>