6

I have legacy CSS which looks like this:

.btn_1 {
    color: #fff;
    background: #004dda;
    display: inline-block;
}
.btn_1:hover {
  background-color: #FFC107;
  color: #222 !important;
}
.btn_1.full-width {
  display: block;
  width: 100%;
}

I want to migrate to using styled-components (CSS-in-JS style) in React.

This is my migration so far:

.btn_1 {
    color: #fff;
    background: #004dda;
    display: inline-block;
    :hover {
        background-color: #FFC107;
        color: #222 !important;
    }
}

but is there any solution in styled-components for selectors like .btn_1.full-width or I should just create another CSS block for that?


I think it would be cool to do something like this (or better):

.btn_1 {
    ${this}.full-width {
        display: block;
        width: 100%;
   }
}

but I can't seem to find the solution in the documents. Do you have any idea how this is possible or is this even a good idea?

Faktor 10
  • 1,868
  • 2
  • 21
  • 29
Mehrad77
  • 83
  • 1
  • 3
  • 7
  • For *joint* selectors follow this link https://stackoverflow.com/questions/3772290/css-selector-that-applies-to-elements-with-two-classes. Note that there is no need to ${this} – Mulli Feb 14 '19 at 07:10
  • Have you tried using an ampersand `&` this is the common way for most CSS pre-processors. – Ginger Wizard Feb 14 '19 at 07:11
  • @Mulli Thanks but I'm looking for a `styled-components` solution. I clearly know how to it in css3. – Mehrad77 Feb 14 '19 at 07:14
  • 1
    @GingerCSSWizard Man, `&.full-width` worked just fine! I wonder why no one talks about it in styled-components docs. Would you write an answer for future visitors? – Mehrad77 Feb 14 '19 at 07:17

2 Answers2

19

from official styled components documentation

For complex selector patterns, the ampersand (&) can be used to refer back to the main component. Here are some more examples of its potential usage:

const Thing = styled.div.attrs({ tabIndex: 0 })`
  color: blue;

  &:hover {
    color: red; // <Thing> when hovered
  }

  & ~ & {
    background: tomato; // <Thing> as a sibling of <Thing>, but maybe not directly next to it
  }

  & + & {
    background: lime; // <Thing> next to <Thing>
  }

  &.something {
    background: orange; // <Thing> tagged with an additional CSS class ".something"
  }

  .something-else & {
    border: 1px solid; // <Thing> inside another element labeled ".something-else"
  }
`

Mulli
  • 1,598
  • 2
  • 22
  • 39
0

You can use the ampersand to chain nested selectors.

.btn_1 {
    &.full-width {
        display: block;
        width: 100%;
   }
}
Ginger Wizard
  • 717
  • 4
  • 13