Compiling SASS
Install and configure the grunt-contrib-sass plugin to automatically compile SASS files into CSS.
Compiling SASS
SASS (Syntactically Awesome Style Sheets) is a CSS preprocessor that adds variables, nesting, mixins, and more to CSS. But browsers cannot read SASS — it must be compiled into regular CSS. In this episode you will set up the grunt-contrib-sass plugin to compile your SASS files automatically.
Why Use SASS?
| SASS Feature | What It Does | Example |
|---|---|---|
| Variables | Store reusable values | $primary: #3498db; |
| Nesting | Nest selectors inside each other | .nav { a { color: #fff; } } |
| Mixins | Reusable blocks of styles | @mixin flex-center { ... } |
| Partials | Split CSS into modular files | @import 'variables'; |
| Math | Perform calculations | width: 100% / 3; |
Prerequisites: Ruby SASS or LibSass
The grunt-contrib-sass plugin requires Ruby and the sass gem installed on your system. Alternatively, you can use grunt-sass which uses LibSass (the C/C++ implementation) and does not require Ruby.
# Option A: Ruby SASS
gem install sass
# Option B: Use grunt-sass with node-sass instead
npm install grunt-sass node-sass --save-dev
We will use grunt-contrib-sass (Ruby SASS) in this tutorial, but the configuration is nearly identical for grunt-sass.
Step 1: Install the Plugin
npm install grunt-contrib-sass --save-dev
Step 2: Configure the Task
Add the sass task to your Gruntfile.js initConfig:
sass: {
dev: {
options: {
style: 'expanded',
},
files: {
'dist/css/styles.css': 'src/scss/styles.scss',
},
},
prod: {
options: {
style: 'compressed',
},
files: {
'dist/css/styles.min.css': 'src/scss/styles.scss',
},
},
},
Understanding the Configuration
The files property uses a destination: source format (the reverse of src/dest used in concat). Each key is the output file path and the value is the source SASS file.
| Target | Output Style | Output File | Use Case |
|---|---|---|---|
dev | expanded (readable) | dist/css/styles.css | Development — easy to read and debug |
prod | compressed (minified) | dist/css/styles.min.css | Production — smallest possible file size |
SASS Output Styles
| Style | Description |
|---|---|
nested | Indented to reflect SASS nesting structure |
expanded | Standard CSS formatting — each property on its own line |
compact | Each rule on a single line |
compressed | Fully minified — all whitespace removed |
expanded output
body {
font-family: Arial, sans-serif;
background: #ecf0f1;
color: #333;
margin: 0;
padding: 20px;
}
compressed output
body{font-family:Arial,sans-serif;background:#ecf0f1;color:#333;margin:0;padding:20px}
Step 3: Load the Plugin and Register Tasks
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.registerTask('default', ['concat', 'sass:dev']);
grunt.registerTask('build', ['concat', 'sass:prod']);
The default task compiles SASS in expanded (readable) mode for development. The build task compiles in compressed mode for production.
Step 4: Run It
# Development build
grunt
# Production build
grunt build
# Just compile SASS (dev target)
grunt sass:dev
# Just compile SASS (prod target)
grunt sass:prod
Compiling Multiple SASS Files
sass: {
dev: {
options: { style: 'expanded' },
files: {
'dist/css/main.css': 'src/scss/main.scss',
'dist/css/admin.css': 'src/scss/admin.scss',
'dist/css/blog.css': 'src/scss/blog.scss',
},
},
},
Each key-value pair in the files object compiles one SASS file to one CSS file. You can have as many pairs as you need.
Using Dynamic File Mappings
sass: {
dev: {
options: { style: 'expanded' },
files: [{
expand: true,
cwd: 'src/scss/',
src: ['*.scss'],
dest: 'dist/css/',
ext: '.css',
}],
},
},
| Property | Purpose |
|---|---|
expand: true | Enable dynamic mapping |
cwd | Current working directory for source files |
src | Glob pattern to match source files |
dest | Output directory |
ext | Change the file extension on output files |
Dynamic mappings automatically compile any .scss file found in the source directory. Add a new SASS file and it is compiled without changing the Gruntfile.
Updated Gruntfile So Far
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
options: { separator: ';\n' },
dist: {
src: ['src/js/*.js'],
dest: 'dist/js/bundle.js',
},
},
sass: {
dev: {
options: { style: 'expanded' },
files: {
'dist/css/styles.css': 'src/scss/styles.scss',
},
},
},
});
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.registerTask('default', ['concat', 'sass']);
};
Key Takeaways
grunt-contrib-sasscompiles SASS/SCSS files into regular CSS- The
filesproperty usesdestination: sourceformat (reversed fromsrc/dest) - Four output styles:
nested,expanded,compact,compressed - Use different targets for development (expanded) and production (compressed) builds
- Dynamic file mappings with
expand: trueautomatically handle new files without config changes - Run specific targets with
grunt sass:devorgrunt sass:prod