79

What is the proper way to apply :before and :after pseudo classes to styled components?

I know that you can use

&:hover {}

to apply the :hover pseudo class to a styled-component.

Does this work for All pseudo elements like before and after?

I have tried using the &:before and &:after strategy with some rather complex examples and i'm not sure if my attempts are not working because i've got something wrong with my example or it just doesn't work like that.

Does someone have some insight on this? Thank you.

rimraf
  • 3,925
  • 3
  • 25
  • 55

6 Answers6

169

Pseudo-selectors in styled-components work just like they do in CSS. (or rather, Sass) Whatever isn't working is likely a problem in your specific code, but that's hard to debug without seeing the actual code!

Here is an example of how to use a simple :after:

const UnicornAfter = styled.div`
  &:after {
    content: " ";
  }
`;

<UnicornAfter>I am a</UnicornAfter> // renders: "I am a "

If you post your code I'll likely be able to help debug your specific issue!

mxstbr
  • 11,087
  • 4
  • 39
  • 37
  • 1
    That's not necessary. Thank you for clarifying! I just needed to know for sure that it was something on my end... =) I wasn't sure that ```&:before``` and ```&:after``` was working. I couldn't find a definitive answer via google... so... Thanks! – rimraf Aug 24 '17 at 22:33
  • No worries, happy to help! – mxstbr Aug 26 '17 at 14:50
  • @mxstbr Hi, mxstbr! I'm having a problem rendering Pseudo-before content dynamically. am I doing wrong? or is it something styled-components doesn't support. https://stackoverflow.com/questions/46339034/how-to-render-pseudo-before-content-dynamically-in-styled-component/46339194#46339194 –  Sep 21 '17 at 23:42
  • Can we apply after and before to any specific child (ie :first-child)? – Sanjay Joshi May 22 '18 at 06:02
  • 1
    If you've come here using object syntax instead of template string, and you want an empty content :before element, you have to include quotations within quotations like content: '""', – joshkarges May 04 '22 at 23:44
12

This will print the triangle at middle of the div.

const LoginBackground = styled.div`
  & {
    width: 30%;
    height: 75%;
    padding: 0.5em;
    background-color: #f8d05d;
    margin: 0 auto;
    position: relative;
  }
  &:after {
    border-right: solid 20px transparent;
    border-left: solid 20px transparent;
    border-top: solid 20px #f8d05d;
    transform: translateX(-50%);
    position: absolute;
    z-index: -1;
    content: "";
    top: 100%;
    left: 50%;
    height: 0;
    width: 0;
  }
`;
Nalan Madheswaran
  • 10,136
  • 1
  • 57
  • 42
4

This is good and simple answer:

https://stackoverflow.com/a/45871869/4499788 by mxstbr

but for elements requiring more complex logic I prefer this approach:

const Figure = styled.div`
  ${Square}:before, 
  ${Square}:after,
  ${Square} div:before, 
  ${Square} div:after {
    background-color: white;
    position: absolute;
    content: "";
    display: block;
    -webkit-transition: all 0.4s ease-in-out;
    transition: all 0.4s ease-in-out;
  }
`;
Adam Kochanski
  • 168
  • 2
  • 7
2

As an object (note the double quotes):

const Div = styled.div({
  '&:before': {
    content: '"a string"',
  },
})
Fellow Stranger
  • 32,129
  • 35
  • 168
  • 232
2

Adding to @mxstbr answer

Note that when you want to render before based on props, don't forget to wrap it with double quotes (or single quotes) , example:

const Button = styled.button`
&:before {
content:"${(props)=>props.theme==='dark'?'dark theme':'white theme'}";
}

because

content:${(props)=>props.theme==='dark'?'dark theme':'white theme'};

will not work

Ghazi
  • 583
  • 5
  • 20
-30
Can try like this.
It works perfectly fine

var setValue="abc";
var elementstyle = '<style>YourClass:before { right:' + abc + 'px;}</style>'
 $(".YourClass").append(setValue);

 var rightMarginForNotificationPanelConnectorStyle = '<style>.authenticated-page.dx-authenticated .dx-notification .dx-notification-dialog.dx-content-frame:before { right:' + rightMarginForNotificationPanelConnectorWithBadge + 'px;}</style>'
                        $(".authenticated-page.dx-authenticated .dx-notification .dx-notification-dialog.dx-content-frame").append(rightMarginForNotificationPanelConnectorStyle);
  • 15
    The question was about styled-components and you are answering using plain javascript. Moreover your solution is not a good practice at all (using jquery, appending to the dom, etc). Also, consider improving the format of your answer: you put everything in a code section – Julien Sanchez Aug 19 '19 at 15:57
  • 1
    there is no point in using react if you are actually manipulating the dom using vanilla js – Ghazi Oct 30 '22 at 02:48