自定义字体在主题中设置,但在标题组件中未呈现的原因是什么?

huangapple go评论67阅读模式
英文:

Why are custom fonts set in theme not rendering in the Heading component?

问题

阅读和学习 Chakra UI,尝试为 Heading 组件设置默认的 fontFamily。我已经尝试在 heading 中设置的字体:

import { extendTheme } from '@chakra-ui/react';

const theme = extendTheme({
  fonts: {
    heading: `'Custom Font', sans-serif`,
  },
  styles: {
    global: {
      h1: {
        fontFamily: 'heading',
        color: 'blue',
      },
    },
  },
})

export default theme

颜色变化了,但字体没有改变。

编辑:根据答案和进一步的研究。除非我的方法不正确,否则似乎存在一个活跃的 问题 ,因此我将概述我所做的一切:

src/theme/index.js:

import { extendTheme, theme as defaultTheme } from '@chakra-ui/react';

const theme = extendTheme(
  {
    ...defaultTheme, // 我认为这不是必需的,但在一个答案中有提到
    fonts: {
      heading: `'Foo Bar', sans-serif`,
    },
    
  },
)

export default theme

字体不在 Fontsource 中,所以尝试了 @font-face 的方法:

src/theme/Fonts.js:

import React from 'react';
import { Global } from '@emotion/react';

const Fonts = () => (
  <Global
    styles={`
    @font-face {
      font-family: 'Foo Bar';
      font-style: normal;
      font-weight: normal;
      font-display: swap;
      src: local('Foo Bar'), url('./fonts/Foo-Bar.woff2') format('woff2');
    }
    `}
  />
)

export default Fonts;

字体存储在以下目录结构中:

src/theme/fonts/Foo-Bar.woff2

Gatsby 包装器:

import React from 'react';
import PropTypes from 'prop-types';
import { ChakraProvider } from '@chakra-ui/react';

// 主题
import theme from './src/theme';
import Fonts from './src/theme/Fonts';

function RootWrapper({ element }) {
  return (
    <ChakraProvider theme={theme}>
      <Fonts /> {/* 字体在这里 */}
      {element}
    </ChakraProvider>
  )
}

RootWrapper.propTypes = {
  element: PropTypes.node.isRequired,
}

export default RootWrapper;

当我记录主题时,我可以看到:

fonts: {
  heading: Foo Bar
}

根据下面的答案,当我检查 var(--chakra-fonts-heading); 时,它仍然显示:

--chakra-fonts-heading: -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";

我唯一能让自定义字体正常工作的方式是使用 Text 并引入一个 textStyle

<Text as="h1" textStyle="h1">test</Text>

我认为这种方法忽略了 Heading 应该是什么。

研究:

依赖项:

"@chakra-ui/gatsby-plugin": "^3.1.3",
"@chakra-ui/icons": "^2.1.0",
"@chakra-ui/react": "^2.8.0",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",

为什么默认情况下自定义字体不会呈现,只有在传递为 textStyle 时才会呈现?如何在主题默认情况下为所有标题使用标题字体?

英文:

Reading and learning Chakra UI and trying to set a default fontFamily for the Heading component I've tried to implement the font I've set in heading:

import { extendTheme } from &#39;@chakra-ui/react&#39;

const theme = extendTheme({
  fonts: {
    heading: `&#39;Custom Font&#39;, sans-serif`,
  },
  styles: {
    global: {
      h1: {
        fontFamily: &#39;heading&#39;,
        color: &#39;blue&#39;,
      },
    },
  },
})

export default theme

color changes but the font will not.


Edit after answer and further research. This seems to be an active issue unless my approach is incorrect so I will outline everything I've done:

src/theme/index.js:

import { extendTheme, theme as defaultTheme } from &#39;@chakra-ui/react&#39;

const theme = extendTheme(
  {
    ...defaultTheme, // Dont think this is needed but was in an answer
    fonts: {
      heading: `&#39;Foo Bar&#39;, sans-serif`,
    },
    
  },
)

export default theme

Font isn't on Fontsource so tried the @font-face approach:

src/theme/Fonts.js:

import React from &#39;react&#39;
import { Global } from &#39;@emotion/react&#39;

const Fonts = () =&gt; (
  &lt;Global
    styles={`
    @font-face {
      font-family: &#39;Foo Bar&#39;;
      font-style: normal;
      font-weight: normal;
      font-display: swap;
      src: local(&#39;Foo Bar&#39;), url(&#39;./fonts/Foo-Bar.woff2&#39;) format(&#39;woff2&#39;);
    }
    `}
  /&gt;
)

