"lessify" a CSS color theme - css

I've inherited a project with a ton of CSS and been assigned the task of modifying it so the color palette can easily be changed.
I've immediately thought of using a CSS preprocessor, tried less and easily switched the colors for variables, so I just have to define a base color and can switch the color theme.
The problem is, every time I switch the color theme I have to either overwrite colors.less with the new color settings or modify the colors.less import in a ton of files.
What I want is to end up with a single file with a lot of imports (basically one per component or set of components), and on that file when I import colors-red.less instead of colors-blue.less all the components imported right after use the red palette so the theme compiled is red instead of blue, for example.
The problem I am having is that the component files do not get the "globals" with the color definitions so I can't compile the base file that imports those files.
I've read there is the possibility of using "partials" (files starting with _ that won't get compiled independently but imported and then compiled), but my compiler seems to be ignoring this feature, and the eclipse plugin I use for editing and verifying less files also complains about the color variables not being defined on those partials.
How can I can get the partials to work? Is there a better approach to do this task?

Stil, they won't be defined on the imported files, just on the main file, so >compilation will break on the imported files. You see what I mean?
Nope? example:
mixins.less:
.mixin()
{
color: #color;
}
variables.less:
#color: orange;
project.less:
#import "mixins";
#import "variables";
p {
.mixin();
}
Now running lessc project.less outputs:
p {
color:orange;
}
Now i change to content of project.less as follows:
#import "mixins";
#import "variables";
p {
.mixin();
}
#color: red;
Then running lessc project.less outputs:
p {
color:red;
}

Related

Sass outputs default file even with changed variables

