My .scss aren't considered in my ruby app - css

I'm a newbie in ruby developement so sorry in advance if my question isn't less precise at the first time.
I try to apply a css style but the way I'm using doesn't work as I think it should.
index.html.erb from home controller app/views/home
<div class="box_home">
...
...
</div>
home.scss app/assets/styelsheets
.box_home { margin-bottom: 20px; }
application.scss app/assets/styelsheets
#import "bootstrap-sprockets";
#import "bootstrap";
body { padding-top: 50px; }
.box_home { margin-bottom: 20px; }
Nothing happend like that. But if I insert the css property in application.scss it works.
Is it the right way to do or should I decentralize styles in each controller's scss files ? If yes, how ?
I tried to find docs or older Q&A but I didn't.
Thanks in advance for your help.

Did you require this file inside application.css?
*= require home

If you are working with SCSS files, you should actually use #import instead of require in your application.scss
#import "bootstrap-sprockets";
#import "bootstrap";
#import "home";
// ...
From the rails asset pipeline documentation
If you want to use multiple Sass files, you should generally use the Sass #import rule
instead of these Sprockets directives. When using Sprockets directives, Sass files exist within
their own scope, making variables or mixins only available within the document they were defined in.

Related

Organize application SASS files using Bootstrap

I'm starting to work on a large application styling files. As Bootstrap 4 offers SASS files, I decided to follow that path.
I have built the following files structure:
theme.scss: general definitios for the theme like colors and fonts. Today there is just one but there could be more in the future.
global.scss: includes Bootstrap, some Bootstrap overrides and application componentes -i.e. a field with its label as part of the top border.
site.scss: general application styles.
additional page-specific SCSS files. I.e.: login.scss.
The problem I'm having is that global.scss -the one that imports Bootstrap- is then imported by site.scss as well as other files like page-specific SCSS files. So, Bootstrap styles end up in more than one compiled CSS. Compiled CSS files are what the application actually references.
I've previously used LESS and I could solve this using #import (reference) "bootstrap" instead of just plain #import "bootstrap". With SASS I haven't been able to find any solution to this problem without modifying Bootstrap core files.
Is there any other recommended way to organize the files and avoid this problem? Am I missing something or doing anything wrong?
Here are the files contents (they are large files but I'm posting only enough contents to show the problem I'm having):
theme.scss
$my-primary-color: #04459a;
global.scss
#import "../theme.scss";
$primary: $my-primary-color;
#import "../../third-party/bootstrap/scss/bootstrap.scss";
%field{
// [...]
}
site.scss
#import "global.scss";
div.field {
#extend %field;
}
// [...]
login.scss (or many other)
#import "global.scss";
// [...]
In the application I'm referencing site.css and login.css (in the loign page, of course) and both of them include Bootstrap styles.
I've built something that works for me, not sure if it's the best solution or which drawbacks it has, though.
I took some ideas from this article: My favored SCSS setup with Bootstrap 4. Here's what I've built:
First I created two SASS files for importing Bootstrap (similar to what the article does with bootstrap/_config.scss but splitted):
bootstrap/_sass-componentes.scss
#import "../../terceros/bootstrap/scss/_functions.scss";
#import "../../terceros/bootstrap/scss/_variables";
#import "../../terceros/bootstrap/scss/_mixins";
bootstrap/_config.scss
#import "_sass-componentes.scss";
// Every other bootstrap file I want to include:
#import "../../terceros/bootstrap/scss/_root";
#import "../../terceros/bootstrap/scss/_reboot";
#import "../../terceros/bootstrap/scss/_type";
// [...]
#import "../../terceros/bootstrap/scss/_utilities";
#import "../../terceros/bootstrap/scss/_print";
Then in global.scss I changed the bootstrap.scss import line to import only bootstrap/_sass-componentes.scss
Finally, in site.scss I included global.scss (such as it was before) and then full Bootstrap files trough bootstrap/_config.scss. **
** After importing _config.scss I also import my Bootstrap customizations. For doing them I followed the recomendation of the linked article although they do not apply directly to my own question.

What is the difference between CSS #import and SASS/SCSS #import?

The original CSS have the #import keyword, which helps us with including an external CSS file.
So, what is the difference between this #import and the one from SASS/SCSS?
#import in CSS: CSS has an import option that lets you split your CSS into smaller, more maintainable portions.
Whereas,
#import in SASS/SCSS: Sass builds on top of the current CSS #import but instead of requiring an HTTP request, Sass will take the file that you want to import and combine it with the file you're importing into so you can serve a single CSS file to the web browser.
For Example:
In _reset.scss
// _reset.scss
html,
body,
ul,
ol {
margin: 0;
padding: 0;
}
In base.scss
// base.scss
#import 'reset';
body {
font: 100% Helvetica, sans-serif;
background-color: #efefef;
}
References: SASS Guide
css #import happens at runtime, Sass #import at build time.
I recommend to use Sass imports wherever it is possible.
Assume that we have the following code written in native CSS:
#import "style1.css";
#import "style2.css";
#import "style3.css";
As a result, you getting one file, which is downloading another files. These requests are sent separately to your server and you get 3 files in response. Just look at the developer console to notice this problem.
In Sass way files are concatenated to one file (by the frontend workflow you use) and it's just one request to your server.
From the docs:
Sass extends CSS's #import rule with the ability to import Sass and CSS stylesheets, providing access to mixins, functions, and variables and combining multiple stylesheets' CSS together.
However, the use of #import is now discouraged in Sass, which recommends using #use instead.
This should reduce the confusion between css and scss #import statements.

