Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v5 createGlobalStyles does not work on production with 2 global styles #2670

Closed
chriserickson opened this issue Jul 5, 2019 · 58 comments
Closed
Labels
needs more info ✋ An issue that needs triaging and reproducible examples or more information to be resolved

Comments

@chriserickson
Copy link

chriserickson commented Jul 5, 2019

Environment

System:

  • OS: macOS 10.14.5
  • CPU: (12) x64 Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
  • Memory: 489.05 MB / 16.00 GB
  • Shell: 3.2.57 - /bin/bash

Binaries:

  • Node: 10.15.1
  • Yarn: 1.16.0
  • npm: 6.9.0

npmPackages:

  • styled-components: ^5.0.0-beta.8 => 5.0.0-beta.8

Reproduction

I have 2 global styles, however on production only the second one loads. (The class names appear fo the first, but no styles are applied.)

import { createGlobalStyle } from 'styled-components/macro';

const GlobalStyling = createGlobalStyle`
html {
  height: 100%;
}

:global(#root) {
  min-height: 100%;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  flex: 1;
}

body {
  min-height: 100%;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  flex: 1;

  max-width: 100vw;
}

button {
  cursor: pointer;
}

main, section {
  display: block;
}

hr {
    margin: 48px 0;
    border-bottom: 1px solid gray;
    border-top: none;
    border-left: none;
    border-right: none;
  }

*:focus {
  outline: 1px solid blue;
}
}`
const GlobalFontStyling = createGlobalStyle`...`;
ReactDOM.render(
  <div>
    <GlobalStyling />
    <GlobalFontStyling />
    <ErrorBoundary>...
   </ErrorBoundary
  </div>,
  document.getElementById('root')
);

Expected Behavior

Styles from both global styles will appear

Actual Behavior

Only styles from GlobalFontStyling appear.

@chriserickson
Copy link
Author

Looks like it may be a red herring -- I tried combining styles and global styles into a single block.

Things like html/body/hr don't load. That is, until I click the element for the global style in the react dom inspector. Then they suddenly load. Investigating still....

@quantizor quantizor added 5.0 needs more info ✋ An issue that needs triaging and reproducible examples or more information to be resolved labels Jul 8, 2019
@mattcosta7
Copy link

I've actually come across the same issue today, but with only a single createGlobalStyle element. Will try to investigate later on today if I can

@marvwhere
Copy link

Not sure if related, but I want to leave it here as a note, as I workaround it:

In my app, I sometimes need to rerender the whole app.

render(<App />, mountNode);

With v3, v4 it worked without any problems. With v5, I had the issue, that the createGlobalStyles went missing after the rerender of the root element of the app in the style object. All other styles are ok.

My workaround, I call:

unmountComponentAtNode(mountNode);

before the new render.

I tried to reproduce it with the sandbox example app, but I couldn't, that's why I didn't create an issue.

@Evalon
Copy link

Evalon commented Jul 11, 2019

I observed this bug in storybook when select different stories and go back to previous story. V4 works fine.

@mattcosta7
Copy link

mattcosta7 commented Jul 15, 2019

Looking into this a little more -

The styles are properly output into the bundled scripts, and they're definitely being interpolated correctly. The styles are not applied. If I open up devtools (with react devtools installed), and click on the element in the component inspector, then I do see the styles applied.

