SASS output multiple different files by variables - css

I am working on a project that involves different themes for each subpage. Each subpage has the exact same HTML markup as a frame, but on every subpage, the same elements - such as headings - must have different colors.
The way I am tackling this problem is to have every single declaration that differs on subpages in their corresponding CSS files, such as red.css or blue.css. These files contain only the color declarations of the selectors that must be different, so font-sizes and everything else is in the global CSS file.
What I am hoping to accomplish is to have the color variables declared in a file and create a SCSS frame for the theme CSS files that include the corresponding variables for the CSS declarations. In a more clear way:
Example of the variable declarations:
$red: red;
$blue: blue;
And the theme frame SCSS file should look something like this:
h1 {
color: $heading-color;
}
And the goal is to make SASS loop through the variables and create an X number of different CSS files that have the same frame, but each of them should have their corresponding values at the right places, so blue.css should have the blue values, red should have the red values, etc.
Is this possible to do? What I'm trying to avoid is to make X SCSS files with the exact frame in it, but with different values for their values, as this means X number of editing every time something changes.

With SASS you can import files which contain common CSS rules. Just create 2 files, each with different variables definition and include everything other from another scss file. Like this:
theme1.scss:
$primaryColor: red;
$secondaryColor: blue;
#import 'all';
theme2.scss:
$primaryColor: orange;
$secondaryColor: violet;
#import 'all';
_all.scss
/*All your CSS rules including for example:*/
h1 {
color: $primaryColor;
}
SASS will compile into 2 files theme1.css and theme2.css but there is no need to write duplicate CSS.

Related

Can I use variables across SCSS files?

I'm using different 'SCSS variables files' (bootstrap variables, company variables, project variables) so it's easy to re-use them in other projects. But it seems I can't use variables across files.
Example:
In company-variables.scss I declared $white: #fff;
In project-variables.scss I want to reuse the above variable like this $body-color: darken($white, 20%);
I get the following error: Undefined variables: "$white". $body-color: darken($white, 20%);
I load my files like this:
#import "bootstrap-variables";
#import "company-variables";
#import "project-variables";
Paths are correct.
I'm pretty new to SCSS. Any idea what I'm doing wrong or is this not possible/not the way to go?
If you want to use it , you should import #import "company-variables"; into #import "project-variables";
Or just use default white color from bootstrap like that:
darken(theme-color("white"), 20%);

Remove border-radius from Bootstrap 4 breadcrumb - Sass

In Bootstrap 4 there is a Sass varaible called $enable-rounded which
"Enables predefined border-radius styles on various components."
(https://getbootstrap.com/docs/4.1/getting-started/theming/#sass-options)
I have a requirement to remove the rounded corners on the Breadcrumb component, but I don't want to remove it from any other components. Therefore I can't use $enable-rounded to do what I need.
However, I don't know what the optimal way to do this is.
The Sass for _breadcrumb.scss contains this:
.breadcrumb {
display: flex;
flex-wrap: wrap;
padding: $breadcrumb-padding-y $breadcrumb-padding-x;
margin-bottom: $breadcrumb-margin-bottom;
list-style: none;
background-color: $breadcrumb-bg;
#include border-radius($border-radius);
}
How do I override #include border-radius($border-radius); without modifying _breadcrumb.scss?
All of the CSS for my app is condensed into 1 file (app.css) which is built from a Sass file (app.scss) which first includes the relevant Bootstrap 4 Sass files. So I could do something like this:
// app.scss
#import breadcrumb;
#import // other_bootstrap_sass_files
// CSS specific to my app
.breadcrumb {
border-radius: 0;
}
This seems a bit too similar to Bootstrap 3 where you had to override what you didn't want.
Is there a smarter way to do this with Sass for Bootstrap 4?
I think that for your specific case where you want only breadcrumbs without border-radius and all other components still have it, your only solution is doing like you mentioned in your question:
.breadcrumb {
border-radius: 0;
}
This seems a bit too similar to Bootstrap 3 where you had to override what you didn't want.
Personally I dont't see any other solution, only because you don't want to edit the original _breadcrumb.scss
If you look at the _variables.scss file, you can see all the variables that are set with !default - think of this as a preferences file. When the SCSS is compiled, your new values are swapped for the default values without having to overwrite the CSS.
Seems like $breadcrumb-border-radius: $border-radius !default; is what you want.
Two ways of resetting that value:
1) Make a copy of the _variables.scss file and place it in your project directory (I like changing the name to, say, _myvariables.scss ), look for that variable, remove the !default and change it to $breadcrumb-border-radius: 0;
OR
2) Make a file, say _myvariables.scss, that contains $breadcrumb-border-radius: 0; (and any other default values you want to change later on).
Next, import that new file BEFORE your bootstrap scss. In your example that would be your app.scss file:
// app.scss
#import myvariables.scss; //no underscore because it's a partial
#import // other_bootstrap_sass_files including the breadcrumb component
Now, when the SCSS is compiled, the breadcrumb radius will be set to 0 without changing anything else or overwriting css.

