Présentation de Font Awesome 5 et des icônes SVG

Voir aussi : We're upgrading our icons to Font Awesome 6!

Nous fusionnerons bientôt dans master une branche qui met à niveau Discourse vers Font Awesome 5.5.0 (version gratuite) et passe à l’utilisation d’icônes SVG au lieu d’une police d’icônes. Il s’agit d’un changement substantiel, offrant de nombreux avantages et une modification significative pour les développeurs.

Voici un aperçu rapide des changements :

  • L’utilisation d’icônes SVG fournira des icônes plus nettes, meilleures pour l’accessibilité et plus faciles à personnaliser ; consultez cet article de GitHub pour plus de détails.
  • Puisque l’ensemble d’icônes Font Awesome est passé à plus de 1300 icônes dans la version 5, nous avons créé une API interne qui délivre aux clients un sous-ensemble de toutes les icônes FA, à savoir uniquement celles utilisées par cette instance Discourse.
  • Heureusement, ce sous-ensemble a une empreinte de taille plus petite : il est déjà en cours d’exécution ici sur Meta, avec seulement 27,5 ko contre 75,7 ko pour la police d’icônes FA 4.7.
  • Les plugins et les thèmes (y compris les composants de thème) peuvent ajouter des icônes FA supplémentaires à l’ensemble.
  • Les icônes de groupe et de badges seront automatiquement incluses dans l’ensemble, et les administrateurs de site peuvent également utiliser un nouveau paramètre de site appelé svg icon subset pour enregistrer leurs icônes choisies et les ajouter au sous-ensemble de leur site.
  • Changement cassant : les développeurs de plugins et de thèmes ne peuvent plus utiliser <i class="fa fa-icon"></i> ou remplacer les sélecteurs pseudo :before pour référencer/remplacer des icônes ; ceux-ci doivent désormais être remplacés par l’utilisation de fonctions Discourse qui injectent des SVG dans la page.

Ci-dessous, vous trouverez des instructions sur la façon de mettre à jour les plugins et les thèmes pour utiliser des icônes du nouvel ensemble.

Quoi de neuf dans Font Awesome 5

Font Awesome 5 a introduit de nombreuses nouvelles icônes, mais aussi quelques changements de nommage. Pour une discussion complète sur les changements, veuillez consulter la documentation de mise à niveau Font Awesome. Le changement principal est que les icônes dans FA sont désormais disponibles dans des styles séparés. Il existe trois styles :

  1. solide (par défaut) – fas
  2. régulier – far
  3. marques – fab

Pour les styles régulier ou marques, FA 5 introduit de nouveaux préfixes de classe, « far » et « fab » respectivement. Pour utiliser une icône du style régulier ou marques, nous devons donc utiliser cette nouvelle convention de nommage : « far fa-address-book » ou « fab fa-facebook ». (Les icônes solides peuvent simplement être référencées comme auparavant « fa-nom-de-l’icône »).

Pour permettre l’association des trois styles en un seul sprite SVG, les icônes des styles régulier et marque dans Discourse sont converties en interne en far-nom-de-l'icône et fab-nom-de-l'icône. Les plugins, les thèmes, les groupes et les badges peuvent utiliser la convention de nommage standard de FontAwesome 5. Les administrateurs de site ajoutant des icônes à l’ensemble via le paramètre de site svg icon subset doivent utiliser la convention de nommage interne.