a quick check at debugging (don't have time to dig through deeply now).

If I add a local state and use effect to force a re-render after initial mounting, the styles apply when that re-render occurs

  • using this with CRA@latest for build setup

@selbekk
Copy link

selbekk commented Jul 29, 2019

I'm experiencing this one as well. Weird!

@shalanah
Copy link

I have this issue as well but with only one createGlobalStyles. Even odder, Firefox seemed to apply the styles fine but Safari and Chrome would not.

@jonkwheeler
Copy link

Just wanted to bump this. Not having the ability to use Global Styles with confidence is a large reason not to switch to v5.

@quantizor
Copy link
Contributor

quantizor commented Sep 3, 2019

So there's one bug we're keeping an eye on re: rules with vendor prefixed-selectors. But I'm successfully using multiple cGS in my nextjs production app with v5.

@quantizor
Copy link
Contributor

@shalanah this is very likely due to a subtle bug we're trying to track down re: vendor-prefixed selectors. You can use tooling like this to find and remove them for the time being: https://stylelint.io/user-guide/rules/selector-no-vendor-prefix

@quantizor
Copy link
Contributor

cc @kitten

@yuliia007naumenko
Copy link

createGlobalStyles doesn't work on server side (next.js v8) but works on client

@quantizor
Copy link
Contributor

quantizor commented Sep 4, 2019 via email

@jonkwheeler
Copy link

That’s interesting. I’m using it on a fresh Next.js 9 repo. Global styling with S-C 5 on a page to page basis is not reliable. Styling seems to unload, even if the component is included on all pages. S-C 4 does not have this issue. The SSR setup has not changed either. If you have more info, let me know.

@quantizor
Copy link
Contributor

quantizor commented Sep 4, 2019 via email

@jonkwheeler
Copy link

Sure did.

@quantizor
Copy link
Contributor

Interesting. Do you have multiple libs using s-c that are consumed in the same app? Two copies loading at once can cause some interesting collisions.

@jonkwheeler
Copy link

That I can confirm. 2 libs. Our Design System runs on S-C. And some other packages we use. Seems like you’re onto something.

@quantizor
Copy link
Contributor

quantizor commented Sep 4, 2019 via email

@jonkwheeler
Copy link

I totally remember the peer dependency quark. However, interestingly I found the DS having S-C set as a dependency AND peer dependency. 😑

@abraxxas
Copy link

We have the same problem in a next.js project. I checked our dependencies and our package-lock.json and we are only using 1 version of styled-components

@sbrichardson
Copy link

sbrichardson commented Sep 17, 2019

@probablyup @kitten I was able to confirm within our app that a vendor prefixed selection rule was causing the GlobalStyle issue.

Note, this issue only happened in the production build version.

Removing this rule resolved:

   /* Gecko Browsers */
  ::-moz-selection {
    background: #C9F6F8;
  }

I was looking at the SC v5 source code, it looks like a few changes were made in how the css is being parsed/generated in GlobalStyle, I haven't dug in yet. I also noticed that the GlobalStyle component has about 50% higher rendering duration times, after upgrading from v4 to v5 (just within our app/not tested extensively).

@jonkwheeler
Copy link

This is an interested find @sbrichardson.

I'm using both ::-moz-selection and ::selection in my global style injection. I 100% think you're onto something. 🐴

@fabb
Copy link

fabb commented Sep 17, 2019

I'm not using any vendor prefixes in our global styles, but still have the issue that they are not loaded all the time.

@sbrichardson
Copy link

sbrichardson commented Sep 17, 2019

@jonkwheeler @fabb I'm thinking that the ::- and :- cases may be causing an issue in some way but there may be other cases that are causing bugs also, I’m still reviewing.

@umitkucuk
Copy link

umitkucuk commented Oct 26, 2019

@Ako92 but you didn't fix it. You just stopped using it. 😄

@Ako92
Copy link

Ako92 commented Oct 26, 2019

@umitkucuk yes. thanks for you comment. I will edit my answer. but i didn't find any other solution to fix.

@Ako92
Copy link

Ako92 commented Oct 26, 2019

To fix createGlobalStyle, you removed it? That is a "work around" some could use. But that is the same as saying, my car is broke, and to fix it I road the bus to work today. (Kidding of course) cowboy_hat_face

:-))
I prefer one place for my globalStyles not two different files and two different locations.because of that i removed createGlobalStyle. if someday this problem got fixed I will come back to createGlobalStyle.

@fabb
Copy link

