Simple SCSS with 11ty
Tags: webdev, design, tutorial, beginners
Published: 2020-02-24 19:32:03

Since migrating my blog to DEV, I've been looking at rebuilding my website as a simple signpost to my various activities on the web, and with this I've been looking into static site generators, and focusing mostly on 11ty.

I've been looking through [philhawksworth/eleventyone](https://github.com/philhawksworth/eleventyone) which for the most part gives a nice overview of the workings of 11ty. But one thing it didn't include was SCSS preprocessing. Instead, Phil opted for standard css preprocessing.

One thing I'm good at is searching the internet, but try as I might for almost 5 long minutes, I couldn't find a good solution out there for this. Phil created a gulp-powered SCSS preprocessor, but I didn't really want to add gulp into the mix. He wrote about how as you add in SCSS your complexity increases but I don't think this _has_ to be the case. I carried on looking, and I found someone who was preprocessing SCSS and writing it to a file. I didn't want to generate files before I generate files either, that xzibits¹ too much recursion for my liking.

After looking at everything I'd seen so far, and deciding to do some thinking of my own, I came up with a way that you can easily add SCSS preprocessing to an 11ty project.

## The Solution 

As I understand it, by having a file with a `.11ty.js` suffix, you're able to introduce some functionality into an endpoint, the path of which you can define in the `permalink` field of the `data()` method in the class you return. You can then define the output of that endpoint by returning a string from the `render()` methods of that class.

Well, once you realise this, it's quite simple really. Assuming we have a directory structure like so, with the scss files within the includes directory and a JavaScript file within the css directory.

```
site/
site/_includes/
site/_includes/scss/
site/_includes/scss/main.scss
site/css/
site/css/style.11ty.js
site/index.md
```


All we need to do is use a scss-to-css module (in this case `node-sass-promise`), render the scss files into css, and then for good measure, clean it before we send it out.


```js
const path = require('path')
const sass = require('node-sass-promise')
const CleanCSS = require('clean-css')

const inputFile = path.join(__dirname, '../_includes/scss/main.scss')
const outputFile = path.join(__dirname, '../css/style.css')

const comment = `/* This is an example comment */`

module.exports = class {
  data() {
    return {
      permalink: 'css/style.css',
      eleventyExcludeFromCollections: true
    }
  }

  async render() {
    const { css } = await sass.render({ file: inputFile })
    const output = new CleanCSS({}).minify(css.toString()).styles

    return `${comment}\n\n${output}`
  }
}
```

Now, I'm _notorious_ for adding comments to the beginning of every source file. I'm old school, and also, I feel old. But when I work with a file that doesn't have a banner comment I don't feel right. With this in mind, I've also added the ability to place a header comment in while removing all other chaff from the scss and placing the clean, processed css afterwards.

This all results in the endpoint `css/style.css` being generated via the `render()` method and outputting something like this:

```css
/* This is an example comment */

*{margin:0;padding:0}body{padding:1rem;}h1{font-size:3rem;}
```

So to summarise, you create a file `site/css/style.11ty.js` in which you read from an input file `../_includes/scss/main.scss`, run it through some npm packages (sass, clean-css etc) and then return it as a string so that the 11ty generator can store it somewhere useful.

----

On the subject of banner comments, I much prefer fancier versions that a simple line of text, such as _catsofinternet.org_...

```
            _              __ _       _                       _                    
           | |            / _(_)     | |                     | |                   
   ___ __ _| |_ ___  ___ | |_ _ _ __ | |_ ___ _ __ _ __   ___| |_   ___  _ __ __ _ 
  / __/ _` | __/ __|/ _ \|  _| | '_ \| __/ _ \ '__| '_ \ / _ \ __| / _ \| '__/ _` |
 | (_| (_| | |_\__ \ (_) | | | | | | | ||  __/ |  | | | |  __/ |_ | (_) | | | (_| |
  \___\__,_|\__|___/\___/|_| |_|_| |_|\__\___|_|  |_| |_|\___|\__(_)___/|_|  \__, |
                                                                              __/ |
                                                                             |___/ 
```

Or _internetdogs.com_...

```

                                                    
      .-.          /                            /   
      `-'.  .-.---/---.-.  ).--..  .-.   .-.---/--- 
     /    )/   ) /  ./.-'_/      )/   )./.-'_ /     
  _.(__. '/   ( /   (__.'/      '/   ( (__.' /      
          .    `-                     `-            
         /                                          
    .-../ .-._..-.    .      .-.  .-._..  .-. .-.   
   (   / (   )(   )  / \ .-.(    (   )  )/   )   )  
    `-'-..`-'  `-/-'/ ._)`-' `---'`-'  '/   /   (   
             -._/  /                             `-'

```


Or _httprefs.org_...

```

 __ __  ______  ______  ____  ____     ___  _____  _____      ___   ____    ____ 
|  |  ||      ||      ||    \|    \   /  _]|     |/ ___/     /   \ |    \  /    |
|  |  ||      ||      ||  o  )  D  ) /  [_ |   __(   \_     |     ||  D  )|   __|
|  _  ||_|  |_||_|  |_||   _/|    / |    _]|  |_  \__  |    |  O  ||    / |  |  |
|  |  |  |  |    |  |  |  |  |    \ |   [_ |   _] /  \ | __ |     ||    \ |  |_ |
|  |  |  |  |    |  |  |  |  |  .  \|     ||  |   \    ||  ||     ||  .  \|     |
|__|__|  |__|    |__|  |__|  |__|\_||_____||__|    \___||__| \___/ |__|\_||___,_|
                                                                                 
```

But I mean, that's not really important is it? If you _do_ like banner comments like this, the [patorjk taag](http://patorjk.com/software/taag/) site is super useful and has been for many years. 

Check it out.

----

¹ xzibit joke not typo