0

For some reason I'm having a rendering issue when it comes to implementing content in a :before or :after pseudo element. Given the stripped down component:

import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';

const Container = styled.div`
  display: block;
  padding: 1rem;
`;

const Foo = styled.p`
  &:before {
    content: '\201C';
    display: block;
    font-size: 4rem;
    font-weight: bold;
    height: 4.25rem;
  }

  &:after {
    content: '\201D';
    display: block;
    font-size: 4rem;
    font-weight: bold;
    height: 2.625rem;
  }

  font-weight: bold;
`;

function Test({ txt }) {
  return (
    <Container>
      <Foo>{txt}</Foo>
    </Container>
  );
}

Test.propTypes = {
    txt: PropTypes.string.isRequired,
};

export default Test;

Nothing gets rendered. Referencing this answer from How to render pseudo before content dynamically in styled-component I tried:

const Foo = styled.p`
  &:before {
    content: '\201C';
    display: block;
    font-size: 4rem;
    font-weight: bold;
    height: 4.25rem;
  }

  &:after {
    content: '\201D';
    display: block;
    font-size: 4rem;
    font-weight: bold;
    height: 2.625rem;
  }

  font-weight: bold;
`;

This answer recommends double colons from Can anyone tell me why before not working on styled components?:

const Foo = styled.p`
  &::before {
    content: '\201C';
    display: block;
    font-size: 4rem;
    font-weight: 700;
    height: 4.25rem;
  }

  &::after {
    content: '\201D';
    display: block;
    font-size: 4rem;
    font-weight: bold;
    height: 2.625rem;
  }

  font-weight: bold;
`;

but I'm unable to render a before or after. Further research I've seen where content might be an issue but I'm referencing them correctly per Double Quotation and a height or width should be declared and I've made sure to pass a height in rem.

Using Styled Components version "^5.3.5", I've removed my cache, dumped the public directory and I've tested in Chrome and Firefox but I'm unable to render quotes.

Research

What am I doing wrong and how can I render pseudo elements?

4 Answers 4

3

EDITED:

@zharkov-ruslan is correct. You need to escape the \ in the content property. The following works:


const Foo = styled.p`
    font-weight: bold;

    &::before {
        content: "\\201C";
        display: block;
        font-size: 4rem;
        font-weight: 700;
        height: 4.25rem;
    }
    &::after {
        content: "\\201D";
        display: block;
        font-size: 4rem;
        font-weight: bold;
        height: 2.625rem;
    }
`;

In addition to just inserting the actual character as a string, you can also use the CSS keywords open-quote and close-quote.


const Foo = styled.p`
    font-weight: bold;

    &::before {
        content: open-quote;
        display: block;
        font-size: 4rem;
        font-weight: 700;
        height: 4.25rem;
    }
    &::after {
        content: close-quote;
        display: block;
        font-size: 4rem;
        font-weight: bold;
        height: 2.625rem;
    }
`;

Sign up to request clarification or add additional context in comments.

4 Comments

That is wrong though and errors out. The later solution is an interesting approach and I learned something new but if you go by the first approach of terminating the quotes it causes an error.
Hmmm... I don't get any errors when I escape the quotes and it renders the characters properly, so I'm going to leave this here for others. Happy though that you have other options to solve the problem!
ah it looks like it might be an ESLint error, debugging now, but I was able to figure it out, I needed to terminate the backslash. Did upvote for the second half was unaware you could do that.
Cool, and yes, it does appear to be the \ that needs to be escaped.
1

Probably something is wrong with your content property inside the pseudo elements, I changes values in that fields and styles worked fine with &:before, &:after.

const Foo = styled.p`
  &:before {
    content: "“";
    display: block;
    font-size: 4rem;
    font-weight: 700;
    height: 4.25rem;
  }

  &:after {
    content: "”";
    display: block;
    font-size: 4rem;
    font-weight: bold;
    height: 2.625rem;
  }

  font-weight: bold;
`;

2 Comments

I could see that approach to resolve the issue temporarily but shouldn't content allow the defined code?
It allows to use approach from @jme11 mentioned before with \\201D. For me it worked too. I checked it via CodeSandbox. Seems that using \\ works for styled-components, because with the plain CSS it works fine with your posted code: \201D. I think the trick is related to template literals in JavaScript.
1

The hardcoded approach from this answer:

&:before {
    content: "“";
    display: block;
    font-size: 4rem;
    font-weight: 700;
    height: 4.25rem;
  }

  &:after {
    content: "”";
    display: block;
    font-size: 4rem;
    font-weight: bold;
    height: 2.625rem;
  }

works as a temporary solution but wasn't the desired course of action because I wanted to know why the code wouldn't be allowed.

The answer suggesting

You need to escape the quotes.

const Foo = styled.p`
    font-weight: bold;

    &::before {
        content: "\\201C\";
        display: block;
        font-size: 4rem;
        font-weight: 700;
        height: 4.25rem;
    }
    &::after {
        content: "\\201D\";
        display: block;
        font-size: 4rem;
        font-weight: bold;
        height: 2.625rem;
    }
`;

is wrong. The issue was escaping the backslash (\). If you escape the quotes then it errors out. As mentioned in other Q&As the preferred approach is to also use single quotes.

Solution to resolve the issue with the code was to terminate the backslash:

const Foo = styled.p`
    font-weight: bold;

    &::before {
        content: '\\201C';
        display: block;
        font-size: 4rem;
        font-weight: 700;
        height: 4.25rem;
    }
    &::after {
        content: '\\201D';
        display: block;
        font-size: 4rem;
        font-weight: bold;
        height: 2.625rem;
    }
`;

Comments

0

I usually do this when I'm using pseudo elements:

  • 'position: relative' on parent.
  • 'position: absolute' on the child element.

3 Comments

I'm somewhat unsure how this answers the question?
This is my first answer to a stack overflow question, so I may not have done it perfectly. However, I looked at the question from my CSS perspective. Generally, when adding pseudo-elements it's good to use a CSS property called "position". You can set the position to a "relative" in the parent element and use the position "absolute" in the child element. developer.mozilla.org/en-US/docs/Web/CSS/::before
um I still dont know how that would resolve the issue to the question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.