How to reference global variables in modular LESS files? - css

How can I reference a variable defined in a central variables.less file in an individual module.less file, when the module does not directly reference variables.less?
Here's the structure of my Styles folder:
Styles
_variables.less
Site.less
Modules
_forms.less
_navbar-top.less
_panels.less
_titlebar.less
Modules.less
Pages
_page1.less
_page2.less
Pages.less
The file Site.less basically looks like this:
#import "_variables.less";
#import "Modules/Modules.less";
#import "Pages/Pages.less";
(it only includes capitalized LESS files)
And Modules.less looks like:
#import "_forms.less";
#import "_navbar-top.less";
#import "_panels.less";
#import "_titlebar.less";
(it only includes underscore-prefixed files in the same folder)
Pages.less is structured the same way.
What I want to do is have the following in the Modules/_panels.less file:
.panel-form {
.panel-variant(1px; #text-color; #component-default-bg; 1px);
border-top: solid darken(#component-default-bg, 1px);
border-bottom: solid darken(#component-default-bg, 1px);
border-left: none;
border-right: none;
}
But of course my LESS compiler (Visual Studio Web Essentials 2013.5) is throwing an error and refusing to compile the file _panels.less because it is referencing a variable that does not exist in its scope.
Currently my workaround is to declare .panel-form in Site.css but that is a hack -- I don't want to start declaring an arbitrary number of modules there.
Is it possible to reference a variable like this and still compile to CSS, and if so how? If not, is there a better structure I should use?
Incidentally I noticed that the LESS compiler doesn't like Bootstrap either, because it raises errors if I type a single space into a Bootstrap LESS file e.g. navbar.less and try to save it, reporting that (for navbar.less) the mixin .clearfix() is undefined. Which of course it is, because navbar.less does not reference mixins.less, yet if it can compile from bootstrap.less downward then everything will work just fine...

I don't know what is your environment but with triple slash directives it usually works:
root
less
_vars.less
modules
someModule.less
Inside "someModule.less" you should try this:
/// <reference path="../_variables.less" />

Related

How do I use sass variables from another sass file

I am developing a WordPress theme and I am trying to use sass from another file using the #use method but it doesn't seem to be working. How can I fix the problem since the #import rule method will be depreciated soon?
I have files
//_brand.scss
$base-color: #c6538c;
$border-dark: rgba($base-color, 0.88);
and then
//footer.scsss
#use 'brand' as b;
.footer{
padding: 0px 5%;
background-color: b.$base-color;
}
and I get this error when it's compiling
Compilation Error
Error: Invalid CSS after "...ground-color: b": expected expression (e.g. 1px, bold), was ".$font-size;"
on line 5 of sass/opt/lampp/.../sass/footer.scss
>> background-color: b.$base-color;
I am using "Live Sass Compiler" visual studio code extension to compile to CSS
If you want to use the variables you have defined within the brand.scss file across different files, you can use the #import directive. For using it, just add the line below to your footer.scss file:
#import "brand";
Source: https://www.w3schools.com/sass/sass_import.asp
I hope my answer will help you

Webpack Encore: unexpected SCSS import order

I use Symfony + Webpack Encore and try to split styles into "layout" and "page-based", but only to make development more comfortable: I still want to compile one css file for them (in fact, there is a limited number of such css files, each one for block of pages, but for easier understanding let's assume only one is necessary). So I do like this:
_global.scss
// ... bootstrap variables redefenition here
#import "~bootstrap/scss/bootstrap";
// ... common functions, mixins, font-face definitions here
.my_style1 {
padding-left: 12px;
padding-right: 12px;
}
.my_style2 {
#include make-container-max-widths();
}
app.css
#import "_global"
// other styles here
During the compilation (require('../css/app.scss'); only in my app.js) styles are ordered: [ global, bootstrap, app ] and I don't understand why. I mean, if you use them as:
<div class="container my-style1"></div>
container's padding will override defined in my-style1.
The most strange thing is that in dev app.css they are ordered as expected (my-style is lower than container), but in prod not (container is lower than my-style). When you work in dev (and Chrome display non-compiled styles, you also see that _grid.scss overrides _global.scss)
Sorry for this quick self-answer, I've really spent a lot of time before asking, but after it found the solution quickly. Hope, can save smb's time.
You should simply add other styles to app.js. This way they will recompile on any file change (in previous example they recompile only on app.scss change) and the order will become correct:
app.js
require('_global.scss');
require('app.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.

Node sass not importing

I am building a sass compiler with nodejs, electron, and node-sass.
There will be a config file that will describe some "sass compilers" for many projects and the user will have the ability to activate and deactivate them through a GUI.
I managed with "electron" to create the interface and with the use of electron`s "ipcmain" to initiate the compilers on demand.
To init a compiler, I spawn a child process which encloses the whole compiler.
The compilation is done with following code:
var result = this.sass.renderSync({
file: 'C:\\Users\\George\\Desktop\\css_compiler_tests\\test3\\scss\\style.scss',
outFile: 'C:\\Users\\George\\Desktop\\css_compiler_tests\\test3\\css\\style.css',
includePaths:[
'C:\\Users\\George\\Desktop\\css_compiler_tests\\test3\\scss\\',
'C:\\Users\\George\\Desktop\\css_compiler_tests\\test3\\scss\\foundation\\components\\'
]
});
I execute the compilation using absolute paths but the files us relative paths.
I run my program/gui and activated the compiler and I got a CSS file.
The problem is that some imports are missing.
My root folder is at 'C:\Users\George\Desktop\css_compiler_tests\test3\'.
I try to compile 'scss\style.scss' which imports 'scss_inculded-files.scss'.
The file 'scss_inculded-files' imports 'scss\foundation.scss' which imports form 'scss\foundation\components'.
Here is an example:
/*scss\style.scss*/
#import "included-files";
/*scss\_inculded-files.scss*/
#import
"includes/fonts",
"includes/custom-colors",
"includes/foundation-custom-settings",
"foundation/settings",
"foundation";
/*scss\foundation.scss*/
#import
"foundation/components/grid",
"foundation/components/accordion";
The content of the two last imports is missing.
Finaly I tried from command line and got the same error:
D:\mytests\nodejs\nodeSass> node_modules/.bin/node-sass C:\Users\George\Desktop\css_compiler_tests\test3\scss\style.scss -o C:\Users\George\Desktop\css_compiler_tests\test3\scss\ --include-path C:\Users\George\Desktop\css_compiler_tests\test3\scss\
Is there a way to include those missing files?
Thank you in advance.
Edit 1
After some experimentation I found out that the Mixins are the problem.
Let say I have a Mixin like that:
#mixin headline($size, $color: $base-color) {
color: $color;
font-size: $size;
}
It is compiled perfectly if I call it like that:
h1 {
#include headline($color: blue, $size: 12px);
}
If I don't call it isn't compiled.
I am using Foundation Zurb framework which I believe auto includes the mixins.

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?
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:
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;
}
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;
}
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"

Resources