Comment ajouter des polices pour créer des projets basés sur des applications?

177

J'utilise create-react-app et je préfère ne pas le faire eject.

On ne sait pas où doivent aller les polices importées via @ font-face et chargées localement.

À savoir, je charge

@font-face {
  font-family: 'Myriad Pro Regular';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Regular'), url('MYRIADPRO-REGULAR.woff') format('woff');
}

Aucune suggestion?

-- ÉDITER

Y compris l'essentiel auquel Dan se réfère dans sa réponse

  Client git:(feature/trivia-game-ui-2)  ls -l public/static/fonts
total 1168
-rwxr-xr-x@ 1 maximveksler  staff  62676 Mar 17  2014 MYRIADPRO-BOLD.woff
-rwxr-xr-x@ 1 maximveksler  staff  61500 Mar 17  2014 MYRIADPRO-BOLDCOND.woff
-rwxr-xr-x@ 1 maximveksler  staff  66024 Mar 17  2014 MYRIADPRO-BOLDCONDIT.woff
-rwxr-xr-x@ 1 maximveksler  staff  66108 Mar 17  2014 MYRIADPRO-BOLDIT.woff
-rwxr-xr-x@ 1 maximveksler  staff  60044 Mar 17  2014 MYRIADPRO-COND.woff
-rwxr-xr-x@ 1 maximveksler  staff  64656 Mar 17  2014 MYRIADPRO-CONDIT.woff
-rwxr-xr-x@ 1 maximveksler  staff  61848 Mar 17  2014 MYRIADPRO-REGULAR.woff
-rwxr-xr-x@ 1 maximveksler  staff  62448 Mar 17  2014 MYRIADPRO-SEMIBOLD.woff
-rwxr-xr-x@ 1 maximveksler  staff  66232 Mar 17  2014 MYRIADPRO-SEMIBOLDIT.woff
  Client git:(feature/trivia-game-ui-2)  cat src/containers/GameModule.css
.GameModule {
  padding: 15px;
}

@font-face {
  font-family: 'Myriad Pro Regular';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Regular'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-REGULAR.woff') format('woff');
}

@font-face {
  font-family: 'Myriad Pro Condensed';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Condensed'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-COND.woff') format('woff');
}

@font-face {
  font-family: 'Myriad Pro Semibold Italic';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Semibold Italic'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-SEMIBOLDIT.woff') format('woff');
}

@font-face {
  font-family: 'Myriad Pro Semibold';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Semibold'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-SEMIBOLD.woff') format('woff');
}

@font-face {
  font-family: 'Myriad Pro Condensed Italic';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Condensed Italic'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-CONDIT.woff') format('woff');
}

@font-face {
  font-family: 'Myriad Pro Bold Italic';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Bold Italic'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-BOLDIT.woff') format('woff');
}

@font-face {
  font-family: 'Myriad Pro Bold Condensed Italic';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Bold Condensed Italic'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-BOLDCONDIT.woff') format('woff');
}

@font-face {
  font-family: 'Myriad Pro Bold Condensed';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Bold Condensed'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-BOLDCOND.woff') format('woff');
}

@font-face {
  font-family: 'Myriad Pro Bold';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Bold'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-BOLD.woff') format('woff');
}
Maxim Veksler
la source
2
Avez-vous vérifié la section "Ajout de polices" dans son guide de l'utilisateur?
Dan Abramov
2
@DanAbramov j'ai, la recommandation est d'importer la police. Mais je pense que ce n'est pas clair (du moins pas pour moi) comment cela devrait être fait dans la pratique. En attendant, j'ai fait ce gist.github.com/maximveksler/5b4f80c5ded20237c3deebc82a31dcd5 et cela semble fonctionner (le pack Web alerte s'il ne trouve pas de fichier de police) mais je suis sûr que ce n'est pas la solution optimale et un exemple ou l'avoir documenté ici aiderait. ty pour tendre la main!
Maxim Veksler
2
J'ai répondu. Votre approche me semble erronée: %PUBLIC_URL%ne peut pas fonctionner (et n'est pas nécessaire) dans un fichier CSS. De plus, comme décrit dans le guide, vous devez utiliser les importations JS dans presque tous les cas, pas le dossier public.
Dan Abramov
Existe-t-il un utilitaire / package pour analyser le dossier spécifié pour les polices et générer le fichier de script avec toutes les variations de polices? Il est fastidieux d'écrire tout cela manuellement
helloworld

Réponses:

290

Il existe deux options:

Utilisation des importations

