Defining variables across files in Less CSS - css

I'm trying to create a CSS theme with multiple color schemes using Bootstrap CSS. Each color scheme is built as a modified version of the boostrap.less file: bootstrap-red.less, bootstrap-green.less, and so on.
What each Bootstrap version does is import all the default Bootstrap files, then the appropriate color palette, then the theme's core structure. For example, bootstrap-red.less:
#import "reset.less";
#import "variables.less";
#import "mixins.less";
/* and so on... until */
// Custom code
#import "elements.less";
#import "_mytheme-color-scheme-red.less";
#import "_mytheme-core.less";
In _mytheme-color-scheme-red.less, I define variables such as:
#bannerBackground: #59a449;
However, when compiling bootstrap-red.less I get:
NameError: variable #bannerBackground is undefined in /.../css/less/_mytheme-core.less
Why does this happen? I would have thought it would work, since variables in the variables.less files are defined in the same way, and they can be used in subsequent files.
I've looked at similar questions and tried different things, but to no avail:
#importing "_mytheme-color-scheme-red.less" in the file _mytheme-core.less - unfeasible; also, Bootstrap doesn't do that and yet it still works.
encoding the files in UTF-8 without BOM - didn't work, same result.
It seems to me the file _mytheme-color-scheme-red.less is not being processed at all. It's as if the Less compiler was just skipping it and going straight for _mytheme-core.less How can I fix this?

Fixed. The problem was the encoding after all: the LESS compiler was skipping all wrongly encoded files. Apparently Sublime Text doesn't properly save to UTF-8 without BOM even if you tell it to; my files were all in either ANSI or UTF-8 with BOM. I had to resort to Notepad++ in order to convert them to plain UTF-8. I feel stupid now.
Source: Variable Name Error "is undefined" even though "variables.less" imported

I had a similar error with LessCss 2.x when compiling Bootstrap 2, downgrading to LessCss 1.7.5 resolved it for me.

Related

Unable to add Sass in Angular 4

I have created a blank project in angular 4 and I am trying to design it but the sass isn't working when ever I add sass and run project I am getting this error
body{
h1{
color : red;
}
}
^
Invalid CSS after "body{": expected "}", was "{"
in C:projectname/src\styles.sass (line 1, column 6)
My index.html code is
<body>
<h1>Here</h1>
</body>
Any help would be appreciated
Based on your error message (C:projectname/src\styles.sass) It seems you're using the .sass extension for a SCSS file. Change your file name to styles.scss.
Sass and SCSS use two different and incompatible syntaxes.
There are two syntaxes available for Sass. The first, known as SCSS
(Sassy CSS) and used throughout this reference, is an extension of the
syntax of CSS. This means that every valid CSS stylesheet is a valid
SCSS file with the same meaning. This syntax is enhanced with the Sass
features described below. Files using this syntax have the .scss
extension.
The second and older syntax, known as the indented syntax (or
sometimes just “Sass”), provides a more concise way of writing CSS. It
uses indentation rather than brackets to indicate nesting of
selectors, and newlines rather than semicolons to separate properties.
Files using this syntax have the .sass extension.

Variables are global with SASS but not SCSS

I have my application.css.scss set like this:
#import "base/variables";
#import "./application/application";
Like the documentation says I am not using Sprockets' directives (require, require_tree, and require_self) at all so I expect my variables defined inside of base/_variables.scss to be globals and available for my /application/application.scss file but it's not the case:
#content {
margin-top: $big;
}
Will return the error Undefined variable: "$big".
I've tried the same thing with SASS by naming by files application.css.sass and /application/application.sass and while the variables now do seems to be globals I'll like to keep using the SCSS syntax, I've tried that by setting config.sass.preferred_syntax = :scss but I'm still being asked for Sass.
Of course I could just import my variables file everytime I need my variables but that would go against the DRY principle.
Is that possible to use the SCSS syntax while making my variables globally available? What am I missing here? Thanks in advance.
What versions of sprockets, rails and sass-rails gems do you have? There were some problems around undefined variables, maybe try to bump up sass-rails and sprockets (if possible).
My application/application.scss was being precompiled (in assets.rb) by an old rule using a wildcard, which I missed, it's now working correctly.

