Wordpress: import scss from plugin in my theme - wordpress

I'm working on a theme and plugin that share components. In my theme I have a scss file and in this I want to import a main.scss file from my plugin. This is the situation:
Plugin main.scss
#import "slick";
#import "slick_theme";
#import "~bootstrap/scss/bootstrap";
#import "~aos/dist/aos.css";
#import "../../../my-directory/**/*.scss";
Theme main.scss
#import "../../plugins/my-plugin/assets/src/scss/main";
II can't compile the main.scss of my theme because it can't resolve the url of node_modules and the directory with wildcards.
Any ideas?

(A) Easiest (and fastest!) way: Use full relative path!
As SASS don't support the wild cards in SASS files using #-rules: just remove wild cards and write full relative path to node-modules like #import '../../complete/relative/path/to/node/module/dir/file.scss' ;-)
(B) ALTERNATIVE: Set includePath
Set node directory as includePath for your project. As I don't know the compiler you use here are the information how to do in original SASS (but 'includePath' variable is almost the same):
https://sass-lang.com/documentation/js-api#includepaths
In that case you are able to #import only by using the filename.
Additional notes:
In SASS rule #import does NOT support mulitple includes at all. Means: in a SASS file #import '*.scss' (as you try in your example by using wildcard * in filename) will not work at all. You ALLWAYS need to specify a concrete single file: #import 'concreteFile.scss'.
In SASS you can remove the suffix .scss from filenames. As this #import path/to/filename'` works as well.

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.

Why does my SASS #import, go onto my CSS #import?

Ok so for example, lets say I have main.css, main.sass, about.sass, and contact.sass.
main.sass should have #import about.sass and #import contact.sass. Then, when main.sass is compiled, main.css should have all the content of about.sass and contact.sass. Not #import's.
Main.sass
#import 'tools/fonts'
#import 'tools/normalize'
#import 'tools/grid'
Now when this is converted to main.min.css it looks exactly the same as in main.sass
#import url(tools/fonts.css);
#import url(tools/normalize.css);
#import url(1-tools/grid.css);
Shouldn't there be no #imports, just the combined css code?
The files you are importing don't have names that start with an underscore. If the file starts with an underscore then SASS knows that it is a partial file, and should be included wherever it is imported.
If a file name does not start with an underscore, then it will be generated as it's own CSS file.
This behaviour is described here.
Partials
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.
Note that you may not include a partial and a non-partial with the same name in the same directory. For example, _colors.scss may not exist alongside colors.scss.

Rails application.css.scss not aware of other scss files in use?

I'm following M Hartl's Rails Tutorial, and trying to add a bootswatch theme.
I have succeeded by using the boostrap-sass gem as defined in the tutorial, and twitter-bootswatch-rails gem from the net.
However, in Hartl's tutorial, all the CSS that we write in addition to default bootstrap is in a separate custom.css.scss file.
My application.css.scss file (Renamed from Rails default .css) contains
#import "bootstrap-sprockets";
// Import cerulean variables
#import "bootswatch/cerulean/variables";
// Then bootstrap itself
#import "bootstrap";
// And finally bootswatch style itself
#import "bootswatch/cerulean/bootswatch";
#import "custom";
Which works, however the custom.css.scss file has a reference to $gray-light, a variable set in bootstrap. The server will return an error at the variable reference in the css file, unless I add
#import "boostrap-sprockets";
#import "bootstrap";
to custom.css.
End result though, is I now have two gigantic CSS files being used, for what I would think is no reason.
I thought the idea of
#import "custom";
was to include my custom.css.scss file into the application.css.scss file so that it would all be in one place, and variables would work nicely.
The other method that works is to dump my entire custom.css.scss contents into application.css.scss but that defeats the point of having separate files.
Am I doing something wrong?
Edit: To add more fuel to the fire, I deleted the two lines from custom.css, and instead `#import bootswatch/cerulean/variables"; and it works. However, the resulting CSS that's on the website itself has NOTHING from that file.
This could well be wrong, but I post an answer to my own question as follows:
It appears that the sprockets lines //= require_self and //= require_tree, even when listed inside the comment section of the manifest as they are by default, are actually running.
This then causes each of the files "required" to be compiled separately. As a result, instead of getting a single application-FINGERPRINT.css file, I was getting an application, a custom, and a static_pages one. I assume this is the "require_tree" line.
After removing these lines, the #import "custom"; line works as I expected it to. The files are all combined into an application-FINGERPRINT.css file and I no longer need to #import anything at the top of custom.scss.

SCSS Partials for .css files without changing the filename

I'm looking for ways to optimize my WordPress instance. The theme has about 8-10 CSS files that are rendered in the functions.php. Consequently, I do not want to change any file names because that would mean that I have to hack the theme and I want to keep that to a bare minimum.
I want to use SCSS to combine these CSS files into one CSS file and include the new file in the theme instead. When I try...
#import "style.css";
#import "reset.css";
#import "shortcodes-styles.css";
It renders as
#import url(style.css);
#import url(reset.css);
#import url(shortcodes-styles.css);
How can I get SCSS to import the CSS as partials without changing the file names? I'm also using CodeKit if that makes a difference.
Not possible. Sass only compiles Sass files: https://github.com/nex3/sass/issues/556

SASS/ SCSS custom css sheets for #import

All I need is to do is have a directory with my custom reset sheets and other sass files for imports.
I've been playing around and I can't get compass to read my custom sheets.
1) Where do I put my custom css sheets for import?
2) how do I #import them
(I'm using the sass indentation, but I doubt that makes a difference,)
(I know little about ruby I'm just using it for compass)
Thanks
Look at the #import section in Sass reference.
You can import a Sass file without telling explicitly the file extension:
#import "file"; /*will import file.scss or file.sass. Anyway you could as well use #import "file.scss" or #import "file.sass*/
To import a CSS, provide its extension.
#import "file.css"; /*will import file.css"
There are more ways to differentiate them in the reference, but these are the most used.
You can put your files where you want, but write the path relative to the current directory (the directory which the file from where you are importing is).

Resources