Dart sass ignores imports in Foundation sass files - css

I'm adding sass and Foundation Sites sass to a project. I created a few sample scss files to test #use statements and make sure autoprefixing is working as expected. However, I cannot figure out why the sass command is ignoring the #import statements in the foundation.scss file. I specified the load-path and it's clearly finding the file, it just doesn't respect the #imports within.
I tried specifying an additional --load-path=./node_modules/foundation-sites/** just in case sass didn't know where to look for the foundation imports, but no luck.
Note: I'm specifically not using node-sass here as it doesn't (yet) recognize the #use statements, but from what I can tell this setup should work?
Thanks for any insight!
Update: On a hunch I tried swapping out the #use for #import statements in app.scss - same results.
Update 2: added a small repo to test the problem: https://github.com/webshooter/my-sass-issue
My sass command (run via npm):
sass --load-path=./node_modules/foundation-sites/scss --style=expanded ./src/scss:./public/css
(sass version 1.23.7 compiled with dart2js 2.6.1)
app.scss:
#use "other";
#use "sample";
#use "foundation";
.app {
color: #141414;
}
.prefix-example {
display: grid;
transition: all .5s;
user-select: none;
background: linear-gradient(to bottom, white, black);
}
_other.scss:
.other {
color: #ff9900;
};
_sample.scss:
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
.sample {
font: 100% $font-stack;
color: $primary-color;
}
app.css: (output)
.other {
color: #ff9900;
}
.sample {
font: 100% Helvetica, sans-serif;
color: #333;
}
/**
* Foundation for Sites by ZURB
* Version 6.6.1
* foundation.zurb.com
* Licensed under MIT Open Source
*/
.app {
color: #141414;
}
.prefix-example {
display: grid;
transition: all 0.5s;
user-select: none;
background: linear-gradient(to bottom, white, black);
}
/*# sourceMappingURL=app.css.map */

Actually i think the correct --load-path to use is : ./node_modules/foundation-sites/assets
Try to:
[ Optional ] Replace #use with #import statements in your app.scss :
#import "other";
#import "sample";
#import "foundation";
Use this to compile you sass files sass --load-path=./node_modules/foundation-sites/assets --style=expanded ./src/scss:./public/css
this should fix the import issue

Related

SassError: Invalid CSS expected expression (e.g. 1px, bold)

I am learning sass in react but I am getting this error and I can't find the answer. I have installed node-sass and everything was compiling good but when I tried to import variables I can't use them
./src/App/sass/styles.scss (./node_modules/css-loader/dist/cjs.js??ref--5-oneOf-6-1!./node_modules/postcss-loader/src??postcss!./node_modules/resolve-url-loader??ref--5-oneOf-6-3!./node_modules/sass-loader/dist/cjs.js??ref--5-oneOf-6-4!./src/App/sass/styles.scss)
SassError: Invalid CSS after "...: mis-variables": expected expression (e.g. 1px, bold), was ".$default-font;"
on line 31 of src/App/sass/styles.scss
>> font-family: mis-variables.$default-font;
------------------------------^
styles.scss:
/* Variables */
#use "mis-variables";
/* SASS Code */
%no-padding {
padding: 0;
margin: 0;
}
html {
#extend %no-padding;
font-family: mis-variables.$default-font;
}
body {
#extend %no-padding;
}
_mis-variables.scss:
$default-font: 'Dosis',
Arial,
Helvetica,
sans-serif;
Node-sass causes this problem to me too. I fixed it using sass instead of node-sass.
Just run npm install sass and should work.

How do I wrap a file in a mixin to #use in a scss file?

