iteratus
iteratus

Reputation: 155

How NOT to combine all CSS into one file with SASS and bootstrap

I'm relatively new to SASS and bootstrap. I use bootstrap with SASS and struggle a little bit with a concept.

I always used CSS like this: one base CSS-file with the basic layout (eq. base.css). Every template includes additionally a different CSS-file (eq. sitemap.css, team.css, news.css). This CSS-files only contain the parts of the respective templates. So I can overwrite the definitions in the previous files.

In SASS everything is compiled in one file. In combination with bootstrap I actually struggle with the concept I used until now.

Every time I want to add a new CSS-file to the existing definitions, I get an error because I have to reinclude the complete bootstrap structure. But if I reinclude it, the whole bootstrap code gets written into the additional files (eq. sitemap.css, team.css, news.css) too. If I include both files in my HTML-tree, the bootstrap definitions (like the whole normalize block) gets defined two or more times.

I have this setup:

- css
|-- source
| |-- base.scss
| |-- team.scss
| |-- vendors
| | |-- bootstrap...
└-- output
  |-- base.css
  └-- team.css

In base.scss I include the bootstrap stuff. I do also need the bootstrap stuff in team.scss, but not all the main stuff like the normalize things.

How do I achieve that? Is that even possible or do I have to switch my css needs by adding a css-class to the body tag (like body.team)? But then I have to carry the whole CSS stuff of every page in one file. Isn't this crab?

Edit to clear things up a bit: This is in base.scss:

@import "settings/vars";
@import "vendors/bootstrap";
...
header {
    @extend .container;
    ...
    .contentbox {
        margin-top: $mainGap;
    }
    ...
}
...

and this is in team.scss:

header .contentbox {
    @extend .sr-only;
}

It's absolutely clear that "@extend .sr-only;" doesn't work in team.scss because of the absence of bootstrap. But if I include bootstrap with

@import "vendors/bootstrap";

in the first line of team.scss, I would automatically add all the standard 16kb bootstrap things to team.css as well. However, these definitions are already in base.css. So I would have a preventable overhead.

I think I know there is no way to say: "Hey bootstrap. I already included you in base.scss. So you don't have to write the whole main definition of yourself into team.scss again. But I need you because I like you as an usable framework. So please provide me the functions and variables anyway.". But perhaps?

Upvotes: 3

Views: 1701

Answers (2)

FelipeAls
FelipeAls

Reputation: 22161

What you're searching for is named a partial in Sass I guess:

If you have a SCSS or Sass file that you want to import but don’t want to compile to a CSS file, you can add an underscore to the beginning of the filename. This will tell Sass not to compile it to a normal CSS file. You can then import these files without using the underscore.

For example, you might have _colors.scss. Then no _colors.css file would be created, and you can do

@import "colors";

and _colors.scss would be imported.

FYI, in LESS it'd be an import option: @import (reference) "colors"

Upvotes: 0

Tomas Ramirez Sarduy
Tomas Ramirez Sarduy

Reputation: 17471

What I do in this case is to compile base.scss with Bootstrap and all the base code and my customized _variables.scss. Then if I want to add team.scss I just import the mixins and the custom variables that I will need to use from Bootstrap. Sounds great!

but...

Since .sr-only and other are just provided as classes instead SASS mixins, you can't @include it, like you could do with the .transition mixin for example.

So, for the moment if you are using SASS, you have 2 options:

  1. Import the Bootstrap module with the class you want to extend/reuse

    //contain the .sr-only definition
    @import "vendors/bootstrap/_scaffolding"; 
    @import "vendors/bootstrap/_variables";
    
    header .contentbox {
        @extend .sr-only;
    }
    
  2. Copy/Paste the class from the Bootstrap source and extend it:

    @import "vendors/bootstrap/_variables";
    
    // Copy/Paste the .sr-only class to reuse, very un-DRY
    .sr-only {
      position: absolute;
      width: 1px;
      height: 1px;
      margin: -1px;
      padding: 0;
      overflow: hidden;
      clip: rect(0 0 0 0);
      border: 0;
    }
    
    header .contentbox {
      @extend .sr-only;
    }
    

Upvotes: 1

Related Questions