SASS – Output separate stylesheets for page templates

Trying to understand the best practice for structuring my sass underscores project.

I have a basic working environment using npm and grunt, and get my main css compiled, but i want to create multiple page templates in a sub folder, and have their respective .scss file be output in a /layout folder so that i can enqueue the separate page template stylesheets as .css after the main stylesheet in function.php

Read More

i structured my project files in roughly this order: // updated //

.gitignore
404.php
archive.php
comments.php
/compiled
    style-human.css // Readable CSS Before prefixing //
    style.css // Minified CSS Before Prefixing //
    /page-layouts
        page-frontage.human.css // Readable page-template CSS before prefixing //
        page-frontage.css // minified page-template CSS before prefixing //
/fonts
footer.php
functions.php
gruntfile.js
header.php
/inc
index.php
/js
/languages
/node_modules
package.json
/page-layouts
    page-frontage.css // prefixed minified CSS to be Enqueued after main style.css in functions.php //
    page-frontage-human.css // prefixed readable CSS //
/page-templates
    page-frontpage.php

page.php
rtl.css
/sass
    _normalize.scss
    /elements
    /forms
    /layout
        _footer
        _header
        /page-layouts
            _page-frontpage.scss 
    /media
    /mixins
    /modules
    /navigation
    /site
    style.css // @imports everything SCSS except page-layouts //
    /variables-site
search.php
sidebar.php
single.php
style-human.css // readable main stylesheet //
style.css // minified main stylesheet Enqueued in functions.php //
/template-parts    

This is the code i used in my gruntfile.js

module.exports = function(grunt){

    grunt.initConfig({

        pkg: grunt.file.readJSON('package.json'),

        /**
        * sass task
        */
        sass: {
            dev: {
                options: {
                  style: 'expanded',
                    sourcemap: 'none',
                },
                files: {
                 'compiled/style-human.css': 'sass/style.scss'   
                }
        }, 
        dist: {
                options: {
                  style: 'compressed',
                    sourcemap: 'none',
                },
                files: {
                 'compiled/style.css': 'sass/style.scss'   
                }
            }
        },

        /**
        * Autoprefixer
        */
        autoprefixer: {
          options: {
           browsers: ['last 2 versions']
          },
            // prefix all files //
            multiple_files: {
             expand: true,
                flatten: true,
                src: 'compiled/*.css',
                dest: ''
            }
        },

        /**
        * Watch task
        */
        watch: {
            css: {
                files: '**/*scss',
                tasks: ['sass','autoprefixer']    
        }
    }

    });
    grunt.loadNpmTasks ('grunt-contrib-sass');
    grunt.loadNpmTasks ('grunt-contrib-watch');
    grunt.loadNpmTasks ('grunt-autoprefixer');
    grunt.registerTask('default',['watch']);
}

Now i have tried a couple of different solutions but I’m nowhere near to understand how i should structure my gruntfile.js so that it outputs my two page-templates scss as auto prefixed css in the layout folder.

Related posts

2 comments

  1. Sort of managed to find a workable solution, probably not the most elegant one, but it works, sort of…

    I structured my files like this:

    .gitignore
    404.php
    archive.php
    comments.php
    /compiled
        style-human.css //-- Readable CSS Before prefixing --//
        style.css //-- Minified CSS Before Prefixing --//
        /page-layouts
            frontage.human.css //-- Readable page-template CSS before prefixing --//
            frontage.css //-- minified page-template CSS before prefixing --//
    /fonts
    footer.php
    functions.php
    gruntfile.js
    header.php
    /inc
    index.php
    /js
    /languages
    /node_modules
    package.json
    /page-layouts
        frontage.css //-- prefixed minified CSS to be Enqueued after main style.css in functions.php --//
        frontage-human.css //-- prefixed readable CSS --//
    /page-templates
        frontage.php //-- code for template goes here, Enqueued in functions.php --//
    page.php
    rtl.css
    /sass
        _normalize.scss
        /elements
        /forms
        /layout
            _footer
            _header
            /page-layouts //-- working folder for all page templates --//
                _frontpage.scss //-- SASS for page template goes here! --//
        /media
        /mixins
        /modules
        /navigation
        /page-templates
            frontpage.scss //-- @imports content of ../layout/page-layouts/_frontpage.scss --//
        /site
        style.css //-- @imports everything SCSS except /page-layouts --//
        /variables-site
    search.php
    sidebar.php
    single.php
    style-human.css //-- readable main stylesheet --//
    style.css //-- minified main stylesheet Enqueued in functions.php --//
    /template-parts    
    

    And i structured my Gruntfile.js as follows

    module.exports = function(grunt){
    
        grunt.initConfig({
    
            pkg: grunt.file.readJSON('package.json'),
    
            /**
            * sass task
            */
            sass: {                // Task
                dev: {             // Target
                    options: {     // Target options
                      style: 'expanded',
                        sourcemap: 'none',
                    },
                    files: {       // Dictionary of files
                     'compiled/style-human.css': 'sass/style.scss', // 'destination': 'source'
                        'compiled/page-layouts/frontpage-human.css': 'sass/page-templates/frontpage.scss'   // 'destination': 'source'
                    }
            }, 
            dist: {             // Target
                    options: {  // Target options
                      style: 'compressed',
                        sourcemap: 'none',
                    },
                    files: {       // Dictionary of files
                     'compiled/style.css': 'sass/style.scss',   // 'destination': 'source'
                        'compiled/page-layouts/frontpage.css': 'sass/page-templates/frontpage.scss' // 'destination': 'source'
    
                    }
                }
            },  // close sass task
    
            /**
            * Autoprefixer
            */
            autoprefixer: {
              options: {
               browsers: ['last 2 versions']
              },
                // prefix all files //
                multiple_files: {
                 expand: true,
                    flatten: true,
                    src: 'compiled/*.css',
                    dest: ''
                },
                // prefix frontpage template //
                multiple_files: {
                 expand: true,
                    flatten: true,
                    src: 'compiled/page-layouts/*.css',
                    dest: './page-layouts'
                },
            },
    
            /**
            * Watch task
            */
            watch: {
                css: {
                    files: '**/*scss',
                    tasks: ['sass','autoprefixer']    
            }
        }
    
        });
        grunt.loadNpmTasks ('grunt-contrib-sass');
        grunt.loadNpmTasks ('grunt-contrib-watch');
        grunt.loadNpmTasks ('grunt-autoprefixer');
        grunt.registerTask('default',['watch']);
    }
    

    Basically this works how i intended it to, the page-template stylesheets get saved as human readable/minified autoprefixed versions in the intended page-layouts folder, so that i can Enqueue them after the main style.css in functions.php

    Only one “small” issue left to work out, my page-template scss files does not understand variables…

  2. For what I see, your default task only launch the watch task, who will only launch the sass and autoprefixer task if a scss file is updated.

    You should use :

    grunt.registerTask('default',['sass','autoprefixer']);
    

    In practice, we don’t place the watch task into the default task, because it stop the thread. We call the watch task instead, once the server is started. (use the command grunt watch in a terminal at the same level of your gruntfile)

Comments are closed.