fabb commented Oct 27, 2019

Maybe the remaining bug on styled-components@test is related to next.js and hydration? I need to investigate more.

@jonkwheeler
Copy link

I wonder if it's possible this is related to a Next.js bug I filed which demonstrates re-hydration of the Head. See here - vercel/next.js#9070

@quantizor
Copy link
Contributor

@jonkwheeler very interesting... could be.

@fabb
Copy link

fabb commented Oct 31, 2019

Ok I found out more. cGS seems to work properly, except in combination with the next.js Head.

We currently have in our _document.tsx the styles included in the Head:

<Head>
    <MyGlobalStyles />
</Head>

The weird thing is that in the getInitialProps of the _document.tsx, we collect the styles only of our App component:

ctx.renderPage = () => originalRenderPage({
    enhanceApp: App => props => sheet.collectStyles(<App {...props} />),
})

So why did that work at all in sc 4? My guess would be that sc 4 did not collect global styles at all, where as sc 5 does - am I on the right track? ❓


So I dug some further, and even when I move the <MyGlobalStyles /> out of the <Head> directly as a regular child of the component tree in _document.tsx, it also does not apply the styles in sc 5 whereas in sc 4 they are applied nonetheless. This would substantiate the suspicion that global styles were not collected in sc 4 whereas they are in sc 5.


When I move the <MyGlobalStyles /> component to anywhere in my App component or further down, it gets applied correctly. 🎉

But when I put it inside a <Head> component inside my <App> component, I get a runtime error:

TypeError: Cannot destructure property `styles` of 'undefined' or 'null'.
    at Head.render (.next/server/static/development/pages/webpack:/node_modules/next/dist/pages/_document.js:18:1)

So it seems sc's collectStyles has a bug in combination with the <Head>.


I'll do some more checks to see if we are really ready for upgrade to sc 5 now when I just move the global styles out of Head and _document.tsx. Should I create a new bug issue for the problems I found in combination with the <Head> component?

@fabb
Copy link

fabb commented Nov 1, 2019

@probablyup I think it would be helpful to add these things 👆 as breaking changes to the v5 release notes, what do you think? Something along these lines:

BREAKING CHANGE: global styles are now collected like regular component styles, therefore they need to be accessible for collection. For example in case of next.js, it is no longer possible to render them in _document.js or as <Head> children anywhere in the application. Rather move them to _app.js or further down to components that need them.

Note that the part about style collection is just guesswork on my side, based on evidence of the behavior in v5. It would be interesting to hear if this is actually the case, or which other change caused the new behavior.

@jonkwheeler
Copy link

I'll give the release candidate a shot, but I'm 99% positive none of my createGlobalStyles are inside _document or <NextHead>.

@mareksuscak
Copy link

Yeah, ours is in the _app.js outside of NextHead and Helmet and we were seeing this issue until we downgraded.

@quantizor
Copy link
Contributor

quantizor commented Nov 1, 2019 via email

@jenseralmeida
Copy link

jenseralmeida commented Nov 2, 2019

I believe that this should be a blocker for the version 5 release. I am pasting below a complete react index.js which is not working as desired. The same code works perfectly well on the v4.

The first image is the result of a developer build.

image

Now, this is the result of a production build.

image

I am starting with react and I could not understand any of the workarounds that could be used and I can not make createGlobalStyle works properly on version v5. Fun-fact, the colors are being applied, but not the fonts. So, this shows that some point the style was rendered by styled-components, and later removed.

index.js

import "./index.css";
import React from "react";
import ReactDOM from "react-dom";
import { ThemeProvider, createGlobalStyle, css } from "styled-components";

