Introducing Font Awesome 5 and SVG icons


#21

Thanks, but for some reason, it didn’t work your method. I do not know if this solution is the best but it worked for me:

// Add Font Awesome 5 Icons to the navigation bar

 @import "common/foundation/mixins";

 a[href="/categories"]:before {
    background: transparent;
    content: svg-uri('<svg fill="gray" xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 512 512"><path d="M12.41 148.02l232.94 105.67c6.8 3.09 14.49 3.09 21.29 0l232.94-105.67c16.55-7.51 16.55-32.52 0-40.03L266.65 2.31a25.607 25.607 0 0 0-21.29 0L12.41 107.98c-16.55 7.51-16.55 32.53 0 40.04zm487.18 88.28l-58.09-26.33-161.64 73.27c-7.56 3.43-15.59 5.17-23.86 5.17s-16.29-1.74-23.86-5.17L70.51 209.97l-58.1 26.33c-16.55 7.5-16.55 32.5 0 40l232.94 105.59c6.8 3.08 14.49 3.08 21.29 0L499.59 276.3c16.55-7.5 16.55-32.5 0-40zm0 127.8l-57.87-26.23-161.86 73.37c-7.56 3.43-15.59 5.17-23.86 5.17s-16.29-1.74-23.86-5.17L70.29 337.87 12.41 364.1c-16.55 7.5-16.55 32.5 0 40l232.94 105.59c6.8 3.08 14.49 3.08 21.29 0L499.59 404.1c16.55-7.5 16.55-32.5 0-40z"></path></svg>');
    vertical-align: baseline;
    margin-right: 4px;
    margin-bottom: -2px;
}

(David Kingham) #22

After a lot of research and guessing, I was able to get the svg icons to work.

First, I opened the svgs I downloaded from FA in Illustrator and followed this How To Export SVGs For The Web From Illustrator – Colin Lord – Medium to export. I’m not sure if this step was necessary.

Then I uploaded those svgs into the theme component, copied the url and put them into the css which ended up looking like this:

CSS
.b-header a::before{
    filter: invert(90%) sepia(30%) saturate(839%) hue-rotate(336deg) brightness(101%) contrast(99%);
    display: inline-block;
    content: ' ';
    background-size: contain;
    height: 15px;
    width: 15px;
    margin-right: 8px;
    margin-top: 4px;
    }

.b-header .nav-pills > li:nth-child(1) a::before {
    background: url('https://npn.sfo2.digitaloceanspaces.com/original/2X/5/5937500ddd5d68b25c8e3667b313901a1d4a61f7.svg'); //home
    background-repeat: no-repeat;
}

.b-header .nav-pills > li:nth-child(2) a::before {
    background: url('https://npn.sfo2.digitaloceanspaces.com/original/2X/d/de70170d27c1658c0d275e4dd870f03a786da3eb.svg'); //community
    background-repeat: no-repeat;
}

.b-header .nav-pills > li:nth-child(3) a::before {
    background: url('https://npn.sfo2.digitaloceanspaces.com/original/2X/b/b60d7c286f8e99a461cc5e4051a2611b201d7be2.svg'); //articles
    background-repeat: no-repeat;
    margin-top: 6px;
}

.b-header .nav-pills > li:nth-child(4) a::before {
    background: url('https://npn.sfo2.digitaloceanspaces.com/original/2X/0/01e24533f51b29ed3f80d78d28bd070c6eb33826.svg'); //store
    background-repeat: no-repeat;
    margin-top: 3px;
}

.b-header .nav-pills > li:nth-child(5) a::before {
    background: url('https://npn.sfo2.digitaloceanspaces.com/original/2X/2/2e0f64a2ce8567c036c42c38124aa0811c0a036d.svg'); //archive
    background-repeat: no-repeat;
    margin-top: 2px;
}

.b-header .nav-pills > li:nth-child(6) a::before {
    background: url('https://npn.sfo2.digitaloceanspaces.com/original/2X/5/58116cd2824c5162baa55ab9b4938fa059021ba7.svg'); //info
    background-repeat: no-repeat;
    margin-top: 0px;
}

.b-header .nav-pills > li:nth-child(7) a::before {
    background: url('https://npn.sfo2.digitaloceanspaces.com/original/2X/8/80598d927cf15ac38700dd160459de3a31320bcd.svg'); //contact
    background-repeat: no-repeat;
}

.b-header .nav-pills > li:nth-child(8) a::before {
    background: url('https://npn.sfo2.digitaloceanspaces.com/original/2X/0/07c0588accc7bb303039ebcbbb7fb28d198a286a.svg'); //account
    background-repeat: no-repeat;
}

The key to changing the color of the svg was using filter: invert(90%) sepia(30%) saturate(839%) hue-rotate(336deg) brightness(101%) contrast(99%);