Développeurs : comment utiliser ou ajouter une icône SVG à votre plugin ou thème

  1. Ajout de nouvelles icônes

    plugins :

    Enregistrez l’icône dans le fichier plugin.rb de votre plugin :

    register_svg_icon "user-times" if respond_to?(:register_svg_icon)
    

    (Remarque : vous devez redémarrer votre serveur Rails dans votre environnement de développement pour que ce changement prenne effet.)

    thèmes ou composants :

    Ajoutez un paramètre de chaîne ou de liste avec un nom contenant _icon, par exemple :

    svg_icons: 
      default: 'question-circle|wallet'
      type: 'list'
      list_type: 'compact'
    

    et Discourse inclura l’(les) icône(s) définie(s) dans ce paramètre de thème dans le sous-ensemble.

  2. Utilisation d’icônes dans votre JavaScript

    plugins :

    import { iconNode } from "discourse-common/lib/icon-library";
    ...
    let icon = iconNode('user-times');
    

    ou utilisez l’helper iconHTML

    import { iconHTML } from "discourse-common/lib/icon-library";
    ...
    let icon = iconHTML('user-times');
    

    thèmes ou composants :

    const { iconNode } = require("discourse-common/lib/icon-library");
    ...
    let icon = iconNode('user-times');
    

    ou utilisez l’helper iconHTML

    const { iconHTML } = require("discourse-common/lib/icon-library");
    ...
    let icon = iconHTML('user-times');
    

    Les helpers peuvent également prendre un deuxième paramètre avec des propriétés comme le titre ou la classe. Cela fonctionne de la même manière dans les plugins et les thèmes / composants, par exemple :

    iconHTML('user-times', { class: "reply-to-glyph" })
    
  3. Utilisation d’icônes dans vos modèles Handlebars
    Dans les modèles Handlebars, vous pouvez utiliser d-icon, comme ceci :

    {{d-icon 'user-times'}}
    

    cela fonctionne également de la même manière pour les plugins et les thèmes / composants.

Ajout d’icônes personnalisées

Si vous souhaitez avoir plus d’icônes que celles disponibles dans FontAwesome, vous pouvez ajouter vos propres icônes SVG dans un plugin ou un thème. Consultez ce sprite SVG pour un exemple de structure de sprite. (Il s’agit essentiellement d’une liste d’éléments <symbol>, chacun avec son propre ID unique.)

Dans les thèmes et les composants : ajoutez le sprite SVG dans le dossier /assets et référencez-le dans about.json en utilisant le nom de variable icons-sprite. Pour un sprite nommé my-icons.svg, votre assets.json doit inclure ceci :

"assets": {
   "icons-sprite": "/assets/my-icons.svg"
}

Vous pouvez également ajouter le sprite SVG à un thème ou un composant via l’interface utilisateur. Dans ce cas, assurez-vous que le nom de la variable SCSS est défini sur icons-sprite. Capture d’écran :

Dans les plugins : incluez simplement un fichier sprite SVG dans le dossier plugins/votre-nom-de-plugin/svg-icons. Redémarrez votre serveur (si en développement) ou reconstruisez le site si vous êtes dans un conteneur Docker, et vos icônes personnalisées devraient être automatiquement disponibles.

Pour éviter tout conflit potentiel avec les IDs d’icônes Font Awesome, vous devez préfixer les IDs des icônes personnalisées dans votre plugin ou thème.

80 « J'aime »

Could someone elaborate on how to update a theme component? I’m very green at this and haven’t been able to make sense of all this. I’m currently using as such:

<a href="javascript:history.back()" class="app-go-back"><i class="fas fa-arrow-left" aria-hidden="true"></i></a>

This may be unrelated, but the following css has broken since the latest build:

.b-header .nav-pills > li:nth-child(3) a::before{
	content: "\f1ea";
}

As you can see here, only this one icon has broken, I double checked and f1ea is still valid in FA5. Is there a better way to achieve this with the new changes?

2 « J'aime »

From what I can see all of the icons are broken:

2 « J'aime »

Hmm interesting, they must be cached on my side. Is the option of using this gone now @pmusaraj?

2 « J'aime »

For HTML code directly, you can replace:

<i class="fas fa-arrow-left" aria-hidden="true"></i>

with:

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

Note that “arrow left” is in two places, in the class and in the <use> tag. Also, this icon is in the solid style in FA5, but for icons in regular or brands, you need to use the prefixes far- and fab-, respectively.

In your header links, you can’t use :before anymore, because SVG sprites can’t be added to pseudo selectors. But you can use this component: Header submenus (it’s been updated recently, and is FA5-compatible).

15 « J'aime »

Good job. :ok_hand:

How can I change this code to work with Font Awesome 5?

 a[href="/new"]:before {
      display: inline-block;
      font-family: FontAwesome;
      font-style: normal;
      font-weight: normal;
      line-height: 1;
      -moz-osx-font-smoothing: grayscale;
      content: "\f0ca";
      margin-right: 3px
    }
2 « J'aime »

What is creating this a[href="/new"] element? If you are adding it in your theme, via JS, then it’s easier to add the icon there, instead of using the CSS pseudo selector. One of iconHTML or iconNode above should do the trick.

5 « J'aime »

I’m very confused. I tried this and it worked:

