Wie füge ich Schriftarten zu Projekten hinzu, die auf Apps basieren?

176

Ich benutze die Create-React-App und ziehe es vor, dies nicht zu tun eject.

Es ist nicht klar, wohin über @ font-face importierte und lokal geladene Schriftarten gehen sollen.

Ich lade nämlich

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

Irgendwelche Vorschläge?

- BEARBEITEN

Einschließlich des Kerns, auf den sich Dan in seiner Antwort bezieht

  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
quelle
2
Haben Sie im Benutzerhandbuch den Abschnitt "Hinzufügen von Schriftarten" aktiviert?
Dan Abramov
2
@ DanAbramov Ich habe, die Empfehlung ist, die Schriftart zu importieren. Aber ich denke, es ist nicht klar (zumindest nicht für mich), wie es in der Praxis gemacht werden soll. In der Zwischenzeit habe ich dies getan. Gist.github.com/maximveksler/5b4f80c5ded20237c3deebc82a31dcd5 und es scheint zu funktionieren ( Webpack- Warnungen, wenn keine Schriftartdatei gefunden werden kann), aber ich bin sicher, dass dies nicht die optimale Lösung und ein Beispiel ist oder es hier dokumentieren zu lassen würde helfen. ty für die Reichweite!
Maxim Veksler
2
Ich antwortete. Ihr Ansatz sieht für mich falsch aus: %PUBLIC_URL%Kann in einer CSS-Datei nicht funktionieren (und ist unnötig). Wie im Handbuch beschrieben, sollten Sie in fast allen Fällen JS-Importe verwenden, nicht den öffentlichen Ordner.
Dan Abramov
Gibt es ein Dienstprogramm / Paket, um den angegebenen Ordner nach Schriftarten zu durchsuchen und die Skriptdatei mit allen Schriftartenvarianten zu generieren? Es ist mühsam, das alles manuell zu schreiben
helloworld

Antworten:

283

Es gibt zwei Möglichkeiten:

Importe verwenden

Dies ist die vorgeschlagene Option. Es stellt sicher, dass Ihre Schriftarten die Build-Pipeline durchlaufen, beim Kompilieren Hashes abrufen, damit das Browser-Caching ordnungsgemäß funktioniert, und dass Kompilierungsfehler angezeigt werden, wenn die Dateien fehlen.

Wie unter „Hinzufügen von Bildern, Schriftarten und Dateien“ beschrieben , muss eine CSS-Datei aus JS importiert werden. Zum Beispiel standardmäßig src/index.jsImporte src/index.css:

import './index.css';

Eine solche CSS-Datei durchläuft die Build-Pipeline und kann auf Schriftarten und Bilder verweisen. Wenn Sie beispielsweise eine Schriftart eingeben src/fonts/MyFont.woff, können Sie index.cssFolgendes einschließen:

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

Beachten Sie, wie wir einen relativen Pfad verwenden, der mit beginnt ./. Dies ist eine spezielle Notation, mit der die Build-Pipeline (unterstützt von Webpack) diese Datei erkennen kann.

Normalerweise sollte dies ausreichen.

Mit publicOrdner

Wenn Sie aus irgendeinem Grund die Build-Pipeline nicht verwenden möchten und dies stattdessen auf „klassische Weise“ tun möchten , können Sie den publicOrdner verwenden und Ihre Schriftarten dort ablegen.

Der Nachteil dieses Ansatzes ist, dass die Dateien beim Kompilieren für die Produktion keine Hashes erhalten, sodass Sie ihre Namen jedes Mal aktualisieren müssen, wenn Sie sie ändern. Andernfalls werden die alten Versionen von Browsern zwischengespeichert.

Wenn Sie dies auf diese Weise tun möchten, legen Sie die Schriftarten irgendwo in dem publicOrdner ab, z. B. in public/fonts/MyFont.woff. Wenn Sie diesem Ansatz folgen, sollten Sie auch CSS-Dateien in publicOrdner ablegen und nicht aus JS importieren, da das Mischen dieser Ansätze sehr verwirrend sein wird. Wenn Sie es also trotzdem tun möchten, haben Sie eine Datei wie public/index.css. Sie müssten <link>dieses Stylesheet manuell hinzufügen von public/index.html:

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

Und darin würden Sie die reguläre CSS-Notation verwenden:

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

