92

I have seen in a lot of the Material UI code that they use pseudo selectors in their react styled components. I thought I would try to do it myself and I cannot get it to work. I'm not sure what I am doing wrong or if this is even possible.

I am trying to make some CSS that will offset this element against the fixed header.

import React from 'react';
import { createStyles, WithStyles, withStyles, Typography } from '@material-ui/core';
import { TypographyProps } from '@material-ui/core/Typography';
import GithubSlugger from 'github-slugger';
import Link from './link';

const styles = () =>
  createStyles({
    h: {
      '&::before': {
        content: 'some content',
        display: 'block',
        height: 60,
        marginTop: -60
      }
    }
  });

interface Props extends WithStyles<typeof styles>, TypographyProps {
  children: string;
}

const AutolinkHeader = ({ classes, children, variant }: Props) => {
  // I have to call new slugger here otherwise on a re-render it will append a 1
  const slug = new GithubSlugger().slug(children);

  return (
    <Link to={`#${slug}`}>
      <Typography classes={{ root: classes.h }} id={slug} variant={variant} children={children} />
    </Link>
  );
};

export default withStyles(styles)(AutolinkHeader);
Olivier Tassinari
  • 8,238
  • 4
  • 23
  • 23
Joff
  • 11,247
  • 16
  • 60
  • 103

3 Answers3

233

I found out that the content attribute needed to be double quoted like this

const styles = () =>
  createStyles({
    h: {
      '&::before': {
        content: '"some content"',
        display: 'block',
        height: 60,
        marginTop: -60
      }
    }
  });

and then everything worked like expected

Alex
  • 5,364
  • 9
  • 54
  • 69
Joff
  • 11,247
  • 16
  • 60
  • 103
  • 8
    content: ' "some content" ', you missed the closed quote but anyway thanks, you saved my day. – Doongsil Feb 10 '19 at 08:10
  • 70
    This is also important for empty pseudo-elements. i.e. `content: '""'` – Eran Goldin Jan 15 '20 at 09:29
  • 9
    wasted 2 hours on that. I was using content: 'blabla' and it was not working ‍♂️ – Aamir Afridi May 08 '20 at 15:37
  • 2
    Well, content wasted my time. – Second Son Jul 27 '20 at 07:20
  • Also wasted a few hours on this. My situation was even shittier as eslint is quite strict on this project I am working on and we're not allowing single quotes. For those in the same boat, just add this line before the `content` property: `/* eslint quotes: [2, "double", "avoid-escape"] */` as this would allow strings to use single or double quotes as long as the string contains a quote that would have to be escaped otherwise. – Christopher Nov 04 '21 at 13:21
53

As @Eran Goldin said, check the value of your content property and make sure it's set to a string "". Odds are, you are doing something like this:

'&::before': {
  content: '',
  ...
}

Which doesn't set the content property at all in the output stylesheet

.makeStyles-content-154:before {
  content: ;
  ...
}

In Material-UI style object, the content of the string is the css value, including the double quote, to fix it simply write

'&::before': {
  content: '""', // "''" will also work.
  ...
}
NearHuscarl
  • 66,950
  • 18
  • 261
  • 230
0

Without having to explicitly set a height

The above solutions require explicit height. If you want height to be dynamic, you can do something like this:

  &::after {
    content: '_'; // Any character can go here
    visibility: hidden;
  }
dipole_moment
  • 5,266
  • 4
  • 39
  • 55