Як додати шрифти для створення проектів на основі додатків?


177

Я використовую create-react-app і вважаю за краще це не робити eject.

Незрозуміло, куди повинні надходити шрифти, імпортовані через @ font-face та локально завантажені.

А саме я завантажую

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

Будь-які пропозиції?

- EDIT

Включаючи суть, на яку Ден посилається у своїй відповіді

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

2
Ви перевірили розділ "Додавання шрифтів" у своєму посібнику користувача?
Дан Абрамов

2
@DanAbramov у мене є, рекомендується імпортувати шрифт. Але я вважаю, що не зрозуміло (принаймні, не для мене), як це робити на практиці. Тим часом я зробив це gist.github.com/maximveksler/5b4f80c5ded20237c3deebc82a31dcd5, і, здається, це працює (повідомлення про веб-пакет, якщо він не може знайти файл шрифту), але я впевнений, що це не оптимальне рішення та приклад чи документальне оформлення тут допоможе. ти для досягнення!
Максим Векслер

2
Я відповів. Ваш підхід для мене виглядає неправильним: %PUBLIC_URL%не можна працювати (і є зайвим) у файлі CSS. Крім того, як описано в посібнику, ви повинні використовувати імпорт JS майже у всіх випадках, а не загальнодоступну папку.
Дан Абрамов

Чи є якась утиліта / пакет для сканування вказаної папки на шрифти та генерування файлу сценарію з усіма варіаціями шрифту? Набридливо писати, що все вручну
helloworld

Відповіді:


289

Є два варіанти:

Використання імпорту

Це запропонований варіант. Це забезпечує, що ваші шрифти проходять через конвеєр збірки, отримують хеші під час компіляції, щоб кешування браузера працювало правильно, і ви отримуєте помилки компіляції, якщо файли відсутні.

Як описано в "Додавання зображень, шрифтів і файлів" , вам потрібно мати файл CSS, імпортований з JS. Наприклад, src/index.jsімпорт за замовчуванням src/index.css:

import './index.css';

CSS-файл, подібний до цього, проходить через конвеєр збірки та може посилатися на шрифти та зображення. Наприклад, якщо ви введете шрифт src/fonts/MyFont.woff, ви можете index.cssвключити такий:

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

Зауважте, як ми використовуємо відносний шлях, починаючи з ./. Це спеціальна примітка, яка допомагає побудувати конвеєр (на базі Webpack) виявити цей файл.

Зазвичай цього має бути достатньо.

Використання publicпапки

Якщо з якоїсь причини ви віддаєте перевагу не використовувати конвеєр збірки, а замість цього робите це «класичним способом», можете скористатися publicпапкою і розмістити там свої шрифти.

Мінусом цього підходу є те, що файли не отримують хеш-файлів під час компіляції для виробництва, тому вам доведеться оновлювати їх імена щоразу, коли ви їх змінюєте, або браузери кешуватимуть старі версії.

Якщо ви хочете зробити це таким чином, покладіть шрифти десь у publicпапку, наприклад, у public/fonts/MyFont.woff. Якщо ви дотримуєтесь цього підходу, вам слід також помістити файли CSS у publicпапку, а не імпортувати їх із JS, оскільки змішування цих підходів буде дуже заплутаним. Отже, якщо ви все ще хочете це зробити, у вас буде такий файл, як public/index.css. Вам потрібно буде вручну додати <link>до цієї таблиці стилів з public/index.html:

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

І всередині нього ви б використовували звичайні позначення CSS:

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