C'est l'option suggérée. Il garantit que vos polices passent par le pipeline de construction, obtiennent des hachages lors de la compilation afin que la mise en cache du navigateur fonctionne correctement et que vous obteniez des erreurs de compilation si les fichiers sont manquants.

Comme décrit dans «Ajout d'images, de polices et de fichiers» , vous devez avoir un fichier CSS importé de JS. Par exemple, par défaut src/index.jsimporte src/index.css:

import './index.css';

Un fichier CSS comme celui-ci passe par le pipeline de construction et peut référencer des polices et des images. Par exemple, si vous mettez une police src/fonts/MyFont.woff, vous index.csspouvez inclure ceci:

@font-face {
  font-family: 'MyFont';
  src: local('MyFont'), url(./fonts/MyFont.woff) format('woff');
}

Remarquez comment nous utilisons un chemin relatif commençant par ./. Il s'agit d'une notation spéciale qui aide le pipeline de construction (alimenté par Webpack) à découvrir ce fichier.

Normalement, cela devrait suffire.

Utilisation du publicdossier

Si, pour une raison quelconque, vous préférez ne pas utiliser le pipeline de construction, et le faire à la place de la «manière classique», vous pouvez utiliser le publicdossier et y placer vos polices.

L'inconvénient de cette approche est que les fichiers n'obtiennent pas de hachage lorsque vous compilez pour la production, vous devrez donc mettre à jour leurs noms à chaque fois que vous les modifiez, sinon les navigateurs mettront en cache les anciennes versions.

Si vous voulez le faire de cette façon, placez les polices quelque part dans le publicdossier, par exemple, dans public/fonts/MyFont.woff. Si vous suivez cette approche, vous devez également mettre les fichiers CSS dans un publicdossier et ne pas les importer de JS car le mélange de ces approches sera très déroutant. Donc, si vous voulez toujours le faire, vous aurez un fichier comme public/index.css. Vous devrez ajouter manuellement <link>à cette feuille de style à partir de public/index.html:

<link rel="stylesheet" href="%PUBLIC_URL%/index.css">

Et à l'intérieur de celui-ci, vous utiliseriez la notation CSS régulière:

@font-face {
  font-family: 'MyFont';
  src: local('MyFont'), url(fonts/MyFont.woff) format('woff');
}

Remarquez comment j'utilise fonts/MyFont.woffcomme chemin. En effet, il se index.csstrouve dans le publicdossier, il sera donc servi à partir du chemin public (il s'agit généralement de la racine du serveur, mais si vous déployez sur les pages GitHub et définissez votre homepagechamp sur http://myuser.github.io/myproject, il sera servi à partir de /myproject). Cependant fontssont également dans le publicdossier, de sorte qu'ils seront servis de fontsrelativement (soit http://mywebsite.com/fontsou http://myuser.github.io/myproject/fonts). Par conséquent, nous utilisons le chemin relatif.

Notez que puisque nous évitons le pipeline de construction dans cet exemple, il ne vérifie pas que le fichier existe réellement. C'est pourquoi je ne recommande pas cette approche. Un autre problème est que notre index.cssfichier n'est pas minifié et ne reçoit pas de hachage. Cela va donc être plus lent pour les utilisateurs finaux, et vous risquez que les navigateurs mettent en cache les anciennes versions du fichier.

 Quelle manière utiliser?

Allez avec la première méthode («Utilisation des importations»). Je n'ai décrit que le second car c'est ce que vous avez essayé de faire (à en juger par votre commentaire), mais il présente de nombreux problèmes et ne devrait être que le dernier recours lorsque vous travaillez sur un problème.

Dan Abramov
la source
5
un exemple dans la documentation serait utile, j'étais aussi un peu confus
Tom
2
J'ai trouvé que je devais en fait utiliser l'url ./fonts/Myfont.woff et non ./Myfont.woff
th3morg
57
Si quelqu'un ajoute une ttfpolice, vous devez donner truetypeau lieu de ttfcomme paramètre au format* .
milkersarac
3
@milkersarac vous êtes le meilleur!
João Vilaça
19
Après @milkersarac si vous utilisez, otfvous devez mettre opentype.
Karl Taylor
46

Voici quelques façons de procéder:

1. Importation de la police

Par exemple, pour utiliser Roboto, installez le package en utilisant

yarn add typeface-roboto

ou

npm install typeface-roboto --save

Dans index.js:

import "typeface-roboto";

Il existe des packages npm pour de nombreuses polices open source et la plupart des polices Google. Vous pouvez voir toutes les polices ici . Tous les packages proviennent de ce projet .

2. Pour les polices hébergées par des tiers

Par exemple, les polices Google, vous pouvez accéder à fonts.google.com où vous pouvez trouver des liens que vous pouvez mettre dans votrepublic/index.html

capture d'écran de fonts.google.com

Ce sera comme

<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet">

ou

<style>
    @import url('https://fonts.googleapis.com/css?family=Montserrat');
</style>

3. Télécharger la police et l'ajouter dans votre code source.

Téléchargez la police. Par exemple, pour les polices google, vous pouvez accéder à fonts.google.com . Cliquez sur le bouton de téléchargement pour télécharger la police.

Déplacez la police dans le fontsrépertoire de votre srcrépertoire

src
|
`----fonts
|      |
|      `-Lato/Lato-Black.ttf
|       -Lato/Lato-BlackItalic.ttf
|       -Lato/Lato-Bold.ttf
|       -Lato/Lato-BoldItalic.ttf
|       -Lato/Lato-Italic.ttf
|       -Lato/Lato-Light.ttf
|       -Lato/Lato-LightItalic.ttf
|       -Lato/Lato-Regular.ttf
|       -Lato/Lato-Thin.ttf
|       -Lato/Lato-ThinItalic.ttf
|
`----App.css

Maintenant App.css, ajoutez ceci

@font-face {
  font-family: 'Lato';
  src: local('Lato'), url(./fonts/Lato-Regular.otf) format('opentype');
}

@font-face {
    font-family: 'Lato';
    font-weight: 900;
    src: local('Lato'), url(./fonts/Lato-Bold.otf) format('opentype');
}

@font-face {
    font-family: 'Lato';
    font-weight: 900;
    src: local('Lato'), url(./fonts/Lato-Black.otf) format('opentype');
}

Pour le ttfformat, vous devez mentionner format('truetype'). Pour woff,format('woff')

Vous pouvez maintenant utiliser la police dans les classes.

.modal-title {
    font-family: Lato, Arial, serif;
    font-weight: black;
}

4. Utilisation du package web-font-loader

Installer le package en utilisant

yarn add webfontloader

ou

npm install webfontloader --save

Dans src/index.js, vous pouvez l'importer et spécifier les polices nécessaires

import WebFont from 'webfontloader';

WebFont.load({
   google: {
     families: ['Titillium Web:300,400,700', 'sans-serif']
   }
});
sudo bangbang
la source
2
--save est par défaut avec npm 5 (2017)
NattyC
Merci pour le commentaire @Natalie, je suis content que npm ait fait ce changement.
sudo bangbang
@sudobangbang Merci, la solution n ° 3 a fonctionné pour moi. Cependant - y a-t-il un moyen de ne pas mettre de fontsdossier sous src, mais publicplutôt sous ? Je l'ai essayé, mais cela ne semble pas autorisé ...
Yossi Vainshtein
@YossiVainshtein, je ne pense pas. Lorsque vous utilisez les polices dans App.css, il doit également être compilé avec.
sudo bangbang
For ttf format, you have to mention format('truetype'). For woff, format('woff')l'a fait pour moi! Merci!
Joseph Briggs
7
  1. Accédez à Google Fonts https://fonts.google.com/
  2. Sélectionnez votre police comme illustré dans l'image ci-dessous:

entrez la description de l'image ici

  1. Copiez puis collez cette URL dans un nouvel onglet, vous obtiendrez le code css pour ajouter cette police. Dans ce cas, si vous allez à

https://fonts.googleapis.com/css?family=Spicy+Rice

Il s'ouvrira comme ceci:

entrez la description de l'image ici

4, copiez et collez ce code dans votre style.css et commencez simplement à utiliser cette police comme ceci:

      <Typography
          variant="h1"
          gutterBottom
          style={{ fontFamily: "Spicy Rice", color: "pink" }}
        >
          React Rock
        </Typography>

Résultat:

entrez la description de l'image ici

Hitesh Sahu
la source
1
Dans de nombreux cas (ex: réseaux d'entreprise), l'accès au CDN externe est bloqué par le pare-feu et cette méthode, bien que correcte, peut ne pas fonctionner. Nous avons plusieurs VLAN dans notre organisation et, à l'exception de l'informatique et de quelques autres, tous les VLAN bloquent l'accès CDN externe, ce qui signifie également que le contenu CDN de Google est également bloqué. J'y suis allé, j'ai fait ça.
AnBisw
2

Vous pouvez utiliser le module WebFont , ce qui simplifie grandement le processus.

render(){
  webfont.load({
     custom: {
       families: ['MyFont'],
       urls: ['/fonts/MyFont.woff']
     }
  });
  return (
    <div style={your style} >
      your text!
    </div>
  );
}
Delfino
la source
0

Je faisais de telles erreurs.

@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i&amp;subset=cyrillic,cyrillic-ext,latin-ext";
@import "https://use.fontawesome.com/releases/v5.3.1/css/all.css";

Cela fonctionne correctement de cette façon

@import url(https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i&amp;subset=cyrillic,cyrillic-ext,latin-ext);
@import url(https://use.fontawesome.com/releases/v5.3.1/css/all.css);
Yasin UYSAL
la source
0

J'ai passé toute la matinée à résoudre un problème similaire après avoir atterri sur cette question de pile. J'ai utilisé la première solution de Dan dans la réponse ci-dessus comme point de départ.

Problème

J'ai un environnement de développement (sur ma machine locale), de préparation et de production. Mes environnements de préparation et de production vivent sur le même serveur.

L'application est déployée pour la mise en scène via acmeserver/~staging/note-taking-appet la version de production vit acmeserver/note-taking-app(blâmez l'informatique).

Tous les fichiers multimédias tels que les polices se chargeaient parfaitement sur dev (ie, react-scripts start).

Cependant, lorsque j'ai créé et téléchargé des versions intermédiaires et de production, alors que les fichiers .csset .jsse chargeaient correctement, les polices ne l'étaient pas. Le .cssfichier compilé semblait avoir un chemin correct mais la requête http du navigateur recevait un chemin très incorrect (illustré ci-dessous).

Le main.fc70b10f.chunk.cssfichier compilé :

@font-face {
  font-family: SairaStencilOne-Regular;
  src: url(note-taking-app/static/media/SairaStencilOne-Regular.ca2c4b9f.ttf) ("truetype");
}

La requête http du navigateur est présentée ci-dessous. Notez comment il s'ajoute /static/css/lorsque le fichier de police se trouve tout simplement /static/media/ainsi que la duplication du dossier de destination. J'ai exclu que la configuration du serveur soit le coupable.

Le Refererest en partie en faute aussi.

GET /~staging/note-taking-app/static/css/note-taking-app/static/media/SairaStencilOne-Regular.ca2c4b9f.ttf HTTP/1.1
Host: acmeserver
Origin: http://acmeserver
Referer: http://acmeserver/~staging/note-taking-app/static/css/main.fc70b10f.chunk.css

Le package.jsonfichier avait la homepagepropriété définie sur ./note-taking-app. Cela causait le problème.

{
  "name": "note-taking-app",
  "version": "0.1.0",
  "private": true,
  "homepage": "./note-taking-app",
  "scripts": {
    "start": "env-cmd -e development react-scripts start",
    "build": "react-scripts build",
    "build:staging": "env-cmd -e staging npm run build",
    "build:production": "env-cmd -e production npm run build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  }
  //...
}

Solution

C'était long - mais la solution est de:

  1. changer la PUBLIC_URLvariable env en fonction de l'environnement
  2. supprimer la homepagepropriété du package.jsonfichier

Ci-dessous mon .env-cmdrcdossier. J'utilise .env-cmdrcplus régulièrement .envcar il garde tout ensemble dans un seul fichier.

{
  "development": {
    "PUBLIC_URL": "",
    "REACT_APP_API": "http://acmeserver/~staging/note-taking-app/api"
  },
  "staging": {
    "PUBLIC_URL": "/~staging/note-taking-app",
    "REACT_APP_API": "http://acmeserver/~staging/note-taking-app/api"
  },
  "production": {
    "PUBLIC_URL": "/note-taking-app",
    "REACT_APP_API": "http://acmeserver/note-taking-app/api"
  }
}

Le routage via react-router-domfonctionne bien aussi - utilisez simplement la PUBLIC_URLvariable env comme basenamepropriété.

import React from "react";
import { BrowserRouter } from "react-router-dom";

const createRouter = RootComponent => (
  <BrowserRouter basename={process.env.PUBLIC_URL}>
    <RootComponent />
  </BrowserRouter>
);

export { createRouter };

La configuration du serveur est définie pour acheminer toutes les demandes vers le ./index.htmlfichier.

Enfin, voici à quoi main.fc70b10f.chunk.cssressemble le fichier compilé après l'implémentation des modifications discutées.

@font-face {
  font-family: SairaStencilOne-Regular;
  src: url(/~staging/note-taking-app/static/media/SairaStencilOne-Regular.ca2c4b9f.ttf)
    format("truetype");
}

Matériel de lecture

puiu
la source