Search code examples
cssreactjsstyled-componentspseudo-element

Why are my :before & :after pseudo elements not rendering in my Styled Components?


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?


Solution

  • 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;
        }
    `;