But when I switched “left” to “right” in both places, it didn’t work. Am I missing something? Here’s the code I tried:

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

(I was actually trying to get the church icon to work, so if that’s going to require something else, let me know.)

1 « J'aime »

The arrow-right icon is not included by default (because it isn’t used elsewhere in Discourse), so you will need to add it to the svg icons subset site setting. Same for the church icon. (FA5 comes with thousands of icons, so we use a subset to avoid loading all the icons all the time. It saves precious bytes :slight_smile:)

17 « J'aime »

Makes complete sense. Thanks much.

2 « J'aime »

I was banging my head against the wall trying to figure out why the right arrow wasn’t displaying last night! FYI I don’t if this is because it is a work in progress, but the instructions say to use far but this did not display the icon, I had to add it as fa-right-arrow for it to display.

3 « J'aime »

Sorry about that, I have updated the description text for that setting to include: “Use prefix ‘fa-’ for solid icons, ‘far-’ for regular icons and ‘fab-’ for brand icons.”

8 « J'aime »

I want to add icons to the navigation bar – and I used a[href="/new"] for meta.discourse.org/new or a[href="/categories"] for meta.discourse.org/categories

// Add Font Awesome 5 Icons to the navigation bar

a[href="/new"]:before {
  font-family: "Font Awesome 5 Free";
  font-weight: 900;
  content: "\f007";
  display: inline-block;
  font-style: normal;
  font-variant: normal;
  text-rendering: auto;
  line-height: 1;
  margin-right: 3px;
  -webkit-font-smoothing: antialiased;
}

But I’m doing something wrong and it’s not working.

2 « J'aime »

We are no longer using Font Awesome as a font, so using the old method of pseudo selectors in CSS will not work.

If you don’t want to touch javascript and want a CSS-only solution, you can use an SVG as an image:

a[href="/new"]:before {
   content: url(/link-to-file.svg);
  // display inline-block, etc still needed
}

or you can inline the SVG’s code (which I believe has some compatibility issues with older browsers)

a[href="/new"]:before {
   content: url('data:image/svg+xml; utf8, <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" data-prefix="fas" data-icon="grin-tongue-wink" class="svg-inline--fa fa-grin-tongue-wink fa-w-16" role="img"  height="25" width="25" viewBox="0 0 496 512"><path fill="white" d="M344 184c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zM248 8C111 8 0 119 0 256c0 106.3 67 196.7 161 232-5.6-12.2-9-25.7-9-40v-45.5c-24.7-16.2-43.5-38.1-47.8-63.8-2-11.8 9.3-21.5 20.7-17.9C155.1 330.5 200 336 248 336s92.9-5.5 123.1-15.2c11.5-3.7 22.6 6.1 20.7 17.9-4.3 25.7-23.1 47.6-47.8 63.8V448c0 14.3-3.4 27.8-9 40 94-35.3 161-125.7 161-232C496 119 385 8 248 8zm-56 225l-9.5-8.5c-14.8-13.2-46.2-13.2-61 0L112 233c-8.5 7.4-21.6.3-19.8-10.8 4-25.2 34.2-42.1 59.9-42.1S208 197 212 222.2c1.6 11.1-11.6 18.2-20 10.8zm152 39c-35.3 0-64-28.7-64-64s28.7-64 64-64 64 28.7 64 64-28.7 64-64 64zm-50.9 102.6c-14.4-6.5-31.1 2.2-34.6 17.6l-1.8 7.8c-2.1 9.2-15.2 9.2-17.3 0l-1.8-7.8c-3.5-15.4-20.2-24.1-34.6-17.6-.9.4.3-.2-18.9 9.4v63c0 35.2 28 64.5 63.1 64.9 35.7.5 64.9-28.4 64.9-64v-64c-19.5-9.6-18.2-8.9-19-9.3z"></path></svg>');
}
8 « J'aime »

I’ve hacked my way through this and I’ve got everything working again except the right arrow on my mobile navigation component for the app, I can’t get it to right align to save my life. I tried using flex with flex-end to no avail. Please forgive my horrible attempt at this…

Here is my components code:
/body

