I have Font Awesome v4.7.0 installed and I'm trying to write Sass classes that extend Font Awesome icon classes, like this:
div.edit-icon {
#extend .fa-pencil-square-o;
font-size: $icon-font-size;
}
At the start of one of my SCSS files (_shared.scss), I try importing the bare essentials I need from Font Awesome (installed in node_modules):
#import '~font-awesome/scss/variables';
#import '~font-awesome/scss/mixins';
#import '~font-awesome/scss/icons';
However, Webpack gives me this error when I save the file:
ERROR in ./~/sass-extract-loader!./app/views/components/_shared.scss
Module build failed: Error: File to import not found or unreadable: ~font-awesome/scss/variables.
Parent style sheet: C:/Users/<me>/WebstormProjects/<project>/app/views/components/_shared.scss
at options.error (C:\Users\<me>\WebstormProjects\<project>\node_modules\node-sass\lib\index.js:291:26)
# ./app/views/components/candb/MessageDefinitionView/CoreMessageDefinitionView.tsx 9:28-77
# ./app/views/components/candb/MessageDefinitionView/TxMessageDefinitionView.tsx
# ./app/views/components/candb/index.ts
# ./app/views/components/index.ts
# ./app/views/layouts/Page/Page.tsx
# ./app/routes.tsx
# ./app/index.tsx
# multi (webpack)-dev-server/client?http://localhost:1212 webpack/hot/dev-server react-hot-loader/patch webpack-dev-server/client?http://localhost:1212/ webpack/hot/only-dev-server ./app/index.tsx
Here's the start of node_modules\font-awesome\scss\_variables.scss:
// Variables
// --------------------------
$fa-font-path: "../fonts" !default;
$fa-font-size-base: 14px !default;
$fa-line-height-base: 1 !default;
//$fa-font-path: "//netdna.bootstrapcdn.com/font-awesome/4.7.0/fonts" !default; // for referencing Bootstrap CDN font files directly
$fa-css-prefix: fa !default;
$fa-version: "4.7.0" !default;
$fa-border-color: #eee !default;
$fa-inverse: #fff !default;
$fa-li-width: (30em / 14) !default;
What I noticed is that the value of $fa-css-prefix is an unquoted string (fa), and that commenting out this assignment allows this SCSS file to compile.
How is it legal for this string to be unquoted, and what can I do to allow me to import this SCSS file?
For reference, this is a relevant part of my Webpack config for loading SCSS modules:
// Add SASS support - compile all other .scss files and pipe it to style.css
{
test: /^((?!\.global).)*\.scss$/,
loader: extractModuleCSS.extract({
fallback: 'style-loader',
use: [
'css-loader?modules&sourceMap&camelCase&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]',
'sass-loader'
]
})
}
Edit
I thought that the fact that Webpack displayed an error about a different file when I commented out $fa-css-prefix: ... meant that at least _variables.scss was compiling fine:
Undefined variable: "$fa-css-prefix".
in C:\Users\<me>\WebstormProjects\<project>\node_modules\font-awesome\scss\_icons.scss (line 4, column 4)
Apparently that isn't the case, though. If I comment out the other imports in _shared like this:
#import '~font-awesome/scss/variables';
//#import '~font-awesome/scss/mixins';
//#import '~font-awesome/scss/icons';
Then I still see the original error ('File to import not found or unreadable: ~font-awesome/scss/variables.') regardless of the changes I make to _variables.scss - even commenting out the entire file.
I've updated the title to reflect this new information.
Edit 2
Based on #CloudTseng's advice I tried this:
$fa-css-prefix: 'fa';
#import '~font-awesome/scss/variables';
#import '~font-awesome/scss/core';
#import '~font-awesome/scss/icons';
$icon-font-size: 16px;
div.edit-icon {
#extend .fa;
#extend .fa-pencil-square-o;
font-size: $icon-font-size;
}
div.cross-icon {
#extend .fa;
#extend .fa-times;
font-size: $icon-font-size;
}
Surprisingly, this gives me exactly what I want. The reason I find this surprising is that apparently I only needed to redefine fa-css-prefix locally - I was expecting that I would have to redefine all the Font Awesome variables from _variables.scss if I went this route.
However, inspecting my generated CSS shows me that all the other variables are magically resolved without me needing to redefine them:
font-awesome/scss/_icons.scss:
.#{$fa-css-prefix}-glass:before { content: $fa-var-glass; }
.#{$fa-css-prefix}-music:before { content: $fa-var-music; }
.#{$fa-css-prefix}-search:before { content: $fa-var-search; }
...
/dist/modules.css:
/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
readers do not read off random characters that represent icons */
.app-views-components-candb-FieldDefinitionTable-___FieldDefinitionTable__fa-glass___2rm6a:before {
content: "\F000"; }
.app-views-components-candb-FieldDefinitionTable-___FieldDefinitionTable__fa-music___3q-Vg:before {
content: "\F001"; }
.app-views-components-candb-FieldDefinitionTable-___FieldDefinitionTable__fa-search___f89bE:before {
content: "\F002"; }
...
Related
Does anybody know how I can use values that I have passed to a sass module (like shown below) inside another sass module that is not in the same scope but uses the module with #use?
I have a project where Sass modules are used in different files that don't always have the same styles.scss as a base. In fact I include our "core" via npm as a node module.
The core has a _core.scss file, and for every core-component a folder with at least 2 files. aA _config.scss file and a _functions.scss file and sometimes a _mixins.scss and a _generate.scss.
here is an example of the _core.scss:
#forward "colors/config";
#forward "colors/functions";
and the colors _config.scss file looks like this:
$colors: (
"primary": #8fc5de,
"secondary": #f25116,
"accent": #bcd955,
) !default;
and the _functions.scss like this:
#use "sass:map";
#use "config" as colors-cfg;
#function color($color-name) {
#if map.has-key(colors-cfg.$colors, $color-name) {
#return var(--adm-color-#{$color-name});
} #else {
#return var(--adm-color-unknown);
}
}
In the project we have 2 specific areas:
the sass folder, where we create all global stylings for the project itself
the components folder, where we style some components who can be used as webcomponents with a shadow dom (optional)
Example of styles.scss in the sass folder
#use "config" as adm-cfg;
#use "nodemodulespath/core/core" as adm;
and the config file:
#use "nodemodulespath/core/colors/config" as colors-cfg with (
$colors: (
"primary": #f59e4b,
"secondary": #f25116,
"accent": #bcd955,
"othercolor": #383723,
)
);
So far so good.
Now I want to use the colors with my color function inside the header.style.scss file. And here I have some problems with the values of the config.
Example:
#use "nodemodulespath/core/core" as adm;
.h1 {
color: adm.color("othercolor");
}
I can't use "othercolor" which i have added to the $colors map in _config.scss inside my color() function. I can only access the colors that are initially added inside the colors config from the core.
Inside the sass Folder i can access everything fine.
Any ideas how i can fix this? I already tried to pass new config values inside of header.style.scss like so:
#use "nodemodulespath/core/colors/config" as colors-cfg with (
$colors: (
"primary": #f59e4b,
"secondary": #f25116,
"accent": #bcd955,
"othercolor": #383723,
)
);
#use "nodemodulespath/core/core" as adm;
.h1 {
color: adm.color("othercolor");
}
But then I get the sass error that I can use the with() option just once.
Would be super cool if someone with a deeper understanding of the sass module system can help me with this one.
thank you!
I'm trying to pull in the Sass bootstrap source (.SCSS), make some customisations (via another .SCSS) and spit out a CSS file.
I've been trying to use Gulp to do this is VS2019 using gulp-sass. I've followed many tutorials and have come up with the following gulpfile.js
var gulp = require('gulp');
var sass = require('gulp-sass');
sass.compiler = require('node-sass');
gulp.task('sass', function () {
return gulp.src('./Main.scss')
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest('./css'));
});
In my Main.css I have the following:
$theme-colors: ( "primary": #fd7e14 );
#import "//lib/bootstrap-4.4.1/scss/bootstrap";
body {
color: #5CFF54;
background: rgb(92,18,18);
height: 400vh;
}
However, the file that is being generated contains the following:
#import "//lib/bootstrap-4.4.1/scss/bootstrap";
body {
color: #5CFF54;
background: #5c1212;
height: 400vh; }
I was expecting it to pull all of the individual styles into the produced CSS file, not just add the import.
Can anyone point me in the right direction?
After much trawling of the internet I have discovered that this is expected behaviour, and is down to the way I am referencing the source bootstrap.scss file.
In short, I am referencing it with web path, this has the effect of adding an import statement to the produced .css file. If I change the reference to a filesystem path such as this:
#import "../lib/bootstrap-4.4.1/scss/bootstrap";
it functions as I had hoped and the produced .css file includes all of the definitions from bootstrap.scss.
I'm using Bulma.io in an Angular 8 project and I've install Bulma with this command: npm install bulma. After that I've included the styles in my angular.json file:
"styles": [
"src/styles.css",
"node_modules/bulma/css/bulma.css"
],
"stylePreprocessorOptions": {
"includePaths":
"node_modules",
"node_modules/bulma/sass/utilities"
]
},
I can work with Bulma but I can't override the variables to change, for instance, the background color of a navbar.
Here's my scss file that overrides the background-color of a navbar:
#import 'horizontal-navbar.component.css';
#import 'initial-variables';
#import "functions";
#import "bulma";
$navbar-background-color: #fff;
What am I doing wrong?
Thanks in advance.
We can import this as we do it with node sass
First save the bulma package
npm install bulma --save
then go to the style.scss and give the below code
// Set your brand colors
$purple: #8a4d76;
$pink: #fa7c91;
$brown: #757763;
$beige-light: #d0d1cd;
$beige-lighter: #eff0eb;
// Update Bulma's global variables
$family-sans-serif: 'Nunito', sans-serif;
$grey-dark: $brown;
$grey-light: $beige-light;
$primary: $purple;
$link: $pink;
$widescreen-enabled: false;
$fullhd-enabled: false;
// Update some of Bulma's component variables
// $body-background-color: $beige-lighter;
$body-background-color: #fff;
$control-border-width: 2px;
$input-border-color: transparent;
$input-shadow: none;
// Import only what you need from Bulma
#import '~node_modules/bulma/sass/utilities/_all';
#import '~node_modules/bulma/sass/base/_all';
#import '~node_modules/bulma/sass/elements/button';
#import '~node_modules/bulma/sass/elements/container';
#import '~node_modules/bulma/sass/elements/title';
#import '~node_modules/bulma/sass/form/_all';
#import '~node_modules/bulma/sass/components/navbar';
#import '~node_modules/bulma/sass/layout/hero';
#import '~node_modules/bulma/sass/layout/section';
I took this example from https://bulma.io/documentation/customize/with-node-sass/
package.json
"scripts": {
"compile:sass": "node-sass sass/main.scss css/style.css -w"
}
main.scss
#import "abstracts/variables";
#import "base/typography";
_variables.scss
$color-light-grey: #777;
$color-white: #fff;
_typography.scss
body {
color: $color-light-grey;
}
.heading-primary {
color: $color-white;
}
Now my issue is when I'm trying to compile with npm run compile:sass it throws the following error:
"message": "Undefined variable: \"$color-light-grey\"."
convert all file names with beginning "_"
example:
typography.scss >> to >> _typography.scss
Looks like there are two errors in your code above:
You import "abstracts/variables" but, at least in the text, the file name seems to be _variables.scss (missing an "s")
You should import "abstracts/variables" before everything else.
Like that:
#import "abstracts/variables";
#import "base/typography";
Simply import everything in this order
- abstracts
- vendors
- base
- layout
- components
- pages
- themes
I've just started using PostCSS exclusively with Webpack. When using postcss-import to inline external stylesheets, I see it's options allow us to configure plugins and transformers to be applied on imported sources, but I'm a bit confused on how this fits in together with other options configured for the main PostCSS runner.
For instance, if I want to inline URLs, should I be adding the postcss-url plugin to postcss-import, the PostCSS runner or both (if my main stylesheet also has URL references)?
It's recommended to make postcss-import the first plugin in your list when you're defining the plugins for postcss in webpack. Since postcss-import just inlines the #import to the start of the file, any postcss plugin defined afterwards will be applied to it.
Example:
(For the example i'm gonna assume you use a postcss.config.js file, the same logic applies if you use an array for the plugins in the webpack 1 format)
// Header.css
#import 'button.css';
.foo {
font-size: 3rem;
transform:translateY(-10px);
}
// Button.css
.bar {
transform:translateX(20px);
}
If the import plugin is behind autoprefixer, it will first apply the autoprefixer plugin on the file and then afterwards import the #import file. So by the time the file is imported the prefixing will have already happened, the output will be:
// postcss.config.js
module.exports = {
plugins: {
'autoprefixer': {},
'postcss-import': {}
},
};
// output.css
.bar {
transform: translateX(20px); // Prefixing hasn't happened on the imported file
}
.foo {
font-size: 3rem;
transform:translateY(-10px);
-webkit-transform:translateY(-10px); // original file has been prefixed though
}
If you put the import first though, it will inline the imported file and then do the autoprefixing, this means both the imported and the original file will be autoprefixed:
// postcss.config.js
module.exports = {
plugins: {
'postcss-import': {},
'autoprefixer': {}
},
};
// output.css
.bar {
transform: translateX(20px);
-webkit-transform:translateX(20px); // Also prefixed now
}
.foo {
font-size: 3rem;
transform:translateY(-10px);
-webkit-transform:translateY(-10px);
}
So this means you don't actually have to add plugins again in the option of the postcss-import plugin.