#import more performant alternative for sass

I've discovered that #import has performance implications. However all of my sass files #import a global-constants.scss at the top of the file to reuse several variables for colour and other properties, so that I can change the main colour etc from one place.
Is there a more performant way to reuse variables in sass?
EDIT: upon pondering this further, I notice that my css file that is generated from my sass file after compilation, has no import statement, and all of the variables are rendered as proper css values. So I'm probably not going to get any performance issues anyway, is my guess.
When you are using #import inside the SCSS, it will try to include the whole file and send it to the browser, (it is better, if you have configured it to return only one single CSS file or minified). That way, it is clean and better:
No #import in the output.
Source code is split using #import, keeping the modularity.
Summary: No performance issues because of #import.

How can one import only variables and mixins from Sass stylesheets?

I'm using the Zurb Foundation 4 (S)CSS framework, and I'm running into an issue of massively duplicated styles. This is because in every file that I #import 'foundation' in, all styles from Foundation are also imported (rules for body, .row, .button and friends). This leads to long SCSS compile times and a hard to navigate web developer console in Chrome, as all of Zurb's styles are declared four or five times.
To mitigate this, I've created a globals scss file, which contains the overrideable variables that Foundation uses (it's copy-pasted from foundation_and_overrides.scss, then foundation_and_overrides import globals). Importing just the globals.scss file gets rid of duplication only in files that don't make use of Foundation mixins.
It's in the files which make use of Foundation mixins: Can I import only the mixins from an SCSS file, without importing the concrete Foundation styles?
Imports are an all or nothing thing. Everything that's in the file is what you get. If you look through the source of Foundation, though, there are variables you can modify that will suppress emitting styles (eg. in buttons, setting $include-html-button-classes to false will disable the styles). This design pattern is Foundation specific, you cannot expect other libraries to be authored this way.
When you import foundation via #import "foundation", you're importing this file: https://github.com/zurb/foundation/blob/master/scss/foundation.scss. As you can see, it imports other files. You don't have to import this file if you don't need everything: just import the specific file you want (eg. #import 'foundation/components/side-nav' for only the side-nav file).
I had similar issue, where I wanted to simply use a variable from another file, without import of all CSS.
The #use keyword of newer Sass-versions can be used to ensure CSS is not emitted more than once.
The down-sides are:
Only "Dart Sass" supports compiling it (at least, at time of writting).
#use rules must be written before any other rules.
Last but not least, we can not simply replace #import with #use, and need to prefix scope, like:
#use '../my-module';
body {
background-color: my-module.$my-variable;
}
Warning: #extends keyword(s) can not have my-module. prefix, because extensions are not scoped at all (at least, at time of writting).

Confusion surrounding #import behaviour in LESS, using Codekit

Currently using Bootstrap, compiling with Codekit, and also have a separate style.less that I'm working on.
In variables.less:
#blue: #0096EF;
In style.less, I have the following:
.title-text {color: #blue;}
#import: "variables.less";
In bootstrap.less:
#import: "style.less";
#import: "variables.less";
Am I doing this right? To my mind, when bootstrap is compiled it results in variables.less occurring twice.
you should be able to go with import of variables.less once in bootstrap as first import instance, and do not include it second time in actual style.less. Because you are right on your assumption, it will import variable.less again. meaning you are importing same variables in two locations.
P.S. as long as variables.less that defines variables that you will be using is imported before you access variables themselves you will be fine.
#color-black: #000;
.color {
color: #color-black;
}
I discovered this is also a Codekit issue too, as I am using Codekit to compile the less files.
Solution:
Create style.less and edit it as intended, reference #blue variable
(not declared in current document)
On save, Codekit returns a compile error, due to un-declared variable in style.less. Ignore the error.
In bootstrap.less #import style.less
Save bootstrap.less, it compiles without issue
Call bootstrap.css in the html doc
Incidentally, I encountered a Codekit bug between step 2 and 3. After step 2, Codekit no longer watches or compiles anything. To solve, I needed to remove the watched project and then re-add it to Codekit.

Resources