Search code examples
javascriptcssreactjsstyled-componentsparceljs

styled-components only rendering certain styles after successful build with parcel


I have a widget that I am embedding on other website, built in React with styled-component. I build it into one js file with parcel and then serve that script in order to embed the widget.

The problem is that not all of my styles are reflected in the widget when embedded. I understand that my styles will naturally be impacted by the styles of the page; this is not about that. Some of my styles are not showing up at all. Not even as styles that are applied but overwritten by the parent site styles.

For example, here's a button I have:

export const StyledFABButton = styled.button`
  z-index: ${zIndex("default")} !important; // NOTE: I've tried both with and without !important flags
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  margin: 0 !important;
  padding: 5px !important;
  min-height: 60px !important;
  min-width: 60px !important;
  border: none !important;
  border-radius: 50% !important;
  box-shadow: ${(props) => props.theme.lightShadow} !important;
  background: papayawhip !important; // the only use of this colour int he whole project.
  transition: background 0.25s !important;
`

In this image you can see how many of those styles are actually reflected on the frontend:

enter image description here

It seems like some styled components styles are jut skipped entirely. I have set some styles on the styled.main and that's what you can see on the .juesmk class. Other elements have some colour, some have widths etc., but it's like the styled components are confused, almost. Some, for example, have coloured text when they shouldn't.

A search for papayawhip in devtools Styles returns no results. If you look in the parcel build file, papayawhip is there:

enter image description here

Things I've tried:

  • Using cleanslate css to reset the page styles. I've tried this via the createGlobalStyles util and inline in my styled.main.
  • Embedding my script tag in both body and head of target sites.
  • Setting !important on everything.

Here's one that does have the right styles, even though I've done nothing different with it:

export const StyledIconWrapper = styled.figure`
  display: flex !important;
  justify-content: center !important;
  align-items: center !important;
  margin: 0 !important;
  padding: 5px !important;
  height: 100% !important;
  width: 100% !important;
`;

enter image description here


Solution

  • This is solved by adding a .babelrc file and a babel plugin. Your file should contain:

    {
      "plugins": ["babel-plugin-styled-components"]
    }
    

    Parcel will pick it up automatically.

    More info here: https://styled-components.com/docs/tooling#babel-plugin and here: https://parceljs.org/recipes/react/#css-in-js

    EDIT: You can also avoid use of !important by using the &&& selector. Infor here: https://styled-components.com/docs/faqs#how-can-i-override-styles-with-higher-specificity