Hello everyone !
This is my first article on the UX-Republic blog and I will explain how I generate an iconfont from files SVG quickly and as unobtrusively as possible using Gulp.js.
Why?
Before using Gulp.js to generate an iconfont, I went through the service IcoMoon App.
It works very well but many steps are necessary before you see an icon appear on your browser:
- go to the page,
- import the SVGs (browse its files on your computer),
- select its icons,
- click on “Generate Font”,
- click on “Download”,
- unzip the archive,
- move font files,
- copy/paste the CSS.
And if something has been forgotten or the SVG file is not correct… you have to start all over again.
The purpose of this exercise carried out with Gulp.js is to make automatic the addition of an icon to its iconfont. That the only action to do is to move its SVG file into a folder and execute a single command in the terminal to start the generation of our iconfont (font and CSS).
Prerequisites
First of all you will have to install some tools on your computer to be able to generate your iconfont.
Node.js
Node.js is a network-oriented software platform. It allows the use of JavaScript elsewhere than in a web browser.
You need to download the installer and run it like installing any program. You can already do it by following the following link: https://nodejs.org/download/.
Gulp.js
Gulp.js is a program developed as its name suggests in JavaScript (extension .js). It is he who will allow us to carry out our tasks.
To install it as easily as possible, we will do it from the command line using a terminal.
Project configuration
Let's start by creating a folder in which we will put all the files and install the modules we will need to generate our iconfont.
Here is the structure I propose:
iconfont_project
\css
\fonts
\custom
\icons
\scss
\templates
_icons.scss
_icons.scss
fonts.scss
main.scss
gulpfile.js
index.html
Open a terminal and navigate to the project folder.
You have to create a file package.json which will aim to gather all the information of the project (name, version, modules used, etc.).
To do this, type the following command:
npm init
Install Gulp.js
To install Gulp.js, type the command:
npm install --save-dev gulp
Install Gulp.js modules
We need several modules for our project:
- gulp sass : plug-in Sass (CSS preprocessor),
- gulp-icont : create SVG/TTF/EOT/WOFF files from SVG files,
- gulp-consolidate : template engine,
- lodash : gulp-consolidate dependency.
To install them, type this command:
npm install --save-dev gulp-sass gulp-iconfont gulp-consolidate lodash
You should see a new folder named “node_modules” appear, this is where Gulp.js and its modules are installed.
Write the Gulpfile
The file gulpfile.js is the file where we will write our tasks that will be used to generate font files and CSS.
We start by calling our previously downloaded libraries:
var gulp = require('gulp')
, sass = require('gulp-sass')
, iconfont = require('gulp-iconfont')
, consolidate = require('gulp-consolidate');
We write our iconfont function (you will find the commented code on GitHub at the end of the article):
gulp.task('iconfont', function () {
gulp.src('icons/**/*.svg')
.pipe(iconfont({
fontName: 'custom'
, centerHorizontally: true
, normalize: true
, appendUnicode: true
}))
.on('glyphs', function (glyphs) {
gulp.src('scss/templates/_icons.scss')
.pipe(consolidate('lodash', {
glyphs: glyphs
, fontName: 'custom'
, fontPath: '../fonts/custom/'
, className: 'icon'
}))
.pipe(gulp.dest('scss'));
})
.pipe(gulp.dest('fonts/custom'));
});
A second function called “sass” to compile our CSS:
gulp.task('sass', function () {
gulp.src('scss/**/*.scss')
.pipe(sass({
indentWidth: 4
, outputStyle: 'expanded'
}))
.pipe(gulp.dest('css'));
});
Gulp.js requires a default function that should be named default:
gulp.task('default', ['sass'], function () {
gulp.watch('scss/**/*.scss', ['sass']);
});
In this function we execute the “sass” function then we tell Gulp.js to look if one of our Sass files is modified. If so, it will run the “sass” function again.
Creation of the template
The template is a Sass file in which we will put the variables of the information that we wrote in our gulpfile.js file, namely the name of our font, the path of our font files, etc.
We will also retrieve the table where the “code points” are stored. This is the code that will be inserted into the CSS content.
Please note: the script will take the name of the SVG you gave it.
Here is an example of what will be generated in CSS if I name my SVG file “myicon.svg”:
.icon-myicon:before {
content: "\E001";
}
We will write our template in the scss/templates folder.
Let's start by writing the @font-face that will call our iconfont:
@font-face {
font-family: '<%= fontName %>';
font-weight: normal;
font-style: normal;
src: url('<%= fontPath %><%= fontName %>.eot');
src: url('<%= fontPath %><%= fontName %>.woff2') format('woff2'),
url('<%= fontPath %><%= fontName %>.woff') format('woff'),
url('<%= fontPath %><%= fontName %>.ttf') format('truetype'),
url('<%= fontPath %><%= fontName %>.eot?#iefix') format('embedded-opentype');
}
Everything contained in “<%=” and “%>” is actually JavaScript code. "fontName" and "fontPath" are variables that take the parameters that we wrote in the "consolidate" method of our "iconfont" task located in our gulpfile.js.
We then write the main class in which we will call the font via font-family as well as the styles specific to the fonts which we initialize to the default value to override the styles which could be applied on the parent tags where our icon would be:
.<%= className %>[class^="<%= className %>-"],
.<%= className %>[class*=" <%= className %>-"] {
display: inline-block;
font-family: '<%= fontName %>';
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
font-style: normal;
font-variant: normal;
font-weight: normal;
line-height: 1;
text-transform: none;
}
The last two properties are used to trigger the effect Cleartype in order to have a better rendering by activating antialiasing.
We will then create a loop to build a map that we will name "icons".
A map is a data type in Sass that allows you to structure data by key / value pair.
$icons: (
<%= glyphs.map(function(glyph) {
return glyph.name + ': '\' + '\\' + glyph.unicode[0].charCodeAt(0).toString(16).toUpperCase() + ''\'
}).join(',\n ') %>
);
"glyphs" (JavaScript variable, see gulpfile.js file) is an array containing objects and for each of them we will execute a function that will return the name of the glyph (glyph.name) which is the name of the file SVG you gave it. These names will be the keys to the Sass map.
For the values of the map we return the code points (glyph.codepoint) that we convert into hexadecimal and that we transform into uppercase.
Once the map is generated, it gives this:
$icons: (
antenna: '\E001',
heart: '\E002'
);
And finally we create a loop (in Sass language this time) which will be used to read each element of our map and generate the CSS:
@each $name, $icon in $icons {
.<%= className %>-#{$name}:before {
content: $icon;
}
}
In the each loop, the first variable “name” contains the keys of the map and the second “icon” contains the values.
Then we write the CSS. In <%= className %> we will have the value “icon” (assigned in the gulpfile.js file).
#{$name} is our key with the class name.
$icon is our value with the dot code.
Why #{$name} and not just $name?
We write a variable inside a character string and we use here what we call thethe interpolation.
When we run our “iconfont” task, it will take the sass/templates/_icons.scss file, run the JavaScript code, and generate the sass/_icons.scss file. It is the "sass" task that will generate the CSS.
Run Gulp.js to generate the iconont
To generate the font files and the SCSS, we need to run our “iconfont” task like this:
gulp iconfont
To compile the Sass code to CSS, we'll run our "default" function:
gulp default
Gulp.js has simplified things, we can omit the word "default", it will still run our task by default:
gulp
Use our new icon
If we take the example above, to display our icon we must write a tag with the icon class which is the main class and the icon-myicon class which contains the content.
Example:
<i class="icon icon-myicon"></i>
Conclusion
It takes a little time to set everything up but during a project, adding an icon to your web font is done in seconds.
All the files are on the GitHub of UX-Republic, you can download them at this address: https://github.com/ux-republic/gulp-icon-font.
Feel free to ask your questions in the comments.
STORYTELLING: THE ART OF CONVINCING # Paris
SMILE Paris
163 quay of Doctor Dervaux 92600 Asnières-sur-Seine
UX/UI ECO-DESIGN # Paris
SMILE Paris
163 quay of Doctor Dervaux 92600 Asnières-sur-Seine
DESIGN THINKING: CREATING INNOVATION # Belgium
UX-REPUBLIC Belgium
12 avenue de Broqueville - 1150 Woluwe-Saint-Pierre
MANAGING AND MEASURING UX # Paris
SMILE Paris
163 quay of Doctor Dervaux 92600 Asnières-sur-Seine
DESIGN SPRINT: INITIATION & FACILITATION # Paris
SMILE Paris
163 quay of Doctor Dervaux 92600 Asnières-sur-Seine
UX-DESIGN: THE FUNDAMENTALS # Belgium
UX-REPUBLIC Belgium
12 avenue de Broqueville - 1150 Woluwe-Saint-Pierre
GOOGLE ANALYTICS 4 #Paris
SMILE Paris
163 quay of Doctor Dervaux 92600 Asnières-sur-Seine
ACCESSIBLE UX/UI DESIGN # Belgium
UX-REPUBLIC Belgium
12 avenue de Broqueville - 1150 Woluwe-Saint-Pierre