You can convert hex colors to filter here: CSS filter generator to convert from black to target hex color

Also the icon was tiling so I had to add background-repeat: no-repeat;

For some reason the icons were not aligning so I had to adjust the margin-top:; for each icon. I’m sure there’s a more elegant way of achieving this!


(Kris) #23

Right, using SVGs as a linked image unfortunately means you can’t control the fill color. As you discovered, CSS filters are one way to overcome this.

What was missing was the height/width attribute within the SVG file. If you open an SVG in a text editor, you’ll see this:

<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" data-prefix="fas" data-icon="home" class="svg-inline--fa fa-home fa-w-18" role="img" width="25" height="25" viewBox="0 0 576 512">
  <path fill="currentColor" d="M488 312.7V456c0 13.3-10.7 24-24 24H348c-6.6 0-12-5.4-12-12V356c0-6.6-5.4-12-12-12h-72c-6.6 0-12 5.4-12 12v112c0 6.6-5.4 12-12 12H112c-13.3 0-24-10.7-24-24V312.7c0-3.6 1.6-7 4.4-9.3l188-154.8c4.4-3.6 10.8-3.6 15.3 0l188 154.8c2.7 2.3 4.3 5.7 4.3 9.3zm83.6-60.9L488 182.9V44.4c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12V117l-89.5-73.7c-17.7-14.6-43.3-14.6-61 0L4.4 251.8c-5.1 4.2-5.8 11.8-1.6 16.9l25.5 31c4.2 5.1 11.8 5.8 16.9 1.6l235.2-193.7c4.4-3.6 10.8-3.6 15.3 0l235.2 193.7c5.1 4.2 12.7 3.5 16.9-1.6l25.5-31c4.2-5.2 3.4-12.7-1.7-16.9z"/>
</svg>

If you scroll to the right a bit and look at line 1, the part I added was width="25" height="25". It looks like Font Awesome icons don’t come with dimensions defined inline (it isn’t necessary if you’re embedding SVGs directly in HTML).

If you look at the line 2, you can also see the fill definition, you can change this to a hex color.


(Steven Greco) #24

How would I do this for a brand icon? I entered “fab fa-discord” into site settings and added this html

<svg class="fab d-icon d-icon-discord svg-icon svg-node"><use xlink:href="#discord"></use></svg>

But it does not show. I must be missing something.


(Kris) #25

Use #fab-discord here


(Lars) #26

Do you have a fix for the old “Add icon to header”-function?

As of now I am using code very similar to the following within my header:

api.decorateWidget('header-icons:before', helper => {
    return helper.h('li', [
        helper.h('a#globe-button.icon', {
            href:'https://www.website.com/',
            title: 'Back to website'
        }, helper.h('i.fa.fa-globe.globe-button-icon.d-icon')),
    ]);
});

Ofc the “i”-functionality is broken but since I am no dev myself I was wondering what to tweak in order to get the icons displayed again :slight_smile:


#27

Hey @LKNickname, try this out:

const { iconNode } = require("discourse-common/lib/icon-library");
api.decorateWidget("header-icons:before", helper => {
  return helper.h("li", [
    helper.h(
      "a#globe-button.icon",
      {
        href: "https://www.website.com/",
        title: "Back to website"
      },
      iconNode("globe")
    )
  ]);
});

(Penar Musaraj) #28

Thanks @tshenry, I’ve also updated the original how-to.


(Lars) #29

Worked like a charm, thanks :slight_smile:


(Jordan) #30

I’ve read all the replies here and am trying to keep this as simple as possible

This is what my html looked like before:

<a class="red" href="https://jewelbound.com/courses"><i style="margin-top: -1px;" class="fa fa-edit"></i><span>&nbsp; Courses</span></a>

I switched to this, and it didn’t work:

<a class="red" href="https://jewelbound.com/courses"><svg style="margin-top: -1px;" class="fas d-icon d-icon-edit svg-icon svg-node"><use xlink:href="#edit"></svg><span>&nbsp; Courses</span></a>

You can see the FA icons in action on my actual site, and here is the same custom global nav bar on my discourse site.

I want to get them back and keep the code as simple and consistent as possible so everything still perfectly aligns with the global nav on my WordPress site.

Would really appreciate some help!


(Evgeny) #31

In the *.hbs file, you can replace it with:

<a class="red" href="https://jewelbound.com/courses">{{d-icon "edit"}}<span>&nbsp; Courses</span></a>

In widgets:

+ import { iconHTML } from "discourse-common/lib/icon-library";
+ let icon_edit = iconHTML('edit');
+ ${icon_edit}

It works for us.

Much depends on where you add the icons (via plugin, admin panel …). Examples of the above we did for plugins.


(Jordan) #32

Thanks for the response @Stranik.