I'm trying to change some variables for my custom version of Bootstrap. Right now I have the Bootstrap SCSS files and my own variables file. My file looks like this:
#import "/path/to/bootstrap";
$blue: #42a5f5;
$indigo: #5c6bc0;
more styles here…
However, when I run sass /path/to/custom.scss /path/to/output.css, it still outputs the default Bootstrap files like this:
:root {
--blue: #007bff;
--indigo: #6610f2;
more styles here…
Why does this happen?
According to Bootstrap 4:
Variable overrides within the same Sass file can come before or after the default variables. However, when overriding across Sass files, your overrides must come before you import Bootstrap’s Sass files.
Since you create your own custom.scss file, it should look like this:
// Your variable overrides
$blue: #42a5f5;
$indigo: #5c6bc0;
// Bootstrap and its default variables
#import "/path/to/bootstrap";

Setting up SCSS color variables won't work

I'd like to define my own color variables in my SCSS, but how?
I checked this website and did everything that is described there.. but it doesn't work.
I have installed a preprocessor already!
Furthermore I tried to create a color-map and access the color with map-get.. doesn't work either.
colors.scss file
$yellow_100: #FFC819;
style.scss file with a colors.scss import
h1 {
color: $yellow_100;
}
I also tried this:
colors.scss file
$colors: (
color: #FFBB00
);
style.scss file
h1 {
color: map-get($colors, color);
}
Neither of them works.
SASS compiler preserves $ in output CSS and doesn't recognize $yellow_100 as a SASS variable. Use Interpolation to access variable's value instead of its name—just put it between #{ and }.
So your code should look like:
$yellow_100: #FFC819;
h1 {
color: #{$yellow_100};
}
Interpolation isn't used in old code examples. That's because SASS developers changed the syntax approximately in July, 2017, making interpolation mandatory for SASS variables. Here is more details on this.
Install sass with npm -g install sass
Create these two source files:
// _colors.scss
$yellow_100: #FFC819;
// style.scss
#import './colors';
h1 {
color: $yellow_100;
}
Execute sass ./style.scss ./output.css to compile your code
Add <link rel="stylesheet" type="text/css" href"[path to output.css]" /> to your HTML
Make sure you're using single colons to prefix your root header tag in your .scss files.
i.e :root{} and not ::root{}

Global scss variables for Angular components without importing them everytime

I do already have SCSS variables defined in src/styles/settings/_variables.scss and I am importing them into src/styles.scss, but still these variables aren't available for every single component.
Is there any way to make a global file which holds all SCSS variables for the rest of my components? Because writing #import in every single component .scss file it is very frustrating, especially if I have many nested components.
I know, there is a lot of similar questions, but it seems like they're all outdated and do not relate to the recent versions of Angular.
I use Angular 7.3 with CLI.
You just need to add a little more config, so where you are declaring your global variables, you need to wrap it up in :root{}. So in src/styles/settings/_variables.scss.
:root
{
--blue: #00b; // or any global you wish to share with components
}
Then when you use them in the SCSS you will need to access them like so.
.example-class {
background-color: var(--blue)
}
To add to this regarding comments, this method can use mixins, #media and keyframes and is not limited to just colours / font. That was an example.
From my understanding you need a global file src/assets/style/global and then to import each scss file into there where you are defining them like so.
#import 'filename';
If you dont want global variables to be used in within a component look when you have the globals working. Look into ViewEncapsulation, as this can be used to ignore them.
Is there any ways to make global file with scss variables available for all components?
Without importing global file everytime in each component, you want those sass variables been available, it's not possible.
The way it works in SASS, if using partials to better organize code, you can apply #import directive for referencing. So if there're some sass variables in shared/_variables.scss:
$lightslategray: #778899;
$darkgray: #A9A9A9;
and these variables need to be used in another stylesheet, stylesheet with them must be #import-ed into it firstly:
// Shared
#import "shared/variables";
.content {
background: $lightslategray;
}
In Angular it works in a similar way (related referencing external stylesheet). So if you need some sass variables, mixins or functions to be used by a particular component.scss, there is no other clean way, but to reference them in that component.scss using #import directive. To ease the task, you can create a file src/_variables.scss and use syntax like this in your component.scss:
#import “~variables.scss”;
step one : go to custom scss file (shared/css/_variable.scss) and write this part
:root{
--color-text: red;
--color-btn-success: green;
}
after go to style.scss (this is main file) and import this file :
#import './shared/css/Variables';
now you can use variables in all components with this Syntax:
.sample{
color : var(--color-text);
}
Easily possibe to access sass style(s) from a global file with two steps.
Add folder path of the style files to includePaths array in angular.json file.
Import style file by file-name in any component.
let say your files and folder structures is as follows: src > my-styles-folder > var.scss
angular.json
"architect": {
"build": {
...
"options": {
"stylePreprocessorOptions": {
"includePaths": [
"src/my-styles-folder" // add path only, do not include file name
]
},
"styles": [
...
]
}
...
}
}
some-component.scss
#import "var"; // var.scss
mat-toolbar {
height: $toolbar-height;
}
In angular 8 work for me.
In your _variable.scss file you have to add:
:root{--my-var:#fabada}
After that go in your angular.json and add this in "styles":
{"input":"yourPath/_variables.scss"}

Can't get dotLESS #import working

I'm struggling with the dotLESS #import to have a separate variables file; I just constantly get "variable is undefined".
If I browse to the variable config file it works; if I put the variables inline in the main stylesheet it works; but in an #import, no dice. I'm mapping .css as well as .less to the extension, however it also doesn't work if I use .less only.
The variables file LESS-config.less is:
/*
.LESS VARIABLES
*/
#mbw_dark_cyan: #1293b5;
#mbw_cyan: #11add4;
#mbw_magenta: #e935da;
#control_text: #ffffff;
#action_delete: #ff5400;
#section_level1_bg: #mbw_dark_cyan;
#section_level1_fg: #control_text;
#button_bg: #mbw_dark_cyan;
#button_fg: #control_text;
#button_icon: #control_text;
#data_table_header: #mbw_cyan;
.dummy {
color: #control_text;
}
Which renders as:
/*
.LESS VARIABLES
*/
.dummy {
color: #ffffff;
}
Calling stylesheet main.css is:
#import (less) '/css/LESS-config';
button {
background: #button_bg;
}
Which gives the error:
variable #button_bg is undefined on line 4 in file '/css/main.css':
[3]: button {
[4]: background: #button_bg;
----------------^
[5]: }
As I said, if I replace the import with the same variables copied and pasted, it all works fine.
I've tried saving without BOM as in another answer, but that doesn't help.
EDIT, I've tried:
Removing the (less)
Changing to double quotes
Using relative path LESS-config as opposed to virtual absolute as above
Adding logger="dotless.Core.Loggers.AspResponseLogger" log="debug" to
web.config (cache is already false)
Adding debug="1"
Adding
debug="true"
Absolutely no change in behaviour.
EDIT 2:
I created a cut-down css that only had the import statement in it; when I browse to it the imported styles are in there. However, on a refresh, I just get a blank response.
So it seems to be something to do with my IIS config / caching? I've turned off content compression but no joy; disabled all output caching for .less and .css, still no joy!
FIXED as per Toni's comment; https://stackoverflow.com/a/51754771/318411:
This turned out to be a dotLESS issue, tracked on GitHub here: https://github.com/dotless/dotless/issues/553
The complete fix was to:
Upgrade dotLESS to version 1.6.7
Downgrade Microsoft.Extensions.DependencyInjection to 1.1.1.0 due to Method
not found error
Change the file extension of the import from .css to .less
Now all working.
Please try version 1.6.7 which fixes an error that imports are only executed on the very first request.
I potentially see two problems that you have.
You are trying to call #import (less) in a css file. This is a syntax specific to less framework.
Your main.css is not a less file.
Change your main.css to a main.less file and now try generating your css from main.less as your root file.
Assuming your import url for LESS-config.less is correct.
The above mentioned corrections should probably do the trick.
#import (less, optional) "mystyle.css"; is Less syntax, you cannot use it in CSS (Less #import Rules).
If you want to use #import in your CSS, it should follow this syntax (See here)
#import url|string list-of-mediaqueries;
But, you cannot import a Less file inside your CSS anyways.
The way I would have done this:
Say you have 3 .less files: config.less, color.less, header.less
I would create a style.less file with the following content:
/*------------------------------------------------------------------------------*/
style.less
/*------------------------------------------------------------------------------*/
/* 01. config */
#import "config.less";
/* 02. color */
#import "color.less";
/* 03. header */
#import "header.less";
Then I would complie style.less which would produce, style.css and I would include style.css in my website.

How do I compile my .scss file into multiple .css files depending on the variables

I have a simple gulp build to compile my .scss files:
gulpfile.js:
gulp.task('sass', function() {
return gulp.src('app/assets/scss/**/*.scss')
.pipe(gulp.dest('app/assets/css'))
});
...
index.scss:
$brand-primary: #b0b0b0;
// $brand-primary: #b1b1b1;
// $brand-primary: #b2b2b2;
...
In index.scss I have multiple versions of the $brand-primary variable I want the file to compile with, e.g. I want gulpfile.js to automatically create multiple versions of index.scss depending on the $brand-primary variable: index-1.css, index-2.css, index-3.css, etc. with the $brand-primary value equal to #b0b0b0 first, then #b1b1b1, then #b2b2b2 accordingly.
The idea is to create multiple color options for my template without manually recompiling it for each color.
PS: I am aware of CSS variables, however those won't work with color function like darken($brand-primary, 10%);
It would be very hard to do what you ask purely programatically. I'm not even sure it's possible.
Why don't you just create 3 index.scss files each with different $brand-color and and then import everything else in them. Or even better make another file which will import all of your other *.scss files and then just import that file and color in each index file. So your index files would look like this:
$brand-primary: #b0b0b0;
#import 'style';
and _style.scss would have all of your other scss dependencies.

Resources