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;
}
Related
I have style.scss (my main scss), _style2.scss, and style.css
// style.scss
body {
background:red;
}
#import '_style2.scss';
div {
background: blue;
}
When this is compiled to style.css it looks like exactly what i want it to look like:
// style.css
body {
background: red;
}
p {
background: green;
}
div {
background: blue;
}
Because #import will be eventually removed from Sass, now we should use #use and #forward, but I can't make it to work with #use and #forward because: Error: #use rules must be written before any other rules.
It only works when my #use is at the beginning of the file, but i want to import my _style2.scss in the middle, how to do it?
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.
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
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
I want to do the variable overriding thing in LESS (solution) but I need to import a resource by reference and it does not work.
file one.less:
#color: #ffffff;
.foo { color: #color; }
file two.less:
// file two.less
.bar {
#import (reference) 'one.less';
}
#color: #000000;
The output:
.bar .foo {
color: #ffffff // <-- expected: "color: #000000"
}
I could not find anything about that in the internet.
Is it a bug (working with version 1.7.5)? Is it a leak in my head? Or is it simply not supported?