Not sure what the best way to import is but '#import' is deprecated and #use should be used instead. I have a grid file that I want to include in style.scss .
_grid.scss
.main-content {
display:grid;
/* Set up grid stuff */
}
header{
grid-area: header;
}
I need to import into here.
style.scss
body{
/* More code here */
}
The final complied code should look like this:
.main-content {
display:grid;
/* Set up grid stuff */
}
header{
grid-area: header;
}
body{
/* More code here */
}
I know this is wrong, but this is what I have tried:
#use 'grid' as *;
$main-content
What about using a mixin?
_grid.scss
#mixin grid {
/* Wrap all the code here from _grid.scss */
.main-content {
display:grid;
/* Set up grid stuff */
}
header{
grid-area: header;
}
}
style.css
#use 'grid' as *;
#include $grid
body{
}
#use is really tricky at the moment ... a real big impact to the language.
(A) First of all you should check if you indeed use the most actual SASS version: DART SASS. HEAD UP: MOST actual compilers even in good maintained frameworks DO NOT YET!!! Here are information about how to find/install compiler with most actual version:
Solution with installing via NPM:
Is it better to use the Live Sass Compiler (VS Code extension) or to install and run Sass via npm? (+ tips how to change from node-sass to dart-sass)
If more comfortable with VS Code:
Live Sass Compiler - #use causes compilation error
(B) #use changes the structure how to write SASS code substantial.
What NOT works with #use is to import code right in the middle of the code like you can do with #import. So, if you need to do so you are right with your last code example using a mixin including code to the body tag. But you need to move the mixin to the body tag where you want to include the code:
//### > SASS _grid.scss
#mixin grid {
.main-content {
display:grid;
/* Set up grid stuff */
}
header{
grid-area: header;
}
}
//### > SASS main.scss
#use 'grid' as *;
body {
#include grid;
}
//### --> compiles to CSS
body .main-content {
display: grid;
/* Set up grid stuff */
}
body header {
grid-area: header;
}
But honestly there are very few scenarios when you need to nest your grid css into the body tag!
If you divide your SASS into partial files and do the output in a main file which only wraps all code together you are able to do use #use very similar to the common use of #import. Example:
//### > SASS PARTIAL _typography.scss
/* TYPOGRAPHY */
html {
font-family: sans-serif;
}
h1 {
font-size: 24px;
}
//### > SASS PARTIAL _structure.scss
/* STRUCTURE */
header{
padding: 10px 20px;
background: darkgray;
}
main {
padding: 20px 20px;
background: white;
}
footer {
padding: 20px 20px 80px 20px;
background: black;
}
//### > SASS PARTIAL _grid.scss
/* GRID HELPER CLASSES */
.grid-col_4 {
display: grid;
grid-template-columns: 25% 25% 25% 25%;
}
//### > SASS MAIN main.scss
// WRAP PARTIALS TOGETHER
// only '#use' files, no css code here
#use 'typography' as *;
#use 'structure' as *;
#use 'grid' as *;
//### --> compiles to CSS
/* TYPOGRAPHY */
html {
font-family: sans-serif;
}
h1 {
font-size: 24px;
}
/* STRUCTURE */
header {
padding: 10px 20px;
background: darkgray;
}
main {
padding: 20px 20px;
background: white;
}
footer {
padding: 20px 20px 80px 20px;
background: black;
}
/* GRID HELPER CLASSES */
.grid-col_4 {
display: grid;
grid-template-columns: 25% 25% 25% 25%;
}
HEAD UP:
Even that seems very similar to the use of #import there is a VERY BIG DIFFERENCE to #import.
If you use variables/mixins/functions you are not able to #import them to the main.scss as before first and they are ready to use by the next included files! With #use now YOU HAVE TO #use the files separatly in every partial file where you need the variables/mixins/function.
If you like you may have an additional look about how that works:
https://stackoverflow.com/a/66300336/9268485
But note: what sounds easy indeed is more complicated in practical use ... even when the projects and modules are bigger and more structured ...
Project configurations splinters to different configurations files and in some cases it additional seems to lead to code/variables repetitions if you need to include different modules with same variables settings ... in every case more code is needed. But up to now that seems to be the future ...
I ended up just using #import , I seriously doubt they would remove it in the next 3 years and break everyone's code everywhere

Ruby on Rails 6 Bootstrap undefined variable error on server restart

I am having a problem in rails 6 where when i restart my server I get Error: Undefined variable. If I comment out any scss variables in my files, refresh the page, un-comment the variables and refresh again everything works fine and I am able to use variables in my CSS files again. Im not really sure why this is happening and any help anyone can offer would be really appreciated.
Here is my application.scss file:
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
* vendor/assets/stylesheets directory can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
* files in this directory. Styles in this file should be added after the last require_* statement.
* It is generally better to create a new file per style scope.
*
*= require_self
*/
#import "custom_variables";
#import 'bootstrap/scss/bootstrap';
#import "#fortawesome/fontawesome-free/css/all.css";
#import 'layouts';
#import 'themes';
#import 'typography';
#import 'states';
and here are the files I am using variables in:
.dropdown-menu {
display: block;
visibility: hidden;
opacity: 0;
transition: all .3s;
}
#media only screen and (min-width: map_get($grid-breakpoints,"lg")) {
.dropdown:hover>.dropdown-menu {
visibility: visible;
opacity: 1;
}
}
#media only screen and (max-width: map_get($grid-breakpoints,"lg")) {
.dropdown-menu {
display: none;
}
}
.footer a:hover {
text-decoration: none;
}
.bg-dark-red {
background-color: $banner-color;
}
.navbar, .footer {
background-color: $navbar-bg-color;
a {
color: $navbar-color;
}
a:hover {
color: $navbar-hover-color;
}
.active {
color: $navbar-active-color;
}
}
.dropdown-menu {
background-color: $navbar-bg-color;
a {
color: $navbar-color;
}
a:hover {
color: $navbar-hover-color;
background-color: inherit;
}
.dropdown-divider {
border-top-color: $dropdown-border-color;
}
}
section.map {
background-color: $map-bg-color;
}
.btn-primary {
#include button-variant($primary-btn-color, darken($primary-btn-color, 7.5%), darken($primary-btn-color, 10%), lighten($primary-btn-color,5%), lighten($primary-btn-color, 10%), darken($primary-btn-color,30%));
}
Any suggestions on what I can do to stop this from occurring?
EDIT: I forgot to include the file where I am importing the variables, here it is:
$white: #fff;
$black: #000;
$primary-color: #FF0103;
$complementary-color: complement($primary-color);
$navbar-color: rgba($white, .55);
$navbar-bg-color: #343A40;
$navbar-hover-color: rgba($white, .75);
$dropdown-border-color: rgba($black, .15);
$navbar-active-color: $white;
$banner-color: $primary-color;
$primary-btn-color: #198754;
$map-bg-color: #E1E1E1;
I was also facing the same exact issue. It was so frustrating. First get rid of all the comments in the application.scss file especially the line that has *= require_self. Any file that uses bootstrap variables should have #import 'bootstrap/scss/bootstrap'; at the top. The following will NOT work:
application.scss:
#import 'bootstrap/scss/bootstrap';
#import 'custom.scss"
custom.css:
body {
background-color: $gray-200;
}
Instead move the line #import 'bootstrap/scss/bootstrap'; from application.scss to custome.scss, then it will work as shown below:
custom.scss:
#import 'bootstrap/scss/bootstrap';
body {
background-color: $gray-200;
}

