最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to put React.Component to CSS content property (in :before:after pseudo-elements)? - Stack Overflow

programmeradmin1浏览0评论

In styled-ponents, I'm trying to get a React Icon to render on hover by passing it through content but for some reason, my render on hover is [Object Object].

Component:

export const FooLink = styled(Link)`
  padding: 0.5rem 2rem;
  color: ${({ theme }) => theme.colors.white};
  text-align: center;
  margin: 0 auto;
  position: relative;
  font-size: ${({ theme }) => theme.fontSizes.p};
  letter-spacing: 0.15em;
  transition: ${({ theme }) => theme.animations.trans3};

  &:after {
    content: '${FaArrowRight}';
    /* content: '>'; */
    position: absolute;
    opacity: 0;
    right: -${({ theme }) => theme.spacings.small};
    transition: ${({ theme }) => theme.animations.trans3};
  }

  &:hover {
    padding-right: ${({ theme }) => theme.spacings.small};
    padding-left: ${({ theme }) => theme.spacings.xxSmall};
  }

  &:hover:after {
    opacity: 1;
    ${({ theme }) => theme.spacings.xSmall};
  }
`

Ive brought everything in with:

import styled from 'styled-ponents'
import { Link } from 'gatsby'
import { FaArrowRight } from 'react-icons/fa'

Other attempts on content

content: ${FaArrowRight};

But I found this won't work per:

That is because content value must be within quotes in CSS.

Realizing I might have spent too long in a CSS mental state I tried bringing in React:

import React from 'react'
import styled from 'styled-ponents'
import { Link } from 'gatsby'
import { FaArrowRight } from 'react-icons/fa'

And rendering:

content: '${(<FaArrowRight />)}';

when I try with template literals I get an error with missing semi-colons:

content: `'${<FaArrowRight />}'`;

All attempts render as [Object Object]

Research to see if this has been asked and I've read through:

  • How to render pseudo before content dynamically in styled-ponent
  • Before and After pseudo classes used with styled-ponents
  • css pseudo code “li::before” in react inline style
  • How do I get a variable from a graphQl query into a pseudo element in either inline styles or styled ponents
  • Do psuedo selectors work in styled-ponents the same as in css with unicode characters

In styled-ponents how can I render a React Icon in content?

In styled-ponents, I'm trying to get a React Icon to render on hover by passing it through content but for some reason, my render on hover is [Object Object].

Component:

export const FooLink = styled(Link)`
  padding: 0.5rem 2rem;
  color: ${({ theme }) => theme.colors.white};
  text-align: center;
  margin: 0 auto;
  position: relative;
  font-size: ${({ theme }) => theme.fontSizes.p};
  letter-spacing: 0.15em;
  transition: ${({ theme }) => theme.animations.trans3};

  &:after {
    content: '${FaArrowRight}';
    /* content: '>'; */
    position: absolute;
    opacity: 0;
    right: -${({ theme }) => theme.spacings.small};
    transition: ${({ theme }) => theme.animations.trans3};
  }

  &:hover {
    padding-right: ${({ theme }) => theme.spacings.small};
    padding-left: ${({ theme }) => theme.spacings.xxSmall};
  }

  &:hover:after {
    opacity: 1;
    ${({ theme }) => theme.spacings.xSmall};
  }
`

Ive brought everything in with:

import styled from 'styled-ponents'
import { Link } from 'gatsby'
import { FaArrowRight } from 'react-icons/fa'

Other attempts on content

content: ${FaArrowRight};

But I found this won't work per:

That is because content value must be within quotes in CSS.

Realizing I might have spent too long in a CSS mental state I tried bringing in React:

import React from 'react'
import styled from 'styled-ponents'
import { Link } from 'gatsby'
import { FaArrowRight } from 'react-icons/fa'

And rendering:

content: '${(<FaArrowRight />)}';

when I try with template literals I get an error with missing semi-colons:

content: `'${<FaArrowRight />}'`;

All attempts render as [Object Object]

Research to see if this has been asked and I've read through:

  • How to render pseudo before content dynamically in styled-ponent
  • Before and After pseudo classes used with styled-ponents
  • css pseudo code “li::before” in react inline style
  • How do I get a variable from a graphQl query into a pseudo element in either inline styles or styled ponents
  • Do psuedo selectors work in styled-ponents the same as in css with unicode characters

In styled-ponents how can I render a React Icon in content?

Share edited Apr 1, 2021 at 12:22 sergdenisov 8,5729 gold badges51 silver badges66 bronze badges asked Mar 31, 2021 at 16:04 GʀᴜᴍᴘʏCᴀᴛGʀᴜᴍᴘʏCᴀᴛ 9,02920 gold badges90 silver badges159 bronze badges 5
  • stick a & before :after – Tom Bombadil Commented Mar 31, 2021 at 16:06
  • ya that was an edit mistake but even then it still renders as object object – GʀᴜᴍᴘʏCᴀᴛ Commented Mar 31, 2021 at 16:07
  • '${FaArrowRight}' Use back ticks instead of single quotes. – Tom Bombadil Commented Mar 31, 2021 at 16:09
  • @TomBombadil as explained in the question, from my research, single quotes should be used with content instead of template literals. – GʀᴜᴍᴘʏCᴀᴛ Commented Mar 31, 2021 at 16:18
  • As far as I know you can't pass an objects as value to content. And I think you are passing an object. Not sure if FaArrowRight is a string or an object. – Tom Bombadil Commented Mar 31, 2021 at 16:30
Add a ment  | 

1 Answer 1

Reset to default 6

If you need to use styled-ponents (or any other CSS-in-JS library) with an icon from react-icons (or any other library that exports a React.Component which renders an <svg> element), I see the only one way: to transform a ponent to an url() with a markup string because only this way you can pass an image to content property in your case. For that transformation, you need: React.createElement(), ReactDOMServer.renderToStaticMarkup() and encodeURIComponent(). Also, you can use Base64 instead.

This one works (CodeSandbox):

import { createElement } from "react";
import { render } from "react-dom";
import { renderToStaticMarkup } from "react-dom/server";
import styled from "styled-ponents";
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")
);

Thanks to this Github Gist.

发布评论

评论列表(0)

  1. 暂无评论