【问题标题】:Isolated styled-components with @font-face带有@font-face 的隔离样式组件
【发布时间】:2017-07-29 06:43:25
【问题描述】:

我正在使用https://github.com/styled-components/styled-components

我正在尝试为需要@font-face 的组件制定最佳策略。我想确保每个组件都独立于其上下文,因此我在每个组件上定义了font-family 样式。但是如果我在多个组件中使用injectGlobal,我会为同一个字体获得多个@font-face 规则。

我是否应该在我的 ThemeProvider 入口点组件中定义 @font-face 规则,并接受浏览器可能无法加载所需字体的事实?

【问题讨论】:

    标签: styled-components


    【解决方案1】:

    我同意

    我重新加载了

    import { createGlobalStyle } from 'styled-components';
    import { silver } from 'shared-components/themes/colors';
    
    export default createGlobalStyle`
        @font-face {
            font-family: "Proxima Nova";
            font-style: normal;
            font-weight: 300;
            font-display: swap;
            src: url("/static/media/fonts/proxima_nova/ProximaNova_300.otf");
        }
    
    

    然后反应创建应用程序

    【讨论】:

      【解决方案2】:

      injectGlobal 已弃用。使用 createGlobalStyle

      import { createGlobalStyle } from 'styled-components'
      
      export const GlobalStyle = createGlobalStyle`  
        body {
          font-family: 'Muli', sans-serif;
      
          h1 {
            font-weight: 800;
            font-size: 36px;
      
          p {
            font-size: 18px;
          }
        }
      `;
      

      然后你就可以在你的 App.js 中使用它了:

      import { GlobalStyle } from './styles/global'
      
      class App extends Component {
        render() {
      
          return (
            <ThemeProvider theme={theme}>
              <>
                <GlobalStyle/>
                <Container/>
              </>
            </ThemeProvider>
      
          )
        }
      }
      

      【讨论】:

      • 即使使用createGlobalStyle,我仍然会重新加载所有字体
      【解决方案3】:

      在 Chrome 的另一面:

      不要在 injectGlobal 中使用 @font-face 如果使用例如反应路由器。 您将在每条新加载的路线上重新绘制所有应用程序。 这就是为什么:

      在每条新路线上下载相同的字体文件。 只要您在单独的 .css 文件中包含 font-face - 如this github issue 中的最后一条评论所述,问题就会得到解决。

      【讨论】:

      • injectGlobal放在react-router外面怎么样?我甚至在ReactDOM.render() 之外使用injectGlobal,即在应用程序的最顶层,我没有为每个路线导航加载字体。
      • @Oleh 你是怎么做到的?将 injectGlobal 移到顶部 - 仍在重新加载字体
      • 可能这是浏览器特有的,因为 Edge 和 Firefox 不会在我每次使用路由导航时加载它们的字体,更不用说在刷新页面上也不会加载字体。 Chrome 每次都会加载字体......所以似乎是 chrome 引擎问题
      • @Oleh,是的,我忘了说这是一个特定于 chrome 的问题)
      【解决方案4】:

      这正是我们制作injectGlobal 的原因。如果您查看我们的docs,他们会说:

      我们不鼓励使用它。每个应用最多使用一次,包含在一个文件中。这是一个逃生舱口。仅将其用于罕见的 @font-face 定义或主体样式。

      所以我要做的是创建一个名为 global-styles.js 的 JS 文件,其中包含以下代码:

      // global-styles.js
      
      import { injectGlobal } from 'styled-components';
      
      injectGlobal`
        @font-face {
           font-family: 'My custom family';
           src: url('my-source.ttf');
        }
      `
      

      如您所见,我们在这里所做的只是注入一些全局样式——在本例中为 @font-face。完成这项工作所需的最后一件事是将此文件导入您的主入口点:

      // index.js
      
      import './global-styles.js'
      
      // More stuff here like ReactDOM.render(...)
      

      这意味着你的字体只被注入一次,但你的所有组件仍然可以通过font-family: 'My custom family' 访问它!

      这样做会给你一个不可见文本 (FOIT) 的闪烁,但这与 styled-components 无关 - 如果你使用香草 CSS,它会是一样的。要摆脱 FOIT,需要更高级的字体加载策略,而不仅仅是 @font-faceing。

      由于这与 styled-components 无关,我强烈建议观看这两集前端中心以了解更多关于如何最好地做到这一点:"Crafting Web Font Fallbacks""The Fastest Webfont Loader in the West"

      【讨论】:

      猜你喜欢
      • 2021-10-07
      • 2012-08-10
      • 2013-08-12
      • 1970-01-01
      • 2012-03-03
      • 1970-01-01
      • 2017-05-14
      • 2018-12-30
      • 1970-01-01
      相关资源
      最近更新 更多