export default Fonts

font is stored in the directory structure:

src/theme/fonts/Foo-Bar.woff2

Gatsby Wrapper:

import React from &#39;react&#39;
import PropTypes from &#39;prop-types&#39;
import { ChakraProvider } from &#39;@chakra-ui/react&#39;

// Theme
import theme from &#39;./src/theme&#39;
import Fonts from &#39;./src/theme/Fonts&#39;

function RootWrapper({ element }) {
  return (
    &lt;ChakraProvider theme={theme}&gt;
      &lt;Fonts /&gt; // &lt;!--- FONTS HERE
      {element}
    &lt;/ChakraProvider&gt;
  )
}

RootWrapper.propTypes = {
  element: PropTypes.node.isRequired,
}

export default RootWrapper

When I log the theme I can see:

fonts: {
  heading: Foo Bar
}

Per the answer below when I check var(--chakra-fonts-heading); it still shows:

--chakra-fonts-heading: -apple-system,BlinkMacSystemFont,&quot;Segoe UI&quot;,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;,&quot;Segoe UI Symbol&quot;;

The only way I can get custom fonts to work is to use Text and bring in a textStyle:

&lt;Text as=&quot;h1&quot; textStyle=&quot;h1&quot;&gt;test&lt;/Text&gt;

I think this approach dismisses what Heading is supposed to be for.

Research:

dependencies:

&quot;@chakra-ui/gatsby-plugin&quot;: &quot;^3.1.3&quot;,
&quot;@chakra-ui/icons&quot;: &quot;^2.1.0&quot;,
&quot;@chakra-ui/react&quot;: &quot;^2.8.0&quot;,
&quot;@emotion/react&quot;: &quot;^11.11.1&quot;,
&quot;@emotion/styled&quot;: &quot;^11.11.0&quot;,

why will a custom fonts not render by default but only when passed as a textStyle? How can I, by theme default use a heading font for all headers?

答案1

得分: 1

我怀疑这可能是一个缓存问题,根据我之前在Gatsby上遇到的问题,运行gatsby clean可以解决这些问题。根据您提供的信息,我无法复现这个问题 - 标题字体在多种配置下都显示为我,使用两种不同的字体,这就是我怀疑这可能是开发环境异常的原因。

我无法准确确定为什么它不起作用,但我将分享对我有效的解决方案。

对于使用Gatsby、@chakra-ui/react和@chakra-ui/gatsby-plugin:

  1. 导入本地字体
    Gatsby 使用本地字体参考

    1. 上传您的字体。在这个示例中,我将它们上传到src/fonts,或者根据用例也可以上传到static文件夹。
    2. 创建一个包含@font-face的CSS文件。我在src/fonts.css中创建了示例。
    @font-face {
        font-family: "Open Sans";
        font-style: normal;
        font-weight: 400;
        font-display: swap;
        src: url("./fonts/OpenSans-Regular.ttf") format("truetype");
    }
    
    1. 创建/编辑根文件夹中的gatsby-browser.js,并添加以下内容以全局加载字体。
      Gatsby 全局样式
    import "./src/fonts.css";
    
    1. 创建/编辑根文件夹中的gatsby-ssr.js以预加载您的字体文件。
      gatsby-ssr
    import * as React from "react";
    
    export const onRenderBody = ({ setHeadComponents }) => {
        setHeadComponents([
            <link
                rel="preload"
                href="./src/fonts/OpenSans-Regular.ttf"
                as="font"
                type="font/ttf"
                crossOrigin="anonymous"
                key="yourFontKey"
            />,
        ])
    }
    
  2. 创建Chakra主题文件的影子以进行自定义
    Chakra Gatsby 插件参考

    1. 创建src/@chakra-ui/gatsby-plugin/theme.js。Chakra gatsby-plugin会自动添加ChakraProvider包装器,所以除非您要做一些自定义操作,否则不需要单独添加它。
    2. 添加您的自定义内容。以下是标题的示例:
    import { extendTheme } from '@chakra-ui/react';
    
    const theme = {
        fonts: {
            heading: `'Open Sans', sans-serif`
        }
    }
    
    export default extendTheme(theme);
    
  3. 重新启动Gatsby服务器

    1. (可选)运行gatsby clean以清除缓存 - 有时这可以解决新/更改的字体和其他显示问题。
    2. 重新启动Gatsby服务器。

工作示例


原始答案:如何为Chakra UI主题设置Heading组件的默认字体?

我尝试了您的第一个代码片段,并且对我来说成功运行。