const GlobalStyle = createGlobalStyle`
${props => props.theme.fonts.titleFace}
${props => props.theme.fonts.bodyFace}
${props => props.theme.fonts.iconsFace}

body {
    font-family: ${props => props.theme.fonts.body}, sans-serif;
}

button {
    color: ${props => props.theme.colors.color};
    background: ${props => props.theme.colors.background};
    border-color: ${props => props.theme.colors.border};
    font-family: ${props => props.theme.fonts.body}, sans-serif;
}

button:hover {
    background: ${props => props.theme.colors.highlightedBackground};
    color: ${props => props.theme.colors.highlightedColor};
    border-color: ${props => props.theme.colors.highlightedBorder};
}

button:after {
    font-family: ${props => props.theme.fonts.icons};
}
`;

const theme = {
    colors: {
        color: "#fafafa",
        background: "#181753",
        border: "#181753",
        highlightedColor: "#dfdfdf",
        highlightedBackground: "#181753",
        highlightedBorder: "#181753"
    },
    fonts: {
        title: "Muli",
        titleFace: css`
            @font-face {
                font-family: "Montserrat";
                font-style: normal;
                font-weight: 400;
                src: local("Montserrat Regular"), local("Montserrat-Regular"),
                    url(https://fonts.gstatic.com/s/montserrat/v13/JTUSjIg1_i6t8kCHKm459Wlhyw.woff2)
                        format("woff2");
                unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC,
                    U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122,
                    U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
            }
        `,
        body: "Montserrat",
        bodyFace: css`
            @font-face {
                font-family: "Montserrat";
                font-style: normal;
                font-weight: 400;
                src: local("Montserrat Regular"), local("Montserrat-Regular"),
                    url(https://fonts.gstatic.com/s/montserrat/v13/JTUSjIg1_i6t8kCHKm459Wlhyw.woff2)
                        format("woff2");
                unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC,
                    U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122,
                    U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
            }
        `,
        icons: "icomoon",
        iconsFace: css`
            @font-face {
                font-family: "icomoon";
                src: url("./fonts/IcoMoon-Free.ttf") format("truetype");
                font-weight: normal;
                font-style: normal;
            }
        `
    }
};

function App() {
    return (
        <ThemeProvider theme={theme}>
            <GlobalStyle theme={theme} />
            <HomePage />
        </ThemeProvider>
    );
}

