Next.js: Bootstrap 4, CSS Selector order

Created on 7 Sep 2018  路  13Comments  路  Source: vercel/next.js

Question about Next.js

Questions should be posted on https://spectrum.chat/next-js

I'm not sure whether this is bug/feature/question, so I decided to post this here. So the problem is following: Order of final css is very chaotic and main problem is that I want to have bootstrap at the top of the css. Or inside another file located in .next/css.

_app.js

import '../src/styles/main.scss' // Main style for whole page

class MyApp extends App {
  render () {
    const { Component, pageProps, reduxStore } = this.props
    return (
      <Container>
        <IntlProvider {...config}>
          <Provider store={reduxStore}>
            <React.Fragment>
              <Header />
              <Component {...pageProps} />
              <Footer />
            </React.Fragment>
          </Provider>
        </IntlProvider>
      </Container>
    )
  }
}

export default withReduxStore(MyApp)

And _document.js:

import React from 'react'
import Document, { Head, Main, NextScript } from 'next/document'

class MyDocument extends Document {
  render = () => (
    <html lang='en'>
      <Head>
        <meta charSet='utf-8' />
        <meta httpEquiv='X-UA-Compatible' content='IE=edge' />
        <meta name='viewport' content='width=device-width, initial-scale=1, shrink-to-fit=no' />
        <link rel='stylesheet' type='text/css' href='/_next/static/style.css' /> // Generated style by next
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </html>
  )
}

export default MyDocument

Example component on page:

import '../styles/brands.scss' // Importing styles from styles directory