Зверніть увагу, як я використовую fonts/MyFont.woffяк шлях. Це тому, що index.cssзнаходиться в publicпапці, тому воно буде подаватися з відкритого шляху (зазвичай це корінь сервера, але якщо ви розгортаєтесь на GitHub Pages і встановлюєте своє homepageполе http://myuser.github.io/myproject, воно буде подано з /myproject). Однак fontsвони також знаходяться в publicпапці, тому вони будуть подаватися з fontsвідносно (або http://mywebsite.com/fontsабо http://myuser.github.io/myproject/fonts). Тому ми використовуємо відносний шлях.

Зауважте, що оскільки у цьому прикладі ми уникаємо конвеєра збірки, він не підтверджує, що файл існує насправді. Ось чому я не рекомендую такий підхід. Інша проблема полягає в тому, що наш index.cssфайл не змінюється і не отримує хеш. Таким чином, для кінцевих користувачів це стане повільніше, і ви ризикуєте браузерам кешувати старі версії файлу.

 Який спосіб використовувати?

Перейдіть за першим методом ("Використання імпорту"). Я описав лише друге, оскільки саме це ви намагалися зробити (судячи з вашого коментаря), але у нього є багато проблем і він повинен бути останнім заходом, коли ви працюєте над якоюсь проблемою.


5
приклад в документах був би корисним, я також трохи розгубився
Том,

2
Я виявив, що мені насправді довелося використовувати URL ./fonts/Myfont.woff, а не ./Myfont.woff
th3morg

57
Якщо хтось додає ttfшрифт, вам слід вказати truetypeзамість ttfпараметра format* .
milkersarac

3
@milkersarac ти найкращий!
Жоао Вілача

19
Слідкуючи за @milkersarac, якщо ви використовуєте, otfвам потрібно поставити opentype.
Карл Тейлор

46

Ось кілька способів зробити це:

1. Імпорт шрифту

Наприклад, для використання Roboto встановіть пакет за допомогою

yarn add typeface-roboto

або

npm install typeface-roboto --save

У index.js:

import "typeface-roboto";

Існують пакети npm для багатьох шрифтів з відкритим кодом та більшості шрифтів Google. Ви можете побачити всі шрифти тут . Усі пакунки від цього проекту .

2. Для шрифтів, розміщених третьою стороною

Наприклад, шрифти Google, ви можете зайти на fonts.google.com, де ви можете знайти посилання, які можна розмістити у своїхpublic/index.html

скріншот fonts.google.com

Це буде як

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

або

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

3. Завантаження шрифту та додавання його у вихідний код.

Завантажте шрифт. Наприклад, для шрифтів Google можна перейти на fonts.google.com . Натисніть кнопку завантажити, щоб завантажити шрифт.

Перемістіть шрифт до fontsкаталогу у своєму srcкаталозі

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

Тепер App.cssдодайте це

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

Щодо ttfформату, ви повинні згадати format('truetype'). для woff,format('woff')

Тепер ви можете використовувати шрифт у класах.

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

4. Використання пакету веб-завантажувачів шрифтів

Встановити пакет за допомогою

yarn add webfontloader

або

npm install webfontloader --save

В src/index.js, ви можете імпортувати це і вказати шрифти , необхідні

import WebFont from 'webfontloader';

WebFont.load({
   google: {
     families: ['Titillium Web:300,400,700', 'sans-serif']
   }
});

2
--save за замовчуванням з npm 5 (2017)
NattyC

Дякую за коментар @Natalie, я радий, що npm внесло це зміни.
sudo bangbang

@sudobangbang Спасибі, рішення №3 працювало для мене. Однак - чи є спосіб не помістити fontsпапку src, а під неї public? Я спробував це, але, схоже, це не дозволено ...
Йоссі Вайнштейн,

@YossiVainshtein, я так не думаю. Оскільки ви використовуєте шрифти в App.css, його також слід компілювати.
sudo bangbang

For ttf format, you have to mention format('truetype'). For woff, format('woff')зробив це для мене! спасибі!
Джозеф Бріггс

7
  1. Перейдіть на сторінку https://fonts.google.com/ Шрифти Google
  2. Виберіть свій шрифт, як зображено на зображенні нижче:

введіть тут опис зображення

  1. Скопіюйте та вставте цей URL на новій вкладці, ви отримаєте код css, щоб додати цей шрифт. У цьому випадку, якщо ви переходите до

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

Він відкриється так:

введіть тут опис зображення

4, Скопіюйте та вставте цей код у свій style.css і просто почніть використовувати такий шрифт:

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

Результат:

введіть тут опис зображення


1
У багатьох випадках (наприклад, корпоративні мережі) доступ до зовнішнього CDN блокується брандмауером, і цей метод, хоча і правильний, може не працювати. У нашій організації є декілька VLAN, за винятком ІТ та кількох інших, всі VLAN блокують зовнішній доступ CDN, що також означає, що вміст CDN від Google також блокується. Був там зробив те.
AnBisw

2

Можна використовувати модуль WebFont , що значно спрощує процес.

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

0

Я робив подібні помилки.

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

Це правильно працює таким чином

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

0

Я провів цілий ранок, вирішуючи подібну проблему після того, як приземлився на це питання про стек. Я використовував перше рішення Дана у відповіді вище, як точку стрибка.

Проблема

У мене є розробник (це на моїй локальній машині), постановочне та виробниче середовище. Моє середовище постановки та виробництва живе на одному сервері.

Додаток розгорнуто для інсценізації, acmeserver/~staging/note-taking-appі виробнича версія живе в acmeserver/note-taking-app(винна ІТ).

Усі медіафайли, такі як шрифти, ідеально завантажувались на dev (тобто react-scripts start).

Однак, коли я створював і завантажував постановки та збірки виробництва, поки файли .cssта .jsфайли завантажувались належним чином, шрифтів не було. Схоже, компільований .cssфайл мав правильний шлях, але http-запит браузера отримував дуже неправильний шлях (показаний нижче).

Складений main.fc70b10f.chunk.cssфайл:

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

Http-запит браузера показано нижче. Зверніть увагу, як він додається, /static/css/коли файл шрифту просто живе /static/media/, а також дублює цільову папку. Я виключив винуватця конфігурації сервера.

RefererЧастково з вини теж.

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

У package.jsonфайлі було встановлено homepageвластивість ./note-taking-app. Це спричинило проблему.

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

Рішення

Це було довго, але це рішення:

  1. зміни PUBLIC_URLзмінної env залежно від середовища
  2. видаліть homepageвластивість з package.jsonфайлу

Нижче мій .env-cmdrcфайл. Я використовую .env-cmdrcнад регулярним, .envоскільки він зберігає все в одному файлі.

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

Маршрутизація через також react-router-domпрацює чудово - просто використовуйте PUBLIC_URLзмінну env як basenameвластивість.

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

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

export { createRouter };

Конфігурація сервера встановлена ​​для маршрутизації всіх запитів у ./index.htmlфайл.

Нарешті, ось, як main.fc70b10f.chunk.cssвиглядає складений файл після впровадження обговорених змін.

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

Матеріал для читання

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.