/body
<div id="mobilenav">
<a href="javascript:history.back()" class="app-go-back">Back</a>
<a href="javascript:history.forward()" class="app-go-forward">Forward</a>
		<div id="mobilenavleft">
			<svg class="fa d-icon d-icon-arrow-left svg-icon svg-node" aria-hidden="true">
			<use xlink:href="#arrow-left"></use>
		</svg>
	</div>
		<div id="mobilenavright">
			<svg class="fa d-icon d-icon-arrow-right svg-icon svg-node" aria-hidden="true">
			<use xlink:href="#arrow-right"></use>
	</svg>
</div>
CSS
@media only screen and (min-width:1024px) {
div#mobilenav {
            display: none !important;
        }
}

/* move up compose window on mobile */
@media only screen and (max-width:1024px) {
#reply-control.open.edit-title {
            margin-bottom: 29px;
            height: 85%;
            margin-top: -29px;
        }

.timeline-container.timeline-fullscreen.show {
            margin-bottom: 29px;
        }
#reply-control.open {
            margin-bottom: 29px;
        }
.docked-composer .docked-editor {
    margin-bottom: 29px;
}
#topic-progress {
    margin-bottom: 33px;
}
.sticky-footer {
    margin-bottom: 33px;
}
}

/* display on ipad in landscape orientation */
@media only screen 
and (min-device-width : 768px) 
and (max-device-width : 1024px) 
and (orientation : landscape) {
div#mobilenav {
            display: block;
        }
}

div#mobilenav {
box-shadow: 0px -1px 5px 0px rgba(0,0,0,0.15);
position: fixed;
bottom: 0px;
width: 100%;
height: auto;
border: none;
z-index: 99999999999;
background-color: #2A2B2F;
}

.app-go-forward {
text-align: right;
padding: 5px 3%;
width: 44%;
float: right;
display: inline-block;
}

.app-go-back {
text-align: left;
padding: 5px 7%;
width: 44%;
float: left;
display: inline-block;
}

div#mobilenav {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}

div#mobilenavleft {
box-shadow: 0px -1px 5px 0px rgba(0,0,0,0.15);
position: fixed;
bottom: 0px;
width: 1%;
height: auto;
border: none;
z-index: 99999999999;
padding-bottom: 4px;
padding-left: 5px;
}

div#mobilenavright {
box-shadow: 0px -1px 5px 0px rgba(0,0,0,0.15);
position: fixed;
bottom: 0px;
width: 1%;
height: auto;
border: none;
z-index: 99999999999;
padding-bottom: 4px;
padding-right: 5px;
justify-content: flex-end;
}

If anyone wants to help, my site is here and this component only displays below 1024px obviously. The left arrow looks perfect and the right arrow should mirror this.

1 « J'aime »

It’s because you’re using position: fixed on the arrow, if you add

div#mobilenavright {
  right: 5px;
}

Then it should be where you want it.

Sidenote: You don’t really need to use position: fixed for those arrows at all because they’re already within a fixed container, if you put the arrows inside of your a tags containing the “forward” and “back” text the layout might be a bit easier to manage in general.

10 « J'aime »

I’m trying to use this with the Brand Header Theme Component but not having any success with this:

.b-header .nav-pills > li:nth-child(1) a::before{
content: url(https://npn.sfo2.cdn.digitaloceanspaces.com/misc/home-solid.svg);
display: inline-block;
width: 20px;
height: 20px;}

I’ve also tried:

.b-header .nav-pills > li:nth-child(1) a::before {
display: block;
  content: ' ';
  background-image: url('https://npn.sfo2.cdn.digitaloceanspaces.com/misc/home-solid.svg');
  background-size: 20px 20px;
  height: 20px;
  width: 20px;
}

Anyone have ideas?

2 « J'aime »

Something is wrong with your SVG image. The screenshot below works with the Discourse logo, but not with that SVG file:

2 « J'aime »

It might be because the SVG doesn’t have any height/width defined (in the SVG markup itself, not the CSS)

Can you right click this one below, save it, and try again… I’ve added some dimensions to it.

home-solid

8 « J'aime »

This does seem to work, dare I ask how? Also, fill: does not seem to work on this to change the color, it just displays as black.

For reference, my code:

.b-header .nav-pills > li:nth-child(1) a::before {
display: inline-block;
content: ' ';
background: url('https://d11a6trkgmumsb.cloudfront.net/original/3X/a/6/a61b08e7f318170faee755cb6dcd48d6f6d7413d.svg');
background-size: contain;
height: 20px;
width: 20px;
border: 1px solid blue;
fill: blue;

}

2 « J'aime »