Confusion surrounding #import behaviour in LESS, using Codekit - css

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.

Related

How to import part of an scss file

For example I am trying to import .navbar-nav from bootstrap's _navbar.scss and not the whole _navbar.scss file to my compiled css file. Is there a way to do it?
Sorry if this was asked before.
You can try doing an extend:
.your-class{
#extend .navbar-nav;
}
However, this would only work if you had imported the _navbar.scss somewhere else or the bootstrap.scss.
Additional
// main.scss
#import ../wherever bootstrap file is/_navbar.scss;
#import _custom.scss;
// _custom.scss
.your-class{
#extend .navbar-nav;
}
One of the way to import .scss in javascript is
import { navbar-nav } from '_navbar.scss'
When using in your component you can do.
<div className={navbar-nav} />
if you want to import it in your .scss file then you can do.
#import '_navbar.scss'
.class {
#extend .navbar-nav
}
As you are learning Sass here are some explanations which may help:
Better wording helps ...
At first some wording to get a correct understandable communication here and anywhere else you are talking about coding:
SASS don't minify a given CSS, it writes the CSS. Minify means the process that a given CSS code is compressed by a postprocessor to a shorter way to write it, - i.e. comments and spaces will be removed ... But yes: as SASS writes CSS it is able to write code in a minified format.
What you mean is to 'reduce code' or 'avoid not needed code' as you only try to import, use and write! the only needed parts of a given module which is a good practice.
.navbar is a CSS class. SASS don't load CSS classes, it writes CSS classes. It doesn't matter if you 'write the code on your own to a SCSS file' or 'get the code from a framework/module' ... SASS writes the however prepared CSS classes to your CSS file.
What you mean is the SASS includes/imports files with code from a framework/module to write that code/classes to css. So yes: maybe you can say you 'load' that module/scss-file ... but you don't load as css class. (This is as important as 'classes' in coding allways means a special construct of excutable code which does something in your programm. CSS classes don't execute anything, in SASS they are content you want to write/output to css.)
Please: these wordings are important to understand each other and to understand the mechanic of the process how SASS works is going on as well.
Reducing code by importing only selected file is good practice
So, I am not sure if I did understand your question right:
No. You are not able to include/import/load a part of the code of a single scss-file only. If you do #import 'somefile.scss' you always get the whole code of the whole file.
Yes. you are able to include/import/load parts of a given framework/module as you are able to load only the special FILES(!) of a framework/module you need for your project.
Yes. That is a really good practice.
As you mentioned Bootstrap indeed is developed and allows you to do that. But head up. If you import i.e. the part navbar.scss (or other selected elements) it only works if you also load the other files navbar.scss depends on. That are almost variables, functions, mixins and sometimes needed JS components to this element as well. Please note, that importing the files the elements are based on (i.e. vars, functions, mixins) has to be done BEFORE you load the element (i.e. like navbars, grid,...) itself.
A way to organize your project
Yes. A good way to organize your project is to have a single(!!!) file which brings all the code together you write in other partial files yourself or which you import from other framework/modules.
In case of Bootstrap this can be (simplified example):
// ###> file: your 'custom.scss'
// Note: file is without leading underscore
// as this files GENERATES/WRITE the css to custom.css
// Files with underscore as _partial-footer-styling.scss
// are not compiled to write css on their own
// that files are only compiled to css when they are imported to files without underscore
#import 'path/your-own-vars';
// Note: technique importing files
// you don't need to write underscore and '.scss'
// Note: function of this file
// the file '_your-own-vars.scss' is to organize you needed vars special to your project
// it includes your own vars and bootstrap vars as well
// --> the Bootstrap vars in this file will overwrite the vars of Bootstrap which will be included next
#import 'bootstrap-path/functions';
#import 'bootstrap-path/variables';
#import 'bootstrap-path/mixins';
#import 'bootstrap-path/your-selected-component-1';
#import 'bootstrap-path/your-selected-component-2';
#import 'bootstrap-path/your-selected-component-3';
...
#import 'path/partial-your-own-additional-css-special-section';
#import 'path/partial-your-own-additional-css-footer-settings';
....
A detailed explanation how to include and use Bootstrap (partly if you like to do so) to your project is here: https://getbootstrap.com/docs/4.6/getting-started/theming/

How can I make #Import function in my main.scss global?

Hey guys I'm a newbie learning sass and I'm using node.js and cmd to serve as my local compiler. I have a main.scss file where I have done all my #imports. This is an image of main.scss with all imports Anytime I try to save my work, I get an error saying my variables are undefined, meanwhile they are.
This is the error.
And this is where the supposed error is. Meanwhile my variable.scss is intact, take a look here
So I guess the question is, how do I make my #imports global in my project.
Double Check your variable $color-primary-light if it is define in your scss file. Or change the #import "base/typography function and transfer it to the upper most part of your main.scss.
Scss reads imports from top to bottom and there are some css specificity/hierarchy of css when compiling them into one css file.
#import "base/typography
#import "base/base
#import "base/animations
#import "base/utilities

Angular 2 - Duplicated <style> blocks everywhere