Can I extend external scss rule without including it in the output?

GIVEN that there is existing scss file that defines rules like .btn {..} or .btn-primary...
I WANT to declare my own rules by extending existing rules
.my-button {
#extend .btn
#extend .btn-primary
}
without actually including the .btn and .btn-primary classes in my generated css file?
Normally I need to #import exiting.scss, but that includes all the rules from the file in my css output.
Sass does not currently support this by default, neither with the #import nor #use rule.
Nonetheless, if you (can) use npm packages (npm / yarn) in your project, then node-sass-magic-importer may come in handy for you.
In your example, you could do the following:
#import '{ .btn, .btn-primary } from ~bootstrap';
.my-button {
#extend .btn
#extend .btn-primary
}
Note that the above will not do exactly what you desire – it will still import the other two classes though at least not the entire stylesheet. If you'd still like to go one step further, you could do:
#import '{ .btn as .my-button } from /bootstrap/_buttons.scss';
#import '[variables] from /bootstrap/_variables.scss';
#import '[mixins] from /bootstrap/mixins/_buttons.scss';
.my-button {
#include button-variant($btn-primary-color, $btn-primary-bg, $btn-primary-border);
}
I will recommend you to use #mixins and #include for this.
Although because as you said in your question, you are using an existing file (probably third party) that defines this rules. It may be tedious to turn the classes from this file into mixins.
so if you are going to use only a few classes from this file I recommend you to do that.
You will have to turn:
.btn{
/*
some cool styles
*/
}
into:
#mixin{
/*
cooler styles
*/
}
but still mixins as declared in the Sass documentation do exactly what you want.
source code SCSS:
#mixin reset-list {
margin: 0;
padding: 0;
list-style: none;
}
#mixin horizontal-list {
#include reset-list;
li {
display: inline-block;
margin: {
left: -2px;
right: 2em;
}
}
}
nav ul {
#include horizontal-list;
}
result CSS:
nav ul {
margin: 0;
padding: 0;
list-style: none;
}
nav ul li {
display: inline-block;
margin-left: -2px;
margin-right: 2em;
}
when you import as #import in scss and when you do a production build the webpack dependancy graph will only include it once at the top level as it becomes a common chunk since you are using it in multiple places. Yes there is a side effect that unused scss is also included as there isn't much of tree shaking that is done.
Hence it should not affect the production build.

less css avoid globalized variable

I'm looking for the best way to avoid globally diffused variables.
I made a test with this configuration:
_import.less
#test: #FFF;
_import2.less
#test: #000;
test.less
#import (reference) "_import";
body {
background: #test;
}
test2.less
#import (reference) "_import2";
div {
background: #test;
}
index.less
#import "test";
#import "test2";
The output with lessc index.less test.css still looks like
body {
background: #000;
}
div {
background: #000;
}
But what I'm looking for is:
body {
background: #FFF;
}
div {
background: #000;
}
Using less 2.7 or 3.9 give the same behavior.
Do someone know a solution?
Thanks
You can always isolate the scope of anything (incl. an imported file) using "unnamed namespace", i.e. & {}, block.
E.g.:
test.less:
#import "_import";
body {
background: #test;
}
test2.less:
#import "_import2";
div {
background: #test;
}
index.less:
& {#import "test";}
& {#import "test2";}
Depending on your goals these & {} blocks can be moved right into the test files themselves.
---
Ref: Local Variable Scoping in Import Files

Resources