Does React Emotion support ::before/ ::after selectors?

Viewed 2480

I am trying to use React Emotion to set up a horizontal rule with text in the middle. It would look like this:

----------------------SOME TEXT----------------------------------

I found examples on StackOverflow on how to do this with CSS, but it's not working for me.

Here is my DIV that I'm using, but it's not working.

Is this possible to set up with react Emotion? What am I missing?

<div
  css={{
    display: 'flex',
    lineHeight:'1em',
    color:'gray',
    '&:before, &:after': {
        content:'',
        display:'inline-block',
        flexGrow:'1px',
        marginTop:'0.5em',
        backgroundColor:'gray',
        height:'1px',
        marginRight:'10px',
        marginLeft:'10px'
    }
   
  }}
>
  SOME TEXT
</div>
3 Answers

Your code is right about the ::before and ::after syntax, However, when trying to replicate I found two errors:

  1. The flexGrow shouldn't have a px unit, just 1: flexGrow:'1
  2. The content should have double quotes content:'""'
<div
    css={{
      display: 'flex',
      lineHeight:'1em',
      color:'gray',
      '&:before, &:after': {
          content:'""',
          display:'inline-block',
          flexGrow:'1',
          marginTop:'0.5em',
          backgroundColor:'gray',
          height:'1px',
          marginRight:'10px',
          marginLeft:'10px'
      }
    }}
  >

You need pass style object in css function from emotion/css or emotion/react.

You forgot to wrap your styled object in a function from emotion.

If you use an object and not a string, then wrap content in double quotes

  // First way, use css from @emotion/css, pass as object

  import { css } from '@emotion/css'

  <div
    className={css({
      display: 'flex',
      lineHeight: '1em',
      color: 'gray',
      ':before, :after': {
          content: '""',
          flexGrow: '1',
          marginTop: '0.5em',
          backgroundColor: 'gray',
          height: '1px',
          marginRight: '10px',
          marginLeft: '10px'
      } 
    })}
  >
    SOME TEXT
  </div>

  // Second way, use css from @emotion/css, pass as string

  import { css } from '@emotion/css'

  <div
    className={css`
      display: flex;
      line-height: 1em;
      color: gray;
      :before, :after: {
          content: '';
          flex-grow: 1;
          margin-top: 0.5em;
          background-color: gray;
          height: 1px;
          margin-right: 10px;
          margin-left: 10px;
      } 
    `}
  >
    SOME TEXT
  </div>

  // Third way, use css from @emotion/react

  import { css } from '@emotion/react'

  <div
    css={css`
      display: flex;
      line-height: 1em;
      color: gray;
      :before, :after: {
          content: '';
          flex-grow: 1;
          margin-top: 0.5em;
          background-color: gray;
          height: 1px;
          margin-right: 10px;
          margin-left: 10px;
      } 
    `}
  >
    SOME TEXT
  </div>

For string interpolation passed for css function you can use it like

let highlight = css`
  border: 1px solid grey;
  &:after {
      position: absolute;
}`;
Related