Icons

THE BUTTER

  • .symbol
  • .symbolAfter
  • .icon-[value]
  • .icon-inline
  • .liga
  • [data-icon]

Icons are very diverse, and special to every project. The only thing that a framework should provide for icons, is a set of functions to use in LESS or SCSS. The following are the definitions and LESS functions in this framework, and how to make use of them.

Don't just use a ready made collection of fonts, generate your own icon font using online tools like icomoon, or fontello.

Variables

Generate an icon font of your favorite, per-project icons, then use these variables to make a single rule ready to use .symbol.

// If set to true, the rules for the icons are generated. 
@enable-icon-font: true;

// the icon file name (provide ttf, woff, and svg)
@icon-font: 'vpicons';

// path relative to css file for the folder where fonts are located
@font-url: '../fonts/';

// for inline icons that need space to the right, how much space?
@icon-inline-margin: 1rem;

Symbol definition

The symbol definition in full, in the framework is this:

.symbolDef() {
    font-family: @icon-font;
    text-transform: none;
    font-style: normal;
    font-weight: normal;
    font-variant: normal;
    display: inline-block;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    speak: none;
    font-smooth: always;
    /* Enable Ligatures */
    letter-spacing: 0;
    -webkit-font-feature-settings: 'liga';
    -moz-font-feature-settings: 'liga=1';
    -moz-font-feature-settings: 'liga';
    -ms-font-feature-settings: 'liga' 1;
    -o-font-feature-settings: 'liga';
    font-feature-settings: 'liga';
    -webkit-font-variant-ligatures: discretionary-ligatures;
    font-variant-ligatures: discretionary-ligatures;
    /* ligatures? */
    content: attr(data-icon);
}

Extend

To extend the defintion in your project, add it as follows (LESS merges the two definitions into one):

.symbolDef() {
     vertical-align: middle;
	 font-size: 150%;
	 line-height: 1;
}

Define

Now add your icons using .icon() functions (handy but not necessary)

// this produces .icon-place class ready to use
.icon(icon-place,"\e900");

Also, to make the same variables usable in your less file, do as I do:

// create a variable @icon-place to use in LESS
@icon-place: "\e900";
	
// then create icon-place rule
.icon(icon-place,@icon-place);

Use

In HTML, combine the class name with .symbol like this (inside a button as an example)

<button class="btn">
	<span class="symbol icon-place"></span>
</button>

If appears inline and you want more space to the right of the icon (this is rare if you setup the icon padding correctly in the icon font).

<span class="symbol icon-place icon-inline">Location</span>
Location

If you have ligatures setup, use .liga class, or pass it to data-icon attribute:

<i class="liga">place</i> ligature location
<span class="symbol" data-icon="place">using data-icon</span>
<span class="symbolAfter" data-icon="place">using symbolAfetr and data-icon</span>
			
place ligature location
using data-icon
using symbolAfetr and data-icon

LESS functions

Using icon class names directly in HTML is one way, using them in LESS is another fine-tuned way, here are some LESS functions you can use.

// .getIcon(value) makes the rule ready for use with :before
.search-icon {
	.getIcon(@icon-search);
}

// pass "after" as a second argument to use :after instead
.next-icon {
	.getIcon(@icon-right, "after");
}

// use .changeIcon(value) to overwrite content only of :before
.expand-icon {
	color: @green;
	.getIcon(@icon-down);

	&.expanded {
		.changeIcon(@icon-up);
	}
}

// pass "after" as a second argument to overwrite content of :after 
.collapse-icon {
	color: @red;
	.getIcon(@icon-up, "after");

	&.collapsed {
		.changeIcon(@icon-down, "after");
	}
}

// and use .displayIcon(value) directly in a pseudo element
.fancy-icon {
	position: relative;
	text-align: center;
	&:before {
		margin: auto;
		border-radius: 1000px;
		display: flex;
		justify-content: center;
		align-items: center;
		width: 50px;
		height: 50px;
		color: @white;
		background-color: fade(@blue, 50);
		.displayIcon(@icon-place);
	}

}

To use in HTML:

<span class="search-icon"></span> Search
<span class="next-icon">Icon after</span>
<div class="expand-icon">Expand</div>...
<div class="expand-icon expanded">Expanded</div>
<div class="collapse-icon">Collapse</div>... 
<div class="collapse-icon collapsed">Collapsed</div>
<div class="fancy-icon">.fancy-icon</div>
  • Search
  • Icon after
  • Expand
    ...
    Expanded
  • Collapse
    ...
  • .fancy-icon

A note about RTL

If you use an automatic mirror task to generate your RTL, you need to also take note of icons with direction, and manually mirror them. Each left icon, will hold the right character, and each right icon will hold the left character, the class names used in HTML should not change.

.icon(icon-left, "\e903");
.icon(icon-right,"\e904");

// in RTL file
.icon(icon-left, "\e904");
.icon(icon-right,"\e903");