function HomePage() {
    return <button>Continue</button>;
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

index.css

body {
    font-size: 16px;
    font-weight: bold;
    overflow-x: hidden !important;
    position: relative;
}

button {
    color: #fff;
    font-size: 20px;
    font-weight: bold;
    padding: 11px 60px 11px 50px;
    border-radius: 80px;
    position: relative;
    cursor: pointer;
    box-shadow: 0 10px 16px 0 rgba(0, 0, 0, 0.2),
        0 6px 20px 0 rgba(0, 0, 0, 0.19);
    border: 3px solid;
}

button:focus {
    outline: none;
}

button:active {
    outline: none;
}

button:hover {
    cursor: pointer;
}

button:after {
    content: "\ea3c";
    speak: none;
    font-style: normal;
    font-weight: normal;
    font-variant: normal;
    text-transform: none;
    line-height: 1;
    position: absolute;
    right: 10px;
    top: 28%;
    -webkit-font-smoothing: antialiased;
}

@quantizor
Copy link
Contributor

quantizor commented Nov 2, 2019 via email

@jenseralmeida
Copy link

jenseralmeida commented Nov 2, 2019

@probablyup, please hold on. This latest fonts issue was my fault. My current codebase, which has all the styling in index.css except for the dynamic properties, works with the rc1.

Just for the sake of testing, I will revert to my previous version where all the styling was managed by styled-components global style, to see if my previous issue is fixed with the current rc.1

@5h5ong
Copy link

5h5ong commented Nov 17, 2019

npmPackages:

  • "styled-components": "^4.4.0
  • "styled-reset": "^4.0.2

My SC version is not V5, but I have a similar problem for that. createGlobalStyle works very well as all, but only * part does not apply. IN PRODUCTION BUILD!
Font, box-sizing, background-color... that things all inside *, but is not applied.

export default createGlobalStyle`
  ${reset}
  * {
    @import url('https://fonts.googleapis.com/css?family=Roboto&display=swap');
    font-family: 'Roboto', sans-serif !important;
    box-sizing: border-box;
    background-color: red;
  }
  body {
    min-height: ${props => props.theme.minHeight};
    padding-top: ${props => props.theme.headerPadding};
  }
`;

@jonkwheeler
Copy link

jonkwheeler commented Nov 17, 2019

@5h5ong what happens if you change it to html * { ?

@5h5ong
Copy link

5h5ong commented Nov 17, 2019

@jonkwheeler Do you mean inside of css file? If then, Yes. Styles works fine in css file. I separated styles in css and html to solve this problem.

@jonkwheeler
Copy link

@5h5ong I was referring to the createGlobalStyle snippet you posted. Does changing * { to html * { fix anything?

@5h5ong
Copy link

5h5ong commented Nov 17, 2019

@jonkwheeler Oh..!

html * {
  ...
}

Does that mean? Thanks for the advice but nothing has changed.

@jonkwheeler
Copy link

Hmm alright. I was just curious if the css parser couldn't understand something. Thanks for trying. Maybe it's the @import. Odd indeed.

andyngo added a commit to andyngo/design-system that referenced this issue Nov 25, 2019
This is possibly a bug with styled-components where global styles are not injected when @import is used.

Reference: styled-components/styled-components#2670
@GiovanniFrigo
Copy link

The issue is still present in @storybook/react v5.2.5

I can also confirm that the issue is caused by the @import statement inside the global style. Removing that, the rest of the style is correctly applied to the node.

This is my globalStyle:

import { createGlobalStyle } from 'styled-components';

export const GlobalStyles = createGlobalStyle`
  body {
    @import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css');
    @import url('https://rsms.me/inter/inter.css');
    font-family: 'Inter', sans-serif;
    *, *::before, *::after {
      box-sizing: border-box;
    }
  }
`;

@PhEEP
Copy link

PhEEP commented Jan 28, 2020

We are experiencing a similar issue on v^4.4.0, here's what we found: Loading Klaviyo analytics.js file caused our global styling to disappear. If you're experiencing this issue, try blocking the file in your developer tools network panel. Here's the file for reference: https://a.klaviyo.com/media/js/analytics/analytics.js #2254 (comment)
Edit: linked comment edited to show that preventing re-render helped. We had a conditional after an user was authed that would render the same <GlobalStyle /> component. Moving the <GlobalStyle /> outside the conditional to render only once helped prevent this issue and our styles loaded as expected.

@kitten
Copy link
Member

kitten commented Jan 28, 2020

@GiovanniFrigo @import is not supported by styled-components so you should probably look into injecting that separately. BTW, it’s also not supposed to be scoped, since it’s an at-rule.

On this note, @font-face is also not supported. This is due to our lack of hoisting them. We skipped adding support for this for now since it’s tricky to make it work dynamically and with SSR. It’s easy enough to inject extra CSS through a multitude of other ways, so that’s why it’s been omitted

I’m pretty sure another bug in this issue that’s being mentioned, vendored rules is not occurring anymore, since we’ve fixed it.

I also saw :global which shouldn’t be used inside a global component. I’m not sure whether stylis supports it, but either way, it’s redundant in a global styles component.

@PhEEP yes, third party scripts can often mess with our style tags when they’re moving our unmount if the node, or even editing it 😱

All in all these issues in this thread all different and either in my list above or unrelated. So I’ll close and lock this issue, please create separate threads so we can track your problems and help you separately! ♥️

@kitten kitten closed this as completed Jan 28, 2020
@styled-components styled-components locked as off-topic and limited conversation to collaborators Jan 28, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
needs more info ✋ An issue that needs triaging and reproducible examples or more information to be resolved
Projects
None yet
Development

No branches or pull requests