Something interesting is that I only changed my html for the “home” link, which is the first of my five links in the global nav bar. It didn’t work. Then about 30 minutes laters I looked at the site and it was working! So I’ve updated all of my other links to follow the same convention. Same issue… not working… but I’m wondering if some time passes and they will load as well ¯_(ツ)_/¯

While the Home icon seems to be working… for all of the links I’m getting an error…

But… back to your suggestion…

In widgets:

+ import { iconHTML } from "discourse-common/lib/icon-library";
+ let icon_edit = iconHTML('edit');
+ ${icon_edit}

If I were to go the route you suggested, where would I add all of this? :arrow_up:


(Evgeny) #33

The option with the plugin (widgets), the one that I gave above, does not suit you.

I think, in your case, the option suggested above in the post will work:

I tried on the test site and it worked.

I do not know how such a construction is correct, but apparently it works for me.

<svg aria-hidden="true" data-prefix="fas" width="25" height="25" data-icon="edit" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class="svg-inline--fa fa-edit fa-w-18"><path fill="currentColor" d="M402.6 83.2l90.2 90.2c3.8 3.8 3.8 10 0 13.8L274.4 405.6l-92.8 10.3c-12.4 1.4-22.9-9.1-21.5-21.5l10.3-92.8L388.8 83.2c3.8-3.8 10-3.8 13.8 0zm162-22.9l-48.8-48.8c-15.2-15.2-39.9-15.2-55.2 0l-35.4 35.4c-3.8 3.8-3.8 10 0 13.8l90.2 90.2c3.8 3.8 10 3.8 13.8 0l35.4-35.4c15.2-15.3 15.2-40 0-55.2zM384 346.2V448H64V128h229.8c3.2 0 6.2-1.3 8.5-3.5l40-40c7.6-7.6 2.2-20.5-8.5-20.5H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V306.2c0-10.7-12.9-16-20.5-8.5l-40 40c-2.2 2.3-3.5 5.3-3.5 8.5z" class=""></path></svg>


(Penar Musaraj) #34

For the edit icon, you can use the following SVG code:

<svg class="fa d-icon d-icon-pencil svg-icon svg-node" aria-hidden="true">
  <use xlink:href="#pencil-alt"></use>
</svg>

Note that you should aim to figure out how to use the JS/Handlebars helper functions in the OP, they automatically handle renamed FontAwesome icons. When using SVGs directly, you’re going to need to track down the icons yourself. As you can see in code above, the edit icon in FA5 is called pencil-alt in the <use> tag. (For other renames, refer to the FontAwesome upgrade guide.)

Also note that the class to include in the svg element is fa, not fas.


(Jordan) #35

I agree with your sentiment here and am okay with a CSS only solution.

Can you tell me exactly what JS I need to put in my </head> ? And what the matching HTML element should look like?

I had a tough time interpreting the OP :disappointed: I’m pretty new to all of this


(Penar Musaraj) #36

I think your best bet here is to look at how some theme components work. I would highlight these two specifically:

and

You can install these two components on your site, and/or inspect their code to see how they use JS to insert elements on the page.


(Jordan) #38

Just reporting back a simple CSS solution that worked for me and coincides perfectly with my global navbar in wordpress:

I added the following to :

<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" crossorigin="anonymous">

My html in the “Header” looks like this:

    <a class="red" href="https://jewelbound.com"><i style="margin-top: -1px;" class="fas fa-home fa-sm"></i><span>&nbsp; Home</span></a> 
    <a class="red" href="https://jewelbound.com/courses"><i style="margin-top: -1px;" class="fas fa-edit fa-sm"></i><span>&nbsp; Courses</span></a> 
    <a class="red" href="https://jewelbound.com/events/"><i style="margin-top: -1px;" class="fas fa-calendar-alt fa-sm"></i><span>&nbsp; Events</span></a>
    <a class="grn" href="https://community.jewelbound.com"><i style="margin-top: -1px;" class="fas fa-comments fa-sm"></i><span>&nbsp; Community</span></a>
    <a class="grn" href="https://community.jewelbound.com/c/discussions/resources"><i style="margin-top: -1px;" class="fas fa-star fa-sm"></i><span>&nbsp; Resources</span></a>

Annnnnnd, my navbar FA icons are back!


(Rafael dos Santos Silva) #39

This will make your site load both the SVG version of Font Awesome and the WebFont version, which will be a extra bytes (85kb).

Not to mention that the extra CSS (foreign to Discourse now) can break in weird ways in the future.


(Jordan) #40

YOWZA! That’s not good to have all the extra bytes. Is there a way to prevent it from loading the SVG version as well? It was just so much easier to do this approach, and I just wanted my icons back up as quick as possible.


(Jeff Atwood) #41

I think you need to do this the correct way rather than the “easy” way…