Ordering stylesheets before gulp-concat

Hello,

I’ve been struggling with an issue but I’ve finally solved it. I’m including the problem description and a solution for Sage users.

Let’s say I’m using Bootstrap Sass because I do CSS in Sass. I’m also using Bootstrap Material Design. However, I want to change the primary color of Material Design, so I use bower to install it as a package. Combining Less and Sass? No problem with Sage! In assets/styles folder I create two files: main.less and main.scss.

In main.scss, I include Bootstrap Sass _bootstrap.scss file from bower_components and then other .scss files. In main.less, I include material.less from bower_components and then change the color scheme (not important for this issue).

After that, I put both of these files in my manifest.json as:

"main.css": {
   "files": ["styles/main.less", "styles/main.scss"]
}

Running the gulp (gulp styles) task, styles gets concatenated in this order:

  1. Bootstrap
  2. My style modifications
  3. Bootstrap Material Design

(= main.scss before main.less)

Material Design styles have to be included after Bootstrap styles and for this it works correctly. But there is a problem…

The problem

From the list above, we can see that Boostrap Material Design style definitions overwrite my style modifications. For example:

// my styles, I want it to be red
body {
   background-color: red;
}
// styles of material design
body {
   background-color: #eee;
}
// the final concatenated main.css styles
body {
   background-color: #eee;
}

To fix this, I could write background-color: red !important; but that’s not good, styles should be included in a better order. Therefore, I used gulp-order library and put

// gulpfile.js
// some code of cssTasks function

.pipe($.order, ['**/*'])
.pipe($.concat, filename)

// some more code

in the gulpfile.js in the cssTasks function.

['**/*'] will order files by in the alphabetical order. The last thing to do is to properly prefix your style files, for example:

// assets/styles

10_bootstrap.scss
20_material-design-bootstrap.less
30_main.scss

In the first file, I import the Bootstrap main file. In the second one, I import the Material Design main file and redefine the primary color scheme variable. In the last file, all of my style modifications are imported. Put all of these files in the manifest.json file and main.css will be concatenated in the proper order.

So a couple things:

Original Problem

Gulp-order is definitely not necessary. You can easily do

"main.css": {
   "files": ["styles/bootstrap.scss", "styles/material-design-bootstrap.less", "styles/main.scss"]
}

To get the same result. The order in the array is the order they get concatenated.

Unhelpful Suggestion

In your situation I would just use Less. Go ahead and ditch Sass for this project. I personally prefer Sass by a longshot but I am not married to any preprocessor really. It all depends on what the project requirements are. If the project hinges on that important Less dependency I would just use Less and be done with it.

@austin thanks for the reply.

Yes, I tried doing it without gulp-order but unsuccessfully. It seems like the Less preprocessor always moves its generated .css file at the top of the files array in the pipe before the concat task.

Here is a result from .pipe(debug) (gulp-debug):

[18:03:37] Starting 'clean'...
[18:03:37] Finished 'clean' after 3.63 ms
[18:03:37] Starting 'default'...
[18:03:37] Starting 'build'...
[18:03:37] Starting 'wiredep'...
[18:03:37] Finished 'default' after 191 ms
[18:03:37] Finished 'wiredep' after 229 ms
[18:03:37] Starting 'styles'...
[18:03:38] gulp-debug: bower_components/bootstrap-material-design/dist/css/ripples.css
[18:03:39] gulp-debug: assets/styles/10_bootstrap.css
[18:03:39] gulp-debug: assets/styles/30_main.css
[18:03:40] gulp-debug: assets/styles/20_material-design-bootstrap.css
[18:03:40] gulp-debug: 4 items
[18:03:42] Finished 'styles' after 4.75 s
[18:03:42] Starting 'jshint'...
[18:03:42] Finished 'jshint' after 375 ms
[18:03:42] Starting 'scripts'...
[18:03:45] Finished 'scripts' after 2.75 s
[18:03:45] Starting 'fonts'...
[18:03:45] Starting 'images'...
[18:03:47] gulp-imagemin: Minified 0 images
[18:03:47] Finished 'images' after 1.65 s
[18:03:47] Finished 'fonts' after 1.77 s
[18:03:47] Finished 'build' after 9.87 s

And manifest.json:

"dependencies": {
        "main.js": {
            "files": [
                "scripts/main.js"
            ],
            "main": true
        },
        "main.css": {
            "files": [
                "styles/10_bootstrap.scss",
                "styles/20_material-design-bootstrap.less",
                "styles/30_main.scss"
            ],
            "main": true
        },
        "jquery.js": {
            "bower": ["jquery"]
        },
        "modernizr.js": {
            "bower": ["modernizr"]
        }
    },

You are right, I should have gone with Less. However, I already have some styles in Sass and I don’t really need Less. Also I’ve never done Less before.

That sucks. I’m creating a reduced test case to verify this behavior. Follow along at: https://gist.github.com/austinpray/15d4514e93217a66e6d3

1 Like

Hmm okay so I’m not able to reproduce this:

So it might not be a gulp-less problem. Can you fork and modify that reduce testcase until it fails?

Ah okay you know what. Was able to reproduce this.

Try running gulp sass+less and you will get the same behavior as you are seeing.

Alright shoot. Was able to reproduce with only gulp-sass. Gulp-sass is the problem here:

Submitted as a bug to gulp-sass: https://github.com/dlmanning/gulp-sass/issues/236

@lamosty would you please run the reduce testcase in the above issue and report your findings over at: https://github.com/dlmanning/gulp-sass/issues/236 ?

Thanks for your investigation efforts.

Looks like I’m gonna have to integrate gulp-order into the default workflow :confused:

Why the upset smiley? It doesn’t slow the task that much as far as I can observe. :smile:

Gonna add some complexity to the gulpfile and https://github.com/austinpray/asset-builder

@lamosty check this out: https://github.com/roots/sage/pull/1485

This should fix your original issue.