Styled-components-website: Add "How can I override styles with higher specificity?" to FAQ

Created on 18 Dec 2017  路  13Comments  路  Source: styled-components/styled-components-website

Since this question comes up almost every day in the main repo, we should add a FAQ entry to the website.

Based on this question and answer we should add a note about the &&& workaround and why it works to the FAQ.

enhancement good first issue help wanted

Most helpful comment

The ampersand solution is for overriding styles applied with former classNames or styled applied from the parent and some other cases. It's not meant to be used for overriding inline styles.

/* css */
.header {
  background: #453434; /* overrided */
}
// JSX
<Div className="header sc-wS45d" />

const Div = styled.div`
  && {
    background: white; /* applied */
  }
`

All 13 comments

I can take this one

Regarding overriding inline CSS, will this trick work too, or will you have to use !important in that case? (I can investigate this if needed)

I think if you use enough ampersands it might work? Not sure though, good question!

After a quick glance at google it looks like the most reliable way is to use the element-attr CSS Selector in conjunction with !important;

/* vanilla CSS */
div[style] {
   font-size: 12px !important;
   color: blue !important;
}

I'll make some tests though, and document both cases in the FAQ section.

I'll make some tests though, and document both cases in the FAQ section.

SGTM

The ampersand solution is for overriding styles applied with former classNames or styled applied from the parent and some other cases. It's not meant to be used for overriding inline styles.

/* css */
.header {
  background: #453434; /* overrided */
}
// JSX
<Div className="header sc-wS45d" />

const Div = styled.div`
  && {
    background: white; /* applied */
  }
`

@morajabi thanks, that's what I thought. Let's document both cases though, for clarity.

Just to update @morajabi's answer , according to the docs you need three &s.

So this would be the correct syntax:

// JSX
<Div className="header sc-wS45d" />

const Div = styled.div`
  &&& {
    background: white; /* applied */
  }

You can use as many & as you want, the more you use the higher the specificity will be!

Compile error when using more than two &s

@joebentaylor1995 can you share an example of a styled component that's failing to compile?

Any idea how to do this with createGlobalStyle?
This doesn't work.

export const StyleHtmlColor = createGlobalStyle`
  html {
    && {
      background-color: red;
    }
  }
`;

I had this problem with third-party component libararies with dynamic css injections like antd.

The style tags from antd and styled-components could be re-ordered according to the js excution order.

image

And I found the solution in webpack's official document:

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          {
            loader: 'style-loader',
            options: {
              insert: function insertAtTop(element) {
                var parent = document.querySelector('head');
                // eslint-disable-next-line no-underscore-dangle
                var lastInsertedElement =
                  window._lastElementInsertedByStyleLoader;

                if (!lastInsertedElement) {
                  parent.insertBefore(element, parent.firstChild);
                } else if (lastInsertedElement.nextSibling) {
                  parent.insertBefore(element, lastInsertedElement.nextSibling);
                } else {
                  parent.appendChild(element);
                }

                // eslint-disable-next-line no-underscore-dangle
                window._lastElementInsertedByStyleLoader = element;
              },
            },
          },
          'css-loader',
        ],
      },
    ],
  },
};

And add a style tag in the index.html:
image

Was this page helpful?
0 / 5 - 0 ratings