对我来说,以下内容适用于导入和设置Heading组件(以及默认使用Chakra 'heading'字体的任何其他组件)的字体系列:

import { extendTheme } from "@chakra-ui/react";
import '@fontsource-variable/yourFont';

const myTheme = extendTheme({
    fonts: {
        heading: `'yourFont Variable', sans-serif`
    }
})

export default myTheme;

Heading组件已经在其默认主题样式中应用了Chakra标题字体系列(请参阅上面的Heading链接以查看源代码,第4行)。要检查浏览器是否尝试应用字体,请在开发工具中选择您的标题组件,并检查CSS是否具有font-family: var(--chakra-fonts-heading);,这表示正在应用Chakra 'heading'样式。如果设置了这个并且主题--chakra-fonts-heading的CSS显示了正确的字体,但字体在浏览器中不显示,可能存在字体导入/渲染的问题。我注意到有时候安装新字体后,我必须停止/启动服务器才能使它们生效。

希望这有所帮助!

英文:

Edit for additional information provided

I'm suspicious that it could be a cache issue based on previous issues I've seen with Gatsby and running a gatsby clean resolving them. I haven't been able to recreate the issue based on what you've provided - the heading font displays for me in multiple configurations with two different fonts, which is why I'm wondering if it's a dev environment anomaly.

I can't pinpoint why specifically it's not working, but I'll share a solution that works for me.

With Gatsby, @chakra-ui/react, and @chakra-ui/gatsby-plugin:

1. Import local fonts

Gatsby Using Local Fonts Reference

  1. Upload your fonts. I uploaded mine to src/fonts in this example. Alternatively to the static folder depending on use case.
  2. Create a CSS file with @font-face. I created the example in src/fonts.css.
@font-face {
    font-family: &quot;Open Sans&quot;;
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url(&quot;./fonts/OpenSans-Regular.ttf&quot;) format(&quot;truetype&quot;);
}
  1. Create/edit gatsby-browser.js in the root folder and add this to load the fonts globally. Gatsby Global Styles
import &quot;./src/fonts.css&quot;
  1. Create/edit gatsby-ssr.js in root folder to preload your font files. gatsby-ssr
import * as React from &quot;react&quot;

export const onRenderBody = ({ setHeadComponents }) =&gt; {
    setHeadComponents([
        &lt;link
            rel=&quot;preload&quot;
            href=&quot;./src/fonts/OpenSans-Regular.ttf&quot;
            as=&quot;font&quot;
            type=&quot;font/ttf&quot;
            crossOrigin=&quot;anonymous&quot;
            key=&quot;yourFontKey&quot;
        /&gt;,
    ])
}

2. Create a shadow of the Chakra theme file for customizations

Chakra Gatsby Plugin Reference

  1. Create src/@chakra-ui/gatsby-plugin/theme.js. The Chakra gatsby-plugin automatically adds the ChakraProvider wrapper, so there's no need to add it separately unless you're doing something custom.
  2. Add your customizations. Heading example below:
import { extendTheme } from &#39;@chakra-ui/react&#39;

const theme = {
   fonts: {
       heading: `&#39;Open Sans&#39;, sans-serif`
   }
}

export default extendTheme(theme);

3. Restart Gatsby server

  1. (Optional) gatsby clean to clear the cache - this sometimes resolves new/changed font and other display issues.
  2. Restart the Gatsby server.

Working sandbox example


Original answer to: Chakra UI theming how to set default fontFamily for Heading component?

I tried your first code snippet with a custom font and it's working successfully for me.

This is what works for me to import and set font families for the Heading component (and any other components that by default use the Chakra 'heading' font):

import {extendTheme} from &quot;@chakra-ui/react&quot;;
import &#39;@fontsource-variable/yourFont&#39;;

const myTheme = extendTheme({
    fonts: {
        heading: `&#39;yourFont Variable&#39;, sans-serif`
    }
})

export default myTheme;


The Heading component already has the Chakra heading font family applied in their default theme styles (see Heading link above for source code, line 4).

To check if the font is attempting to apply in the browser, select your heading component in dev tools and check if the CSS has font-family: var(--chakra-fonts-heading);, which means it's getting the Chakra 'heading' style applied. If that's set and the theme --chakra-fonts-heading CSS shows the correct fonts, yet the font is not displaying in the browser, there might be an issue with the font import/render. I've noticed sometimes after I install new fonts I have to stop/start the server for them to pick up.

Hope this helps!

huangapple
  • 本文由 发表于 2023年7月27日 21:23:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76780210.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定