Sass layouts supported?

Hello world!

I was trying to build a SASS layout to include a number the variables that I parse from YAML data and config files. I find this convenient since that way I don’t need to be copying and pasting the same lines of code around for every main file I create. However, although I get no errors, the layout does not get sourced.

Is this feature supported? Is there another way of doing this? Since I am new to Jekyll I was hesitant of opening a PR on github.

Thanks!

For SASS loading basics

Follow SASS in the Jekyll docs

or check this Minima 2.5.1 theme (the one on GH Pages).

Loaded in assets/main.scss

Used here.

I don’t know if Jekyll supports Liquid variables in sass files but I would guess so.
Because in a .css at least, with frontmatter, you can use a for loop etc. And can use

---
---
{{ site.data.foo | inspect }}

To reference _data.foo.yml as a data file.

Or site.title for _config.yml.

Thanks Michael!

I have been following the docs, however I did not find any reference to SASS layouts. What I want to do is something like this:

---
# _layouts/colors.scss
---
$my-color: {{ site.colors.green }};
---
# css/main.scss
layout: colors
---
body {
    background-color: $my-color;
}

Variables are supported in main sass files (i.e. not an import in sass_dir).

1 Like

Here 's what I do:

in _layout/default.html

{% capture styles %}
     {% include main.css %}
{% endcapture %}

cat _includes/main.css

@import "main.scss"

in _config.yml

sass:
    load_paths:
        - _sass
        - node_modules
        - assets/css
        - assets/vendor
    style: compressed

and finally in assets/css/main.scss

$body-background-color: #2B2E31;
$content-max-width: 100%;
$content-color: #222;
$content-background-color: #fff;
$brand-colour: #3583d6;
$brand-colour-light: mix($brand-colour, $content-background-color, 10%);

$nav-header-background-color: $brand-colour;
$nav-header-height: 60px;
$nav-background-color: #f5f5f5;
$nav-width: 300px;
$space: 20px;
$mobile-break: 700px;
$full-width-break: $nav-width + ($space * 4) + 700;

/* the fol;owing files iare in _sass/_filensma.scss
example: _sass/_layout.scss */

@import "mixins";
@import "normalize";
@import "pygments";
@import "typography";
@import "code";
@import "tables";
@import "layout";
1 Like

I also include random stuff like

@import "bootstrap/scss/bootstrap";

That why I have node_modules and assets/vendor in my sass - load_paths

I haven’t encountered SASS layouts and I don’t know the usecase. I mean CSS should ideally be outputted as a single file to be reused across the whole site. You shouldn’t be using some CSS files on some pages and some on others, but one file and then you use classes etc. to choose a style on your post page vs your homepage etc.

If you use the approach I linked to in minima, you’ll see a file of variables and multiple underscore files and then a minima.scss file which ties them altogether.

1 Like

Hi Michael, this is no use since I cannot use liquid syntax in sass imports (i.e. files in _sass directory). Therefore, I am no table to parse jekyll variables to sass variables in one such file, forcing me to place that logic in a main file, and making sass layouts desirable.

Nonetheless, I get your point of having only one css file for the whole site. However, having one css file per page style will save bandwidth and make the website faster to load. Also, I may simply want to use different styles for different pages, in which case it makes no sense loading all the extra stuff, going through the trouble of duplicating every single class, or isolating standard selectors such as a.

I am not seeing how this solves the issue though… I still can’t have a sass layout (or equivalent) from which to build new sass files. Am I missing something?

A workaround is to use includes instead of a layout

I think you are trying to do a few things here. One is to create a common set of variables you can use throughout the site. That is doable with TerminalAddict’s approach (which I elaborate on in this post). Simply create a scss file (or files) that contain the variables you want, rather than trying to use Jekyll/Liquid variables. The approach is preferred because it is portable and not tied to just Jekyll and it follows a good coding practice. I like to use this rule: sass variables are for layout and Jekyll/Liquid/Data variables are for HTML.

As for creating a scss file per page, I went down that path and ultimately realized it was a bad idea just because any time I changed one page’s details, I had to go and change a whole bunch of SCSS files so other pages looked similar.

You can choose to do it on a per-page basis if you want and I totally think that is reasonable if that is what you want. As a matter of fact, I did that for certain pages on my site and I even created re-usable HTML code that has its own matching scss file. Read on for how I did that.

In my mind, you can create as many css/scss files you desire, but you will find that compiling them into a single file is the right way to go.

Site example

I created a site for my company, Cambermast. I will walk you through the process. Maybe you already have it and I’m repeating myself, or maybe it helps. Here is the repo if you want to take a look at it:

I created a folder called _sass/abstracts and one of those files is called _variables. As you can see, it contains all the common variables I use throughout the site. This is the equivalent of creating Liquid variables using Jekyll data, but in a sass-ey way.

