除了一个特定组件之外,下一个/字体在任何地方都适用

and*_*lla 9 javascript css fonts next.js tailwind-css

下一个/字体

\n

将 Next.js 与 TypeScript 和 Tailwind CSS 结合使用

\n

这是我第一次使用新next/font软件包。我遵循了 Next.js 的教程,它很容易设置。我正在使用 Inter 和名为 App Takeoff 的自定义本地字体。为了实际使用这两种字体,我使用 Tailwind CSS,其中 Inter 连接到font-sans,App Takeoff 连接到font-display

\n

除一处外一切正常

\n

我已经在文件之间进行了大量的测试,并且出于某种原因,除了我的Modal组件之外,两种字体都可以在任何地方使用。(请参阅底部的“有用更新”以了解它在组件中不起作用的原因Modal。)

\n

例子

\n

索引.tsx

\n

Inter 和 App Takeoff 字体正常工作

\n

modal.tsx 通过 index.tsx

\n

Inter 和 App Takeoff 字体不起作用

\n

正如您所看到的,当字体不在模式中时,它们工作得很好,但是一旦它们在模式中,它们就不起作用。

\n

这是一些相关代码:

\n
// app.tsx\n\nimport \'@/styles/globals.css\'\nimport type { AppProps } from \'next/app\'\n\nimport { Inter } from \'next/font/google\'\nconst inter = Inter({\n  subsets: [\'latin\'],\n  variable: \'--font-inter\'\n})\n\nimport localFont from \'next/font/local\'\nconst appTakeoff = localFont({\n  src: [\n    {\n      path: \'../fonts/app-takeoff/regular.otf\',\n      weight: \'400\',\n      style: \'normal\'\n    },\n    {\n      path: \'../fonts/app-takeoff/regular.eot\',\n      weight: \'400\',\n      style: \'normal\'\n    },\n    {\n      path: \'../fonts/app-takeoff/regular.woff2\',\n      weight: \'400\',\n      style: \'normal\'\n    },\n    {\n      path: \'../fonts/app-takeoff/regular.woff\',\n      weight: \'400\',\n      style: \'normal\'\n    },\n    {\n      path: \'../fonts/app-takeoff/regular.ttf\',\n      weight: \'400\',\n      style: \'normal\'\n    }\n  ],\n  variable: \'--font-app-takeoff\'\n})\n\nconst App = ({ Component, pageProps }: AppProps) => {\n  return (\n    <div className={`${inter.variable} font-sans ${appTakeoff.variable}`}>\n      <Component {...pageProps} />\n    </div>\n  )\n}\n\nexport default App\n
Run Code Online (Sandbox Code Playgroud)\n
// modal.tsx\n\nimport type { FunctionComponent } from \'react\'\nimport type { Modal as ModalProps } from \'@/typings/components\'\nimport React, { useState } from \'react\'\nimport { Fragment } from \'react\'\nimport { Transition, Dialog } from \'@headlessui/react\'\n\nconst Modal: FunctionComponent<ModalProps> = ({ trigger, place = \'bottom\', className, addClass, children }) => {\n\n  const [isOpen, setIsOpen] = useState(false),\n        openModal = () => setIsOpen(true),\n        closeModal = () => setIsOpen(false)\n\n  const Trigger = () => React.cloneElement(trigger, { onClick: openModal })\n\n  const enterFrom = place === \'center\'\n    ? \'-translate-y-[calc(50%-12rem)]\'\n    : \'translate-y-full sm:-translate-y-[calc(50%-12rem)]\'\n\n  const mainPosition = place === \'center\'\n    ? \'-translate-y-1/2\'\n    : \'translate-y-0 sm:-translate-y-1/2\'\n\n  const leaveTo = place === \'center\'\n    ? \'-translate-y-[calc(50%+8rem)]\'\n    : \'translate-y-full sm:-translate-y-[calc(50%+8rem)]\'\n\n  return (\n    <>\n    \n      <Trigger />\n\n      <Dialog open={isOpen} onClose={closeModal} className=\'z-50\'>\n\n        {/* Backdrop */}\n        <div className=\'fixed inset-0 bg-zinc-200/50 dark:bg-zinc-900/50 backdrop-blur-sm cursor-pointer\' aria-hidden=\'true\' />\n\n        <Dialog.Panel\n          className={`\n            ${className || `\n              fixed left-1/2\n              ${\n                place === \'center\'\n                ? \'top-1/2 rounded-2xl\'\n                : \'bottom-0 sm:bottom-auto sm:top-1/2 rounded-t-2xl xs:rounded-b-2xl\'\n              }\n              bg-zinc-50 dark:bg-zinc-900\n              w-min\n              -translate-x-1/2\n              overflow-hidden\n              px-2 xs:px-6\n              shadow-3xl shadow-primary-400/10\n            `}\n            ${addClass || \'\'}\n          `}\n        >\n          {children}\n              \n        </Dialog.Panel>\n\n        <button\n          onClick={closeModal}\n          className=\'\n            fixed top-4 right-4\n            bg-primary-600 hover:bg-primary-400\n            rounded-full\n            h-7 w-7 desktop:hover:w-20\n            overflow-x-hidden\n            transition-[background-color_width] duration-300 ease-in-out\n            group/button\n          \'\n          aria-role=\'button\'\n        >\n          Close\n        </button>\n\n      </Dialog>\n\n    </>\n  )\n}\n\nexport default Modal\n
Run Code Online (Sandbox Code Playgroud)\n