How to modify a parameter's value in sass files from typescript?

I am trying to change a variable's value in "../myStyle.scss" file from myComponent.ts . I read that it is impossible to achieve it because sass file are compiled into css by the sass pre-processor and the variable disapears. Isn't there a way to work this around.
My variable is called $theme.
And I want to change it's value.
$theme: #5A352A;
and I want it to become $theme: #ffffff; when the user clicks
You have to work in a different way.
Basically when you compile the angular app , it will generate a css file where it substitute the variable with the value , wherever you used it.
So if you want to achieve a color change you have to create a other variable and other classes and swipe it in your class attributes (this is one way, check also ngStyle and ngClass in angular reference).
For example white-theme/dark-theme (the most common case).
variables -> $black: #00000; $white: #ffffff
Example classes:
.body-dark {
background-color: $black;
}
.body-white {
background-color: $white;
}
and swipe the classes in the html elements.
setDark(){
document.getElementById("bodyId").setAttribute("class","body-dark ")
}
the same for white.

Grunt - remove styles from x.css which already exist in y.css

I'm wondering if there's a grunt plugin that can compare two files and remove duplicates from one of them.
Example: if both blog.css and main.css contain the rule .button { color: red; } I'd like to remove that rule from blog.css. (main.css should always remain unchaged)
Background:
I've got two LESS-bundles, main.less and blog.less, which I compile into main.css and blog.css
The idea is that my site should load main.css on every page. On blog pages I'll load both both main.css and blog.css.
The problem is that these LESS-files share a few "utility"-files (with variables, mixins and some common classes like .button)
So I end up with blog.css containing duplicates of some rules which are already defined in main.css, and I'd like to get rid of those duplicates to reduce file size.
Found it
https://www.npmjs.com/package/grunt-csscss
csscss: {
dist: {
src: ['css/x.css', 'css/y.css']
}
}
Allthough in my case the solution was actually much simpler. Turns out LESS now has import ("reference") which will import a file to use as a dependency only, without outputting any of it's css.
So now I can use import ("reference") commonstuff.less in blog.less and thus none of the styles from commonstuff.less will be output to blog.css! :)

CSS breaks when packed

Let's say I have about 10 css files on my site. I wanted to combine them into one. But when I combining them(just "concatenating" files, in order they are included into html), my style/layout breaks. It's not the problem of paths or something, just selectors doesn't work as before.
Am I missing something, or maybe my file is too big? What could be the problem? I thought there is no difference if styles are in one file or many(they shouldn't be) as long as order is preserved...
Cheers
Make sure you don't have #import directives in your files. According to CSS spec, it may be place only before other rules. All other imports are ignored.
For example:
1.css:
BODY {background: #fff; }
2.css:
#import "foobar.css";
1+2.css:
BODY {background: #fff; }
#import "foobar.css"; /* This import won't work. */

Resources