如何将 React.Component 放入 CSS 内容属性(在 :before/:after 伪元素中)?

Dᴀʀ*_*ᴅᴇʀ 6 javascript css reactjs styled-components react-component

在 中styled-components,我试图通过传递 React Icon 来在悬停时渲染它,content但由于某种原因,我的悬停渲染是[Object Object]

\n

成分:

\n
export const FooLink = styled(Link)`\n  padding: 0.5rem 2rem;\n  color: ${({ theme }) => theme.colors.white};\n  text-align: center;\n  margin: 0 auto;\n  position: relative;\n  font-size: ${({ theme }) => theme.fontSizes.p};\n  letter-spacing: 0.15em;\n  transition: ${({ theme }) => theme.animations.trans3};\n\n  &:after {\n    content: \'${FaArrowRight}\';\n    /* content: \'>\'; */\n    position: absolute;\n    opacity: 0;\n    right: -${({ theme }) => theme.spacings.small};\n    transition: ${({ theme }) => theme.animations.trans3};\n  }\n\n  &:hover {\n    padding-right: ${({ theme }) => theme.spacings.small};\n    padding-left: ${({ theme }) => theme.spacings.xxSmall};\n  }\n\n  &:hover:after {\n    opacity: 1;\n    ${({ theme }) => theme.spacings.xSmall};\n  }\n`\n
Run Code Online (Sandbox Code Playgroud)\n

我把所有东西都带来了:

\n
import styled from \'styled-components\'\nimport { Link } from \'gatsby\'\nimport { FaArrowRight } from \'react-icons/fa\'\n
Run Code Online (Sandbox Code Playgroud)\n

内容上的其他尝试

\n
content: ${FaArrowRight};\n
Run Code Online (Sandbox Code Playgroud)\n

但我发现这不起作用:

\n
\n

这是因为 CSS 中的内容值必须位于引号内。

\n
\n

意识到我可能在 CSS 心理状态中度过了太长时间,我尝试引入 React:

\n
import React from \'react\'\nimport styled from \'styled-components\'\nimport { Link } from \'gatsby\'\nimport { FaArrowRight } from \'react-icons/fa\'\n
Run Code Online (Sandbox Code Playgroud)\n

和渲染:

\n
content: \'${(<FaArrowRight />)}\';\n
Run Code Online (Sandbox Code Playgroud)\n

当我尝试使用模板文字时,出现缺少分号的错误:

\n
content: `\'${<FaArrowRight />}\'`;\n
Run Code Online (Sandbox Code Playgroud)\n

所有尝试均呈现为[Object Object]

\n

研究看看是否有人问过这个问题并且我已经通读过:

\n\n

如何在styled-components中渲染 React 图标content

\n

Ser*_*sov 6

如果您需要将styled-components(或任何其他 CSS-in-JS 库)与来自react-icons(或导出React.Component呈现<svg>元素的任何其他库)的图标一起使用,我看到唯一的一种方法:将组件转换为url()带有标记的组件字符串,因为只有这样你才能将图像传递给content你的情况下的属性。对于该转换,您需要:React.createElement()ReactDOMServer.renderToStaticMarkup()encodeURIComponent()。另外,您也可以使用Base64代替。

这个有效(CodeSandbox):

import { createElement } from "react";
import { render } from "react-dom";
import { renderToStaticMarkup } from "react-dom/server";
import styled from "styled-components";
import { Link } from "gatsby";
import { FaArrowRight } from "react-icons/fa";

window.___loader = { enqueue: () => {}, hovering: () => {} };

const reactSvgComponentToMarkupString = (Component, props) =>
  `data:image/svg+xml,${encodeURIComponent(
    renderToStaticMarkup(createElement(Component, props))
  )}`;

const FooLink = styled(Link)`
  ${({ color }) => color && `color: ${color};`}
  &:after {
    content: ${({ color }) =>
      `url(${reactSvgComponentToMarkupString(FaArrowRight, {
        color
      })})`};
    position: absolute;
    opacity: 0;
  }

  &:hover:after {
    opacity: 1;
  }
`;

render(
  <>
    <div>
      <FooLink to="/test1" color="red">
        Link with arrow (red)
      </FooLink>
    </div>
    <div>
      <FooLink to="/test2">Link with arrow (default)</FooLink>
    </div>
  </>,
  document.getElementById("root")
);
Run Code Online (Sandbox Code Playgroud)

感谢这个 Github Gist