Rails: Assets/stylesheets/application.scss formatting not applied to view

This is my application.scss file:
#import "bootstrap-sprockets";
#import "bootstrap";
.fav_yes {
color: white;
background-color: red;
}
.navigation {
color:green;
};
Yet when I have elements with class="fav_yes" in my views I'm still not seeing the styled html. I tried messing around with semicolons and whatnot with no luck. No similar questions seem to provide effective solutions. What am I missing?
From the bootstrap-saas git-hub write up:
If you have just generated a new Rails app, it may come with a .css file instead. If this file exists, it will be served instead of Sass, so rename it:
I still had an application.css file, so the .scss was being overriden. I just copied and pasted content of the .scss into .css, deleted the .scss file and renamed the the .css file to .scss.
you forgot to add this to your application.js: //= require bootstrap-sprockets
make sure it is under //= require jquery

How to do LESS #import without #import literally?

I'm using LESS. From Google PageSpeed I've learnt that, using #import in CSS file will hamper the site speed. So I'd like to exclude any #import thing from my CSS. I have 2 different stylesheets reset.css, and rebuild.css - to avoid #import I copied all of their code into my main stylesheet. So the real styles of my site got below many code and that's a problem. So I need the two stylesheets to #import into the styles.less (main stylesheet) file, in a way, so that, they actually won't generate any #import when I'm compiling them with WinLESS into pure styles.css. I want them to insert physically into the style.css when I'll compile the styles.less into styles.css.
I want styles.less like:
#import('reset.css');
#import('rebuild.css');
/* SITE STYLES HERE */
But want the rendered styles.css to be:
code from reset.css
code from rebuild.css
/* THEN, SITE STYLES HERE */
I'm using WinLESS to compile the CSS file from LESS, and NOT USING .less with JavaScript directly, but using the styles.css only.
The simplest way:
#import (less) 'reset.css';
#import (less) 'rebuild.css';
/* SITE STYLES HERE */
You can just use an import statement in your less file. it will be included (css code is inserted) in your result css file.
read more on winless example page (click on Importing)
Example:
styles.less:
#import('other.less');
.myOtherClass {
// other rules
}
other.less:
.myClass {
// rules
}
after compiling using winless (or any other less compiler); result.css:
.myClass {
// rules
}
.myOtherClass {
// other rules
}

import .css file into .less file

Can you import .css files into .less files...?
I'm pretty familiar with less and use it for all my development. I regularly use a structure as follows:
#import "normalize";
//styles here
#import "mixins";
#import "media-queries";
#import "print";
All imports are other .less files and all works as it should.
My current issue is this:
I want to import a .css file into .less that references styles used in the .css file as follows:
#import "../style.css";
.small {
font-size:60%;
.type;
}
// other styles here
The .css file contains a class called .type but when I try to compile the .less file I get the error NameError: .type is undefined
Will the .less file not import .css files, only other .less ones...? Or am I referencing it wrong...?!
You can force a file to be interpreted as a particular type by specifying an option, e.g.:
#import (css) "lib";
will output
#import "lib";
and
#import (less) "lib.css";
will import the lib.css file and treat it as less. If you specify a file is less and do not include an extension, none will be added.
If you want your CSS to be copied into the output without being processed, you can use the (inline) directive. e.g.,
#import (inline) '../timepicker/jquery.ui.timepicker.css';
I had to use the following with version 1.7.4
#import (less) "foo.css"
I know the accepted answer is #import (css) "foo.css" but it didn't work. If you want to reuse your css class in your new less file, you need to use (less) and not (css).
Check the documentation.
Change the file extension of your css file to .less. You don't need to write any LESS in it; all CSS is valid LESS (except of the MS stuff that you have to escape, but that's another issue.)
Per Fractalf's answer this is fixed in v1.4.0
From the LESS website:
If you want to import a CSS file, and don’t want LESS to process it,
just use the .css extension:
#import "lib.css"; The directive will just be left as is, and end up
in the CSS output.
As jitbit points out in the comments below, this is really only useful for development purposes, as you wouldn't want to have unnecessary #imports consuming precious bandwidth.
Try this :
#import "lib.css";
From the Official Documentation :
You can import both css and less files. Only less files import
statements are processed, css file import statements are kept as they
are. If you want to import a CSS file, and don’t want LESS to process
it, just use the .css extension:
Source : http://lesscss.org/
If you just want to import a CSS-File as a Reference (e.g. to use the classes in Mixins) but not include the whole CSS file in the result you can use #import (less,reference) "reference.css";:
my.less
#import (less,reference) "reference.css";
.my-class{
background-color:black;
.reference-class;
color:blue;
}
reference.css
.reference-class{
border: 1px solid red;
}
*Result (my.css) with lessc my.less out/my.css *
.my-class {
background-color: black;
border: 1px solid red;
color: blue;
}
I'm using lessc 2.5.3
If you want to import a css file that should be treaded as less use this line:
.ie {
#import (less) 'ie.css';
}
since 1.5.0 u can use the 'inline' keyword.
Example: #import (inline) "not-less-compatible.css";
You will use this when a CSS file may not be Less compatible; this is because although Less supports most known standards CSS, it does not support comments in some places and does not support all known CSS hacks without modifying the CSS.
So you can use this to include the file in the output so that all CSS will be in one file.
(source: http://lesscss.org/features/#import-directives-feature)

Resources