Further down, you can see I created another folder called _sass/layout. Here is where I create all my individual scss files. For example, you can see I have a feed of posts that I want to look unique throughout the site, so I created an individual _feed.scss file. I also have scss files for pages, posts, and so on. I create them for shared elements or individual pages as you are alluding to.
Note how I am using the sass variables for margin-left and margin-right.

Similar to the minima theme, I created a single file, in my case called _sass/cambermast.scss, that imports all the variable and layout (and mixin) scss files, combining them into one large scss file.

In the _includes folder, I create a head.html file that links to that one stylesheet. That head.html file gets re-used for every single HTML page on my site, so I do not have to re-create the HTML structure every time I create a new page. This is important as it will greatly reduce the amount of testing you have to do, reduce the number of pages you have to compile, and generally make your life easier.

The method I am showing you here is essentially mimicking how the minima theme works. As you can see in the images above, I have a lot of scss files to import with a decent amount of sass variables and unique layouts, but after all is said and done, my single compiled css file is only about 15kb, which is super small and while I say this as an assumption, I think it is a smart assumption, that the browser will cache the css after the first visit rather than re-load for each page. Unless you are creating dozens or hundreds of complex css files, I really don’t think you need to concern yourself with Jekyll building a single css file for all your pages.
image

Hope this helps!

3 Likes

Hi Bill,

Wow! This is very helpful indeed. A lot of useful things to extract from what you are saying. Thanks a lot.

Just to clarify, what I had in mind was to have a scss file which parses liquid/jekyll variables into scss variable; then using that parsed set of variables throughout the rest of the stylesheets. This way I would make the scss code reusable —as you suggest— while still having just one centralized file in which to make changes.

$colors: (
{% for color in site.colors %}
  '{{ color[0] }}': {{ color[1] }},
{% endfor %}
);

@function color($color-name) {
  @return map-get($colors, $color-name);
}

Now, I did not want to suggest that I intended using one css file per page. Only that I can find it useful to have, say, a couple of different stylesheets for collecting different styles inside a single webpage. However, that is the least important thing in my argument, and did not want to get into these fine details to avoid losing the focus of my question. I am sorry if I failed at making this clear.

The reason I was wondering about scss layouts (as in /_layouts) is that, in order to reuse the parsing logic for different files, layouts are useful. Particularly, they are easier to use than their workaround /_includes.

For the sake of discussion (I know there are different approaches to this but bear with me), say we wanted to have both a regular and a compact view of a feed. We could then use two different css files: main.css and compact.css. In that case, we would like to reuse the color-parsing logic in both the main.scss and compact.scss files. If layouts were supported, it would be as easy as placing the above mentioned logic in /_layouts/colors.scss and then adding layout: colors to the front matter of said files.

Of course, this can also be done placing the logic in /_includes/colors.scss and going for something like: {% include colors.scss %}. However, if at some point we wanted to have code before as well as after the contents, we would need to add two lines to the files instead of just one. Not a huge amount of extra work, I know, but why would we even have a front matter in scss files if not to actually use it?

I hope this helped clarify the context of my question. Whose answer, I guess, is simply NO, sass layouts are not supported. I would love to learn why this is the case though.

PULL REQUEST: feat: add support for sass layouts · Issue #8573 · jekyll/jekyll · GitHub

While I totally understand you are asking some specific questions and want the answers, I feel my responses will not properly represent an answer that is the “right” way to create your Jekyll site. If you do not mind, I would like to step back and completely remove Jekyll and the underlying technology for a moment. I want to give you the answers to your question, plus a solution that will work for you long term.

Here is my take on what you are asking for, in the form of a user story:

User story

As a website developer, I want the content on a page to display a different layout for the site depending on the browser’s resolution. That layout may include a different look-and-feel, and the CSS styles may also change.

Example scenarios

  1. For a full-size browser greater than 800 pixels in width, I want to display two vertical columns, one with the blog content and one with advertisements. The titles will be purple, and the content will have a grey background.
  2. For a more compact browser, less than 800 pixels in width, I want to display one vertical column with the blog content and no ads. The title will be dark blue, and the background will be the default display for that browser.

Does that get at what you are looking to do? If not, could you lay out the requirement in this fashion without thinking about Jekyll or the underlying technology?

Since you are mentioning different layouts of the same feed, check out my 3-part video series that shows you how to create a single feed for your posts that can look very different based on how you want to display the content and the size of the display. Maybe this is what you want?

P.S. In the meantime, I did try adding data to a css/scss file, and that does not work (which I expected but did confirm). I tried adding the data with and without front matter. If adding Jekyll (Liquid) data to scss/css is possible, I have not figured it out.

1 Like