我希望这个信息帮助。如果还有其他有帮助的信息,请告诉我。

\n

有用的更新

\n

感谢Jonathan Wieben解释为什么这不起作用(请参阅解释)。这个问题仅仅与应用样式的范围以及 Headless UI 对 React 组件的使用有关Portal。如果有人对我如何更改Portal渲染位置或更改样式范围有一些想法,那将非常有帮助。Jonathan Wieben指出了一种方法来做到这一点,但是 \xe2\x80\x94 从我的测试 \xe2\x80\x94 来看,它不适用于 Tailwind CSS。

\n

Jon*_*ben 10

您正在使用的组件Dialog在门户中呈现(请参阅此处)。

您通常希望将它们呈现为 React 应用程序最根节点的同级节点。这样,您就可以依靠自然 DOM 排序来确保其内容呈现在现有应用程序 UI 之上。

您可以通过检查浏览器中的模态 DOM 元素并查看它是否确实放置在组件div的包装器之外App(我怀疑是这样)来确认这一点。

如果是这样,这就是为什么模式内容不使用预期字体呈现的解释:它是在定义字体的组件外部呈现的。

为了解决这个问题,您可以在更高的级别上定义您的字体,例如在您的头脑中,如下所述:下一个文档

  • 这是有道理的,但这似乎不适用于 TailwindCSS,除非我只是做错了。您知道在 TailwindCSS 级别应用此方法的方法吗? (3认同)

小智 5

我在 headlessui、tailwind 和 nextjs 上也遇到了完全相同的问题。我发现正确标记的解决方案对于像模态这样简单的事情来说太复杂了。对我有用的是将相同的字体插入模态组件中:

//Modal.tsx
import { Dialog, Transition } from '@headlessui/react';
import { Rubik } from '@next/font/google';

const rubik = Rubik({
  subsets: ['latin'],
  variable: '--font-rubik',
});

type Props = {
  children: React.ReactNode;
  isOpen: boolean;
  closeModal: any;
};

const Modal = ({ children, isOpen, closeModal }: Props) => {
  return (
  <>
  <Transition ...>
    <Dialog ...>
    ...
        <Dialog.Panel
              className={`${rubik.variable} font-sans ...`}>
              ...
        </Dialog.Panel>
    </Dialog>
  </Transition>
  </>
    );
};
export default Modal;
Run Code Online (Sandbox Code Playgroud)

工作起来就像一个魅力。