How to import images in SASS? - css

I used to use the Compass library for SASS (.scss) but in my current project I'm not. In Compass I would load images for sprites like so:
#import "../../../images/sprites/large/*.png";
But now when I do this it gives the following error:
Error: File to import not found or unreadable: ../../../images/sprites/large/*.png
I know SASS doesn't have built in support for sprites but I copied over the compass sprite functions to be able to use them independent of the rest of the library.
Any idea how to solve this issue? The path is correct and the images do exist at that location relative to the .scss file where the import is called. I'm assuming this happens because on Compass's config.rb file you can define the import paths but on plain SASS there is no config file to do this from...

Related

Import css cdn in sass file and extend class from it

I have exposed CSS classes as CDN to be imported into any scss file.
The way i am importing the cdn into my scss file is using
#import url(cdn_name)
And in the same file, I have extended one of the classes that is in cdn.
But the issue is that at build time the url is not resolved and it gives error that it could not find the class that is being extended
Is there any way that the url actually gets resolved at build time only so that this error does not come?
Check the following code snippet of scss file
#import url("cdn_name");
.abc{
#extend .def
}
The def class is actually there in cdn_name url but is not found at compile time

PhpStorm File Watcher for SCSS not compiling node_modules

I'm working on a custom theme for my local WordPress site. I've set up a File Watcher in PhpStorm that compiles my scss files in myTheme/scss/ to myTheme/style.css.
This works as intended, the variables which I've declared in _variables.scss are able to be used in style.css or any file imported after it.
My problem now is that the #import '~foundation-sites/dist/css/foundation.min.css'; is being compiled as #import '~foundation-sites/dist/css/foundation.min.css'; instead of the actual css content.
I've tried using #import '../node_modules/foundation-sites/dist/css/foundation.min.css'; instead but this compiles the same way.
What am I doing wrong?
.css extension in import statement tells the compiler to generate plain CSS import instead of pulling the contents in; see https://github.com/sass/sass/issues/556#issuecomment-397771726 for reference.
I'd suggest changing your import to
#import '../node_modules/foundation-sites/dist/css/foundation' - this should help.
Note that ~ prefix is a webpack feature SASS compiler is not aware of. So, when using SASS in your file watcher, you have to either change paths to relative or pass --load-path node_modules/ to compiler
I ran into this issue and this solved it for me. Uncheck Track only root files, which is defaultly checked.

Im importing regular CSS file in SCSS file, but?

im import in scss #import "./libs/bootstrap-select.css";
after build given #import url(./libs/bootstrap-select.css);
i need css code in file
if import in scss #import "./libs/bootstrap-select"; norm, but
DEPRECATION WARNING on line 1, column 8 of /libsass/test.scss:
Including .css files with #import is non-standard behaviour which will be removed in future versions of LibSass.
Use a custom importer to maintain this behaviour. Check your implementations documentation on how to create a custom importer.
The latest implementation of LibSass is warning us about an upcoming change in an effort to stick to the sass standards and they primarily say that you should direct the sass/scss code to "load" your standard css file instead of importing it inline to form part of a unique css file, it won't work that way anymore, of course it is just a warning for now but in a near future they will remove that functionality, called by them "non-standard behavior" :D so I invite you to read this thread:
Including .css files with #import is non-standard behaviour which will be removed in future versions of LibSass. (GitHub issue #2362)
I just figured out a handy workaround for this problem.
Simply rename your .css file to a .scss file and import that instead, making sure to update your import statement to reference the file with the new .scss extension.
The warning goes away :)
wrap it in an url()
e.g.
#import url("{file Path here}");
I had the same problem, but only needed the .css file on one page. My solution was, instead of importing it in my .scss, to copy the .css file from my resources directory to the public directory with Gulp. Then, on the page which needed the .css code I imported it with:
<link href="path + file.css" rel="stylesheet" type="text/css">
Import works for *.scss the same way as for *.css files - just omit the extension:
#import "path/to/file";
This will import file.css
If this does not work, change your extention from the .css file to .scss and import it #import "yourfile";

Bundle sass files into single sass file

TL;DR: My question is how to bundle some of my sass files into single sass file?
I've been developing an Angular component library and I package it with ng-packagr. Let's call it #my-lib/ngx-components.
Consumers of my lib will import my components like #my-lib/ngx-components/navbar.
I decided to add theming support to components.
For example, I have a navbar component with default colors (background, text, hover etc.) I want consumers of my library to be able to override these colors with their own theme. That's why I've written a mixin which takes a $theme input and override some css rules as follows (this is a basic version of what I have)
_navbar-theme.sass
#mixin navbar-theme($theme)
$primary-color: map-get($theme, primary-color)
$secondary-color: map-get($theme, secondary-color)
$color: map-get($theme, color)
.navbar
background-color: $primary-color
color: $color
&:hover
background-color: $secondary-color
Each component has its own *-theme.sass file.
I also have global _theming.sass file which imports all of these as follows
_theming.sass
#import './components/navbar/navbar-theme'
#import './components/button/button-theme'
#import './components/dropdown/dropdown-theme'
I want to export this _theming.sass file from my lib, so people can import this file in their own sass file as #import '~#my-lib/ngx-components/theming' and start using all of the mixins available.
If they want to have custom navbar, button etc, they should be able to use those mixins with single import.
I tried to make it look like angular-material theming setup.
At first, I have tried node-sass which is already in my dependencies. But, it tries to build sass into css so it omits mixins in the output file.
Then, I looked at what angular-material has done. They use scss-bundle
I thought "this is exactly what I want." However, it requires scss files, not sass files. It cannot read sass files.
Then, I thought "Okay, I can give up on sass and start using scss. How do I convert all those files to scss without going through them by hand". Then, I found sass-convert. In this question it was said that I can use it within command line. However, when I install sass-convert with npm globally, it didn't give me a command line executable. I think I need Gulp to use it.
I've been avoding to use Gulp from the beginning, because it means another tool to learn and it adds complexity to codebase.
At this point, I feel like "Hal fixing light bulb"
TL;DR: My question is how to bundle some of my sass files into single sass file?
Also, If you can come up with a solution that requires webpack, that's fine too.
Let's through your opinion or questions:
I want to export this _theming.sass file from my lib, so people can
import this file in their own sass file as #import
'~#my-lib/ngx-components/theming' and start using all of the mixins
available. If they want to have custom navbar, button etc, they should
be able to use those mixins with single import.
You need to know, what is your target audience. Mostly people using angular cli for create their app like template scratch.
So you need provide css bundle (people just want import your css) and sass bundle (who want to use your object or your mixin).
I want to export this _theming.sass file from my lib, so people can
import this file in their own sass file as #import
'~#my-lib/ngx-components/theming' and start using all of the mixins
available. If they want to have custom navbar, button etc, they should
be able to use those mixins with single import.
I tried to make it look like angular-material theming setup.
Firstly, you need to know that #angular/material doesn't export sass (they use scss) but they export css thene compiled by scss-bundle (as you mention it) see their code and documentation theme.
I thought "this is exactly what I want." However, it requires scss
files, not sass files. It cannot read sass files.
I would like quote this answer:
Sass is a CSS pre-processor with syntax advancements. Style sheets in
the advanced syntax are processed by the program, and turned into
regular CSS style sheets. However, they do not extend the CSS standard
itself.
It is better you need transfer your code from sass to scss (by yourself), it would not much to do it (I think, I always write scss instead sass file).
Solution:
1. Provide css and sass (scss better)
When you deliver your component libs, You have to provide css and scss. Beacuse angular cli doesn't provide scss loader by default.
Don't use sass file, use scss file see my refer answer on top.
scss-bundle + webpack
Since you have to provide css, you can you webpack shell plugin to bundle scss. Scss have provide cli, if you want to use cli.
2. Structure your scss
Okay, let's take sample from bootstrap#4 module for this case. Bootstrap use structure like this (Documents):
scss
|-- _variables.scss
|-- _mixins.scss
|-- _functions.scss
|-- ...
|-- index.scss
inside index.scss will have like this:
#import 'variables'
#import 'mixins'
#import 'functions'
...
so, this scss you have to deliver beside css. Like bootstrap do, then mixin will available to consumer. Also this good approach when consumer to find scss file in scss folder (easy to pointing which is scss put in).
UPDATE
For bundle to single file you have to create task runner to do it. In your case you want to use webpack, you can create a plugin to do it.
Here example plugin:
scss-bundle-plugin.js
call to you config webpack:
plugins: [
new webpack.NoEmitOnErrorsPlugin(),
new SCSSBundlePlugin({
file: path.join(__dirname, 'src/index.scss')
})
],
To try playground, checkout hello-world-loader then:
# install dependency
npm install
# try play ground
npm run webpack
it will create file _theme.scss at ./dist.
My advice don't use webpack, use task runner instead (gulp or grunt) for this simple case. Webpack too advance and hard to write task.
There is also a widely used package, called scss-bundle.
It is quite simple to use, you just create a config file with all relevant configuration and then run scss-bundle.
This for example will use all scss files, imported in entry.scss and move it to out.scss. All imports will be resolved, except for angular themes in this example, like #import '~#angular/material/theming';.
scss-bundle.config.json:
{
"bundlerOptions": {
"entryFile": "my-project/src/entry.scss",
"outFile": "dist/out.scss",
"rootDir": "my-project/src",
"project": "../../",
"ignoreImports": [
"~#angular/.*"
],
"logLevel": "debug"
}
}
My solution for scss / sass files
I've used small module bundle-scss
It bundles files by file name mask. So you need to pass correct mask like ./src/**/*.theme.scss specify destination file and maybe your custom sort-order
You don't have to create one entry point file with all imports. bundle-scss will get all files by mask analyze all imports and include this files as well

Meteor bootstrap less mixins not working across files

I am using bootstrap with Meteor, and importing the bootstrap.less files, which is installed in the public folder, through an import command in main.less:
#import "public/bower_components/bootstrap/less/bootstrap.less";
Below it, I can start using the bootstrap mixins such as .clearfix() and text-hide() and they compile fine.
However, when I want to abstract my own less code into a separate file apply.less and import that file back into main.less, which now looks like this:
#import "public/bower_components/bootstrap/less/bootstrap.less";
#import "apply.less";
I now gets an error
=> Errors prevented startup:
While building the application:
client/less/apply.less:10:2: Less compiler error: .clearfix is undefined
This is really strange. Is this an issue with Meteor?
Another thing I found out - if I put this empty mixin definition
.clearfix(){}
at the top of my apply.less file, things will compile fine again.
Has anyone come across this issue before and figured out a workaround?
Rename your second file as apply.lessimport and import it as:
#import "apply.lessimport";
Basically, the less package looks for every file in the directory tree with a ".less" extension and compiles it to CSS individually, regardless of whether the file is being imported by another file.
When it finds a file with a ".lessimport" extension, it adds it to the list of watched files, but does not actually compile or do anything with it.

Resources