class Brands extends React.Component {

Brands.scss for that Component

@import '../../../../../styles/partials/extends';

.brands-table {

Styles:

@import url('https://fonts.googleapis.com/css?family=Roboto:400,500,900');
@import './partials/constants';
@import "~bootstrap/scss/bootstrap"; // Modified bootstrap with variables
@import './partials/globals';
@import './partials/buttons';
@import './partials/form';

And here's the problem, final css located in style has very different order from what would I expect:

IconComponent styles
Footer Styles
Whole homepage
Bootstrap // This style should be first because it's located in _app, Am I right?
Rest of main styles

```packpage.json
{
"// Some information omited :)": "",
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.4",
"@fortawesome/free-regular-svg-icons": "^5.3.1",
"@fortawesome/free-solid-svg-icons": "^5.3.1",
"@fortawesome/react-fontawesome": "^0.1.2",
"@zeit/next-sass": "^0.2.0",
"autoprefixer": "^9.1.3",
"axios": "^0.18.0",
"bootstrap": "^4.1.3",
"classnames": "2.2.6",
"express": "^4.16.3",
"global": "^4.3.2",
"i18n-iso-countries": "^3.7.5",
"lru-cache": "^4.1.3",
"next": "^6.1.1",
"next-assets-import": "^0.0.2",
"next-optimized-images": "^1.4.1",
"next-routes": "^1.4.2",
"node-fetch": "^2.2.0",
"node-sass": "^4.9.3",
"npm": "^6.4.1",
"nprogress": "^0.2.0",
"postcss-loader": "^3.0.0",
"postcss-scss": "^2.0.0",
"prop-types": "^15.6.2",
"ramda": "^0.25.0",
"react": "^16.4.2",
"react-custom-scrollbars": "^4.2.1",
"react-dom": "^16.4.2",
"react-ga": "^2.5.3",
"react-google-recaptcha": "^1.0.0",
"react-helmet": "^5.2.0",
"react-intl": "^2.4.0",
"react-intl-auto": "^0.0.3",
"react-intl-po": "^2.2.2",
"react-intl-translations-manager": "^5.0.3",
"react-player": "^1.6.4",
"react-redux": "^5.0.7",
"react-thunk": "^1.0.0",
"reactstrap": "^6.4.0",
"redis": "^2.8.0",
"redux": "^4.0.0",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.3.0",
"standard": "^12.0.1",
"validator": "^10.7.0"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^9.0.0",
"babel-jest": "^23.4.2",
"babel-plugin-inline-dotenv": "^1.1.2",
"babel-plugin-module-resolver": "^3.1.1",
"babel-plugin-react-intl": "^2.4.0",
"babel-plugin-react-intl-auto": "^1.1.0",
"babel-plugin-transform-assets-import-to-string": "^1.2.0",
"babel-plugin-transform-inline-environment-variables": "^0.4.3",
"enzyme": "3.5.0",
"enzyme-adapter-react-16": "1.3.0",
"eslint": "^5.4.0",
"extract-react-intl": "^0.6.0",
"extract-react-intl-messages": "^0.10.0",
"gulp-babel": "^8.0.0",
"identity-obj-proxy": "^3.0.0",
"jest": "^23.5.0",
"jest-cli": "^23.5.0",
"jest-static-stubs": "0.0.1",
"maid": "^0.3.0",
"react-addons-test-utils": "15.6.2",
"react-test-renderer": "16.4.2",
"redux-devtools-extension": "^2.13.5",
"standard": "^12.0.1",
"stylelint": "^9.5.0",
"stylelint-config-standard": "^18.2.0",
"stylelint-scss": "^3.2.0"
},
"standard": {
"env": [
"jest",
"browser"
],
"parser": "babel-eslint"
}
}

next.config.js
```js
const withSass = require('@zeit/next-sass')
const withAssetsImport = require('next-assets-import')
const withOptimizedImages = require('next-optimized-images')

module.exports = withAssetsImport(withOptimizedImages(withSass()))

Most helpful comment

@timneutkens I have already tried @canary but it's not fixed yet. I will try to modify webpack configuration.

All 13 comments

@VeeeneX yeah it's the exact same issue, reading through the extract-text-webpack-plugin issue it mentions mini-css-extact-plugin has fixed this. Next 7 will have webpack 4 + next-css will be using that plugin instead of extract-text-webpack-plugin. You can already try this using next@canary and @zeit/next-css@canary.

I'm going to close this issue as we can't fix this upstream issue on our side.

@timneutkens I have already tried @canary but it's not fixed yet. I will try to modify webpack configuration.

@timneutkens, still unable to specify the import order of css/sass files with css-mini-extract-plugin. It seems to be loading them in alphabetical order instead. Is there a solution for this?

Has anyone had any luck with a solution for this? We just got bit for the first time during a production deploy.

I will try to dig into it a bit

I have the same issue, it doesn't look to be fixed.

Same issue here, css files imported in _app override my internal component's custom styles. Ended up importing styles in the head component placed in _document.

As one solution...

in my situation, global Bootstrap CSS was overriding Sass CSS Module styles.

I fixed this by importing Bootstrap via cdn

<link
                        rel="stylesheet"
                        href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
                        integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
                        crossOrigin="anonymous"
                    />

in _document.js

As opposed to importing it from the library ('bootstrap') in _app.js.

This fixed the issue for me.

This should be fixed with the new CSS support, which is available on canary with the experimental.css flag!

This should be fixed with the new CSS support, which is available on canary with the experimental.css flag!

Hi @Timer , thanks for the reply - I was wondering how to enable the experimental.css flag as I can't find any relevant documentation; do you mind expanding on how to go about that? And are you referring to the canary release of next or @zeit/next-css? Thank you!

We're referring to the built-in experimental support. Be sure to remove all traces of @zeit/next-css, then create a next.config.js with:

// next.config.js
module.exports = {
  experimental: { css: true }
}

You must be on the latest next@canary.

We're referring to the built-in experimental support. Be sure to remove all traces of @zeit/next-css, then create a next.config.js with:

// next.config.js
module.exports = {
  experimental: { css: true }
}

You must be on the latest next@canary.

@Timer makes sense, thank you!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

knipferrc picture knipferrc  路  3Comments

irrigator picture irrigator  路  3Comments

swrdfish picture swrdfish  路  3Comments

kenji4569 picture kenji4569  路  3Comments

formula349 picture formula349  路  3Comments