I am using the latest Angular(4) with Angular CLI. I followed the advice found on SO for setting up global scss that is available to components.
Angular-CLI global scss vairables
My structure looks like this
/
styles.scss
/styles
variables.scss
mixins.scss
common.scss
/app
/component1
component1.scss
/component2
component2.scss
The main styles.scss file has the following code
#import './styles/variables.scss';
#import './styles/mixins.scss';
#import './styles/common.scss';
And in my components, I start each component scss file with the statement of
#import '~styles.scss';
I thought that this was the correct way to bring global variables/mixins/common into my component's scss. However, when I started to have components within components, I began to notice that Webpack was actually creating one block per component in the page, and each one of them had all of the global scss written out in them. So there would be one block for component1, with ALL of the variables,mixins,common stuff at the top, and then another block right below that one for the other component2 in the page, with all that information again.
Besides this being extremely inefficient, it means that the global styles are overwritting themselves (can see that in chrome debug) once for each time they are loaded.
Some direction would be very much appreciated.
The <style> tags are normal angular behaviour. Each components SCSS gets written into a <style> element, so there is nothing wrong with that.
The style.scss is for global styles that do not need encapsulation. It also gets written into a <style> element, if you imported it in your angular.json:
"styles": [
    "styles.css"
],
What you are getting wrong is the question you linked (which is still not accepted).
You shouldn't import your already imported styles.scss (apart from variables or mixins) into your components, because this will lead to increasing bundle sizes, as you import the code over and over (which is also the reason for the GitHub issue you mentioned).
You can use the mixins, variables and common.scss simply by including them directly in your components SCSS, just as you need them.
This is basic sass behaviour, you should never import things that result in css several times (sass files imported into component should typically only contain variables, mixins and functions). If you need your import to happen only once, add it to the default styles file.
Look here

How to avoid multiple #imports of SASS variables?

The site I'm working on uses the rails asset pipeline and an application.scss file to import and process different CSS files.
However, some stylesheets are used in specific places, and for those, it makes little sense to import them into the global manifest. But not so importing them requires importing variables.scss, and possibly mixins.scss into the sheet itself (so they'll process correctly), resulting in duplicate code in the final CSS.
Is there a way to basically tell the preprocessor - "trust me, the variable/mixin you're seeing will be defined by the time everything gets processed"?
Otherwise, I don't see how to avoid importing every sheet into a single manifest, which seems bloated.
Thanks.
The short answer to your question is no. The variables need to be defined in a logical order from when they are called in compilation. It's like a "chicken and the egg" scenario.
From what I can ascertain in your description, the project you're working on is not compiling into a unified workflow, but chunking out into modular portions relational to your file structure. IF this is the case, what you can do at the beginning of each file is reference the variables file from the root.
In a normal workflow, you would import your scss files based on your defined hierarchy like so:
sass/style.scss
/* Main Stylesheet */
#import "variables";
#import "mixins";
/* Modular Sections */
#import "layout/header";
#import "layout/body";
#import "layout/footer";
would compile out to one stylesheet style.css with a command sass sass/style.scss:style.css
What I'm assuming your project does is have all the /* Modular Sections */ files compile out into their own CSS files.
layout/header.scss
/* Header Stylesheet */
#import "../variables";
#import "../mixins";
Given a files structure that resembles:
/root
style.scss
variables.scss
mixins.scss
/layouts
header.scss
body.scss
footer.scss
This all seems kinda silly though. I don't know all the parameters that go into your current sass compilation, but I'd recommend using a unified workflow.
You can use Partials so the compiler will not try to interpret variables etc.
Basically, rename the files that you do not want the compiler to interpret -- but will be available when compiled -- with an underscore before the filename.
eg.
_filename.scss
If I understood well you want to avoid copies of the same css in css files caused by using #import in scss. I solved this problems by doing a hierarchical three.
For exemple consider the home.scss file, where you import header.scss and footer.scss.
Both header.scss and footer.scss use specific colors that you import from a file named colors.scss:
// colors.scss
$MidnightBlue: #00478f;
$RedOrange: #ff5d00;
$MistyBlue: #d8e1e7;
$Ebony: #2a231f;
Now you could import colors in header.scss, footer.scss and maybe even in home.scss. The result is that in home.css the code of colors.scss is repeated 3 times.
A solution is importing colors.scss only in header.scss. Then in home.scss the first #import that you specify is #import "header.scss"; and then #import "footer.scss";, thus you can use the colors variables in footer.scss and in home.scss even if you don't import them directly in footer.scss and home.scss. That's because the variables of colors are imported before the footer and compiled before the rest of the code in home.scss.
Now if you check home.css you shouldn't see repeated code
When at first you write the color variables in footer you will receive an error because they are not defined, but it disappear when you import footer in home.scss
If you #import the same SASS file (e.g. variables.sass) in multiple files and then #import those files in the one main.sass file, the resulting main.css file will contain the content of variables multiple times.
A good way of structuring SASS files is to obey the rule of importing each file only once. Iconic architecture is the 7-1 Pattern. You basically decompose your SASS files into atomic parts and then import those in appropriate order only once in the main file.

Override LESS variables

I have the following stack:
Symfony2
Twig with lessphp filter installed.
Twitter Boostrap
In base.css i have:
// base.less
#import '/path/to/bootstrap.less'
#linkColor: 13px;
Variable name is not important at all. It can be any other variable used in bootstrap. It just doesn't get overridden. But if i put the variable into separate .less file and import it in base.less everything works as expected:
// base.less
#import '/path/to/bootstrap.less'
#import '/path/to/variables.less'
and
// variables.less
#linkColor: 13px;
Why does this work and the other not? Looked up for the docs (less/lessphp) but couldn't find anything related to this. (or i didn't know where to look).
Can someone explain why is this happening?
It looks like it's a bug in the lessphp compiler. Take a look at the github issue. Your workaround, to put the variable declaration into another file and also import it works just fine. Thanks by the way ;)
This is happening because you override the variable after it's been used to define all the Bootstrap styles.
I solve this problem this way:
Create my own main.less that imports my own bootstrap.less.
My own bootstrap.less is just the Bootstrap's bootstrap.less file copied over to my own folder with import paths changed accordingly, but with one exception: it imports by own variables.less instead of the Bootstrap's one.
My own variables.less imports the Bootstrap's variables.less and then overrides the ones I need.

Resources