Advertisement

#1 How To Minimize Page Weight While Using Font Awesome Icons

This video will be the first of several videos where we explore how to add Font Awesome icons to a project. We will start off by including the entire package which while very convenient will massively increase the size of our javascript file. For a web project this increase in size is completely unacceptable so we will quickly come up with a solution that will minimize the impact on the page weight while still allowing us to utilize the icons that we would like to use.

Parts

Code Snippets

package.json

{
    ...
    "devDependencies": {
        "@fortawesome/fontawesome-svg-core": "^1.2.25",
        "@fortawesome/fontawesome-free": "^5.11.2",
        "@fortawesome/free-solid-svg-icons": "^5.11.2",
        "fontawesome-svg-sprite-generator": "^1.0.2",
    },
    ...
}
root ⟩ package.json

main.ts

require("@fortawesome/fontawesome-free/js/all.min.js");
root ⟩ main.ts

main.pug

doctype html
html(lang="en")
    head
        meta(charset="UTF-8")
        meta(name="viewport", content="width=device-width, initial-scale=1.0")
        meta(http-equiv="X-UA-Compatible", content="ie=edge")
        title Font Awesome
        link(rel="stylesheet" href="main.css")
    body
        i.fas.fa-camera.fa-3x
        script(src="main.js")
root ⟩ main.pug

main.ts

import {dom, library} from "@fortawesome/fontawesome-svg-core";
import {faCamera} from "@fortawesome/free-solid-svg-icons";

library.add(faCamera);

dom.watch();
root ⟩ main.ts

main.pug

doctype html
html(lang="en")
    head
        meta(charset="UTF-8")
        meta(name="viewport", content="width=device-width, initial-scale=1.0")
        meta(http-equiv="X-UA-Compatible", content="ie=edge")
        title Font Awesome
        link(rel="stylesheet", href="main.css")
    body
        svg.svg-inline--fa.fa-camera.fa-w-16.fa-3x(
            aria-hidden="true"
            focusable="false"
            data-prefix="fas"
            data-icon="camera"
            role="img"
            xmlns="http://www.w3.org/2000/svg"
            viewBox="0 0 512 512"
            data-fa-i2svg="")
                path(
                    fill="currentColor"
                    d="M512 144v288c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V144c0-26.5 21.5-48 48-48h88l12.3-32.9c7-18.7 24.9-31.1 44.9-31.1h125.5c20 0 37.9 12.4 44.9 31.1L376 96h88c26.5 0 48 21.5 48 48zM376 288c0-66.2-53.8-120-120-120s-120 53.8-120 120 53.8 120 120 120 120-53.8 120-120zm-32 0c0 48.5-39.5 88-88 88s-88-39.5-88-88 39.5-88 88-88 88 39.5 88 88z")
root ⟩ main.pug

main.scss

svg:not(:root).svg-inline--fa {
    overflow: visible;
}

.svg-inline--fa {
    display: inline-block;
    font-size: inherit;
    height: 1em;
    overflow: visible;
    vertical-align: -0.125em;
}

.svg-inline--fa.fa-w-16 {
    width: 1em;
}

.fa-3x {
    font-size: 3em;
}
root ⟩ main.scss

icons.js

const fs = require("fs");
const path = require("path");

const fas = require("@fortawesome/free-solid-svg-icons");
const faSvgSprite = require("fontawesome-svg-sprite-generator");

const sprite = faSvgSprite.generate([fas.faCamera]);

fs.writeFile(path.join(__dirname, "fa-icons.svg"), sprite.svg, (err) => {
    if (err) {
        throw err;
    }
});
fs.writeFile(path.join(__dirname, "fa.json"), JSON.stringify(sprite.attributes, null, 4), (err) => {
    if (err) {
        throw err;
    }
});
root ⟩ icons.js

Advertisement

main.pug

doctype html
html(lang="en")
    ...
    body
        svg.svg-inline--fa.fa-camera.fa-w-16.fa-3x(
            aria-hidden="true"
            focusable="false"
            role="img"
            xmlns="http://www.w3.org/2000/svg"
            viewBox="0 0 512 512"
            data-fa-i2svg="")
                use(href="/fa-icons.svg#fas-fa-camera")
root ⟩ main.pug

main.pug

mixin faIcon(id, width, scale=1)
    - href = `/fa-icons.svg#${id}`; 
    - cssClass = `${id} fa-w-${width} fa-${scale}x`;
    - viewBoxWidth = 512*width/16;
    - viewBox = `0 0 ${viewBoxWidth} 512`;
    svg.svg-inline--fa(
        aria-hidden="true"
        focusable="false"
        role="img"
        xmlns="http://www.w3.org/2000/svg"
        class=cssClass
        viewBox=viewBox)
        use(href=href)

doctype html
html(lang="en")
    ...
    body
        +faIcon("fas-fa-camera", 16, 3)
root ⟩ main.pug

main.scss

@mixin font-awesome-class($class) {
    $width: $class / 16;

    .svg-inline--fa.fa-w-#{$class} {
        width: #{$width}em;
    }
}

@mixin scale($scale) {
    .fa-#{$scale}x {
        font-size: #{$scale}em;
    }
}
...
@include font-awesome-class(16);
@include scale(3);
root ⟩ main.scss

main.scss

...
@for $i from 0 through 10 {
    @include font-awesome-class(10 + $i);
}

@for $i from 1 through 10 {
    @include scale($i);
}
...
root ⟩ main.scss

main.pug

mixin faIcon(id, width, scale=1)
    ... 
    - scaleStr = `${scale}`.replace(".", "_");
    - cssClass = `${id} fa-w-${width} fa-${scaleStr}x`;
    ...
...
root ⟩ main.pug

main.scss

@function str-replace($string, $search, $replace: "") {
    $index: str-index($string, $search);

    @if $index {
        @return str-slice($string, 1, $index - 1) + $replace +
            str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
    }

    @return $string;
}
...
@mixin scale($scale) {
    $scale-str: str-replace(#{$scale}, ".", "_");
    .fa-#{$scale-str}x {
        font-size: #{$scale}em;
    }
}
...
@include scale(2.5);
root ⟩ main.scss

main.pug

...
html(lang="en")
    ...
    body
        +faIcon("fas-fa-camera", 16, 2.5)
root ⟩ main.pug

Exciton Interactive LLC
Advertisement