Beachten Sie, wie ich fonts/MyFont.woffals Pfad verwende. Dies liegt daran, dass index.csses sich im publicOrdner befindet, sodass es über den öffentlichen Pfad bereitgestellt wird (normalerweise ist es das Serverstammverzeichnis, aber wenn Sie es auf GitHub Pages bereitstellen und Ihr homepageFeld auf festlegen http://myuser.github.io/myproject, wird es von bereitgestellt /myproject). Befinden sich fontsjedoch auch im publicOrdner, so werden sie fontsrelativ (entweder http://mywebsite.com/fontsoder http://myuser.github.io/myproject/fonts) bedient. Deshalb verwenden wir den relativen Pfad.

Da wir in diesem Beispiel die Build-Pipeline vermeiden, wird nicht überprüft, ob die Datei tatsächlich vorhanden ist. Deshalb empfehle ich diesen Ansatz nicht. Ein weiteres Problem ist, dass unsere index.cssDatei nicht minimiert wird und keinen Hash erhält. Für die Endbenutzer wird es also langsamer, und Sie riskieren, dass die Browser alte Versionen der Datei zwischenspeichern.

 Welche Art zu verwenden?

Fahren Sie mit der ersten Methode fort („Verwenden von Importen“). Ich habe nur den zweiten beschrieben, da Sie dies versucht haben (nach Ihrem Kommentar zu urteilen), aber er hat viele Probleme und sollte nur der letzte Ausweg sein, wenn Sie an einem Problem arbeiten.

Dan Abramov
quelle
5
Ein Beispiel in den Dokumenten wäre nützlich, ich war auch ein wenig verwirrt
Tom
2
Ich fand, dass ich tatsächlich die URL ./fonts/Myfont.woff und nicht ./Myfont.woff verwenden musste
th3morg
55
Wenn jemand eine ttfSchriftart hinzufügt , sollten Sie dem *truetype statt ttfals Parameter geben . format
Milkersarac
3
@milkersarac du bist der Beste!
João Vilaça
19
Folgen Sie @milkersarac, wenn Sie verwenden otf, müssen Sie setzen opentype.
Karl Taylor
45

Hier sind einige Möglichkeiten, dies zu tun:

1. Schriftart importieren

Wenn Sie beispielsweise Roboto verwenden möchten, installieren Sie das Paket mit

yarn add typeface-roboto

oder

npm install typeface-roboto --save

In index.js:

import "typeface-roboto";

Es gibt npm-Pakete für viele Open Source-Schriftarten und die meisten Google-Schriftarten. Sie können alle Schriftarten hier sehen . Alle Pakete stammen aus diesem Projekt .

2. Für Schriftarten, die von Dritten gehostet werden

Zum Beispiel können Sie unter Google Fonts unter fonts.google.com Links finden, die Sie in Ihre einfügen könnenpublic/index.html

Screenshot von fonts.google.com

Es wird so sein

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

oder

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

3. Laden Sie die Schriftart herunter und fügen Sie sie Ihrem Quellcode hinzu.

Laden Sie die Schriftart herunter. Für Google-Schriftarten können Sie beispielsweise zu fonts.google.com gehen . Klicken Sie auf den Download-Button, um die Schriftart herunterzuladen.

Verschieben Sie die Schriftart in das fontsVerzeichnis in Ihrem srcVerzeichnis

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

Fügen App.cssSie dies jetzt hinzu

@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');
}

Für das ttfFormat müssen Sie erwähnen format('truetype'). Zumwoff ,format('woff')

Jetzt können Sie die Schriftart in Klassen verwenden.

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

4. Verwenden des Web-Font-Loader-Pakets

Installieren Sie das Paket mit

yarn add webfontloader

oder

npm install webfontloader --save

In src/index.jskönnen Sie dies importieren und die benötigten Schriftarten angeben

import WebFont from 'webfontloader';

WebFont.load({
   google: {
     families: ['Titillium Web:300,400,700', 'sans-serif']
   }
});
Sudo Bangbang
quelle
2
- Speichern ist Standard mit npm 5 (2017)
NattyC
Vielen Dank für den Kommentar @Natalie, ich bin froh, dass npm diese Änderung vorgenommen hat.
Sudo Bangbang
@sudobangbang Danke, Lösung 3 hat bei mir funktioniert. Gibt es jedoch eine Möglichkeit, fontsOrdner nicht unter src, sondern unter publiczu platzieren? Ich habe es versucht, aber es scheint nicht erlaubt ...
Yossi Vainshtein
@ YossiVainshtein, das glaube ich nicht. Da Sie die Schriftarten in App.css verwenden, sollten diese auch damit kompiliert werden.
Sudo Bangbang
For ttf format, you have to mention format('truetype'). For woff, format('woff')habe es für mich getan! Danke!
Joseph Briggs
6
  1. Gehen Sie zu Google Fonts https://fonts.google.com/
  2. Wählen Sie Ihre Schriftart wie im Bild unten dargestellt:

Geben Sie hier die Bildbeschreibung ein

  1. Kopieren Sie diese URL und fügen Sie sie in einen neuen Tab ein. Sie erhalten den CSS-Code zum Hinzufügen dieser Schriftart. In diesem Fall, wenn Sie zu gehen

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

Es wird so geöffnet:

Geben Sie hier die Bildbeschreibung ein

4, Kopieren Sie diesen Code und fügen Sie ihn in Ihre style.css ein. Verwenden Sie diese Schriftart einfach wie folgt:

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

Ergebnis:

Geben Sie hier die Bildbeschreibung ein

Hitesh Sahu
quelle
1
In vielen Fällen (z. B. Unternehmensnetzwerke) wird der Zugriff auf externes CDN durch eine Firewall blockiert, und diese Methode funktioniert möglicherweise nicht, obwohl sie korrekt ist. Wir haben mehrere VLANs in unserer Organisation und außer der IT und wenigen anderen blockieren alle VLANs den externen CDN-Zugriff, was auch bedeutet, dass das Content-CDN von Google ebenfalls blockiert ist. Kenne ich schon.
AnBisw
2

Sie können das WebFont- Modul verwenden, das den Vorgang erheblich vereinfacht.

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

Ich habe solche Fehler gemacht.

@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";

Auf diese Weise funktioniert es richtig

@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
quelle
0

Ich habe den ganzen Morgen damit verbracht, ein ähnliches Problem zu lösen, nachdem ich auf dieser Stapelfrage gelandet war. Ich habe Dans erste Lösung in der obigen Antwort als Startpunkt verwendet.

Problem

Ich habe eine Entwickler- (dies ist auf meinem lokalen Computer), Staging- und Produktionsumgebung. Meine Staging- und Produktionsumgebungen befinden sich auf demselben Server.

Die App wird für das Staging über bereitgestellt acmeserver/~staging/note-taking-appund die Produktionsversion lebt bei acmeserver/note-taking-app(Schuld an der IT).

Alle Mediendateien wie Schriftarten wurden auf dev (dh react-scripts start) einwandfrei geladen .

Als ich jedoch Staging- und Produktions-Builds erstellte und hochlud, während die Dateien .cssund .jsordnungsgemäß geladen wurden, waren dies bei den Schriftarten nicht der Fall. Das kompilierte.css Datei schien einen korrekten Pfad zu haben, aber die http-Anforderung des Browsers erhielt einen sehr falschen Pfad (siehe unten).

Die kompilierte main.fc70b10f.chunk.cssDatei:

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

Die http-Anfrage des Browsers wird unten angezeigt. Beachten Sie, wie es hinzugefügt wird, /static/css/wenn die Schriftartdatei nur noch vorhanden ist, und /static/media/wie der Zielordner dupliziert wird. Ich habe ausgeschlossen, dass die Serverkonfiguration der Schuldige ist.

Das Refererist auch teilweise schuld.

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

Für die package.jsonDatei wurde die homepageEigenschaft festgelegt ./note-taking-app. Dies verursachte das Problem.

{
  "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"
  }
  //...
}

Lösung

Das war langwierig - aber die Lösung ist:

  1. ändere das PUBLIC_URL env-Variable abhängig von der Umgebung
  2. Entfernen Sie die homepageEigenschaft aus der package.jsonDatei

Unten ist meine .env-cmdrcDatei. Ich benutze .env-cmdrcüber regelmäßig, .envweil es alles in einer Datei zusammenhält.

{
  "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"
  }
}

Das Routing über react-router-domfunktioniert auch einwandfrei - verwenden Sie einfach die PUBLIC_URLenv-Variable als basenameEigenschaft.

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

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

export { createRouter };

Die Serverkonfiguration ist so eingestellt, dass alle Anforderungen an die ./index.htmlDatei weitergeleitet werden.

Schließlich sehen Sie hier, wie die kompilierte main.fc70b10f.chunk.cssDatei aussieht, nachdem die besprochenen Änderungen implementiert wurden.

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

Lesestoff

puiu
quelle