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.
I am trying to load font awesome using npm package manager and webpack in laravel project.
I tried many solution with/without $fa-font-path but none of them are working.
I tried:
$fa-font-path: "~#fortawesome/fontawesome-free/webfonts/";
#import '~#fortawesome/fontawesome-free/scss/fontawesome.scss';
#import '~#fortawesome/fontawesome-free/scss/solid.scss';
#import '~#fortawesome/fontawesome-free/scss/brands.scss';
#import "~#fortawesome";
with/without ~ sign too.
Each time font files are generated on the public/fonts/vendor/#fortawesome/fontawesome-free/webfonts/
It seems like it is considering default font path: $fa-font-path: "~#fortawesome/fontawesome-free/webfonts";
And the other issue is that it always look for /css/~#fortawesome/fontawesome-free/webfonts/fa-solid-900.woff this path. I dont know why it is adding ~ in css. I belive its $fa-font-path set inside fontawesome _variable library. While the generated directory is #fortawesome without ~
So I need to fix two issues here:
1) Fix the path in laravel mix webpack
2) Remove prefix ~ sign from path and make $fa-font-path work
In /resources/sass/app.scss add...
// Fontawesome
#import '~#fortawesome/fontawesome-free/scss/fontawesome';
#import '~#fortawesome/fontawesome-free/scss/regular';
#import '~#fortawesome/fontawesome-free/scss/solid';
#import '~#fortawesome/fontawesome-free/scss/brands';
You don't need: $fa-font-path. The ~ references the /node_modules directory.
I'm doing a tutorial to learn Bootstrap 4 (alpha 6). I need to customize the original css configuration from bootstrap.
For this I have modified the _custom.scss:
// Bootstrap overrides
//
// Copy variables from `_variables.scss` to this file to override
default values
// without modifying source files.
$green:red;
I then recompile the bootstrap.scss file (I'm using prepros) and when I reload the page, nothing has changed. When I look to the generated bootstrap.css file the color is still the default green color from bootstrap main theme.
When I modify the _variables.scss file directly it works perfectly.
In my bootstrap.scss file the _custom.scss file is imported after _variables.scss :
// Core variables and mixins
#import "variables";
#import "mixins";
#import "custom";
Does anyone have a clue on why this isn't working ?
Ok I found the answer.
It was a misunderstanding of how Sass works. I thought that these variables was like in java : a reference. But it is not the case here in sass so you have to redefine also the components using the color variable like this :
$green:red;
$brand-success:$green;
I had the same issue, my _custom.scss wasn't seems to be working while compiling, but actually its its a very simple fix.
copy _variables.scss content and paste into _custom.scss file and simply remove all !default; from the whole file.
$font-size-h1: 2.5rem !default;
to
$font-size-h1: 2.5rem;
will fix the issue.
In Java8_31 I imported different CSS files like that in my main.css:
#import "style/common/test1.css";
#import "style/common/test2.css";
All files were in the package style/common and it worked great.
Now with the build Java8_40 I did the same thing, but I get the following error message:
Could not find stylesheet:
file:/mypath/../style/common/style/common/test2.css
com.sun.javafx.css.parser.CSSParser handleImport
All my styles from the CSS file test1.css are working. What I was curious about was the fact that my path style/common is showing up two times.
So I tried to change my imports to the following:
#import "style/common/test1.css";
#import "test2.css";
With these imports, both styles of the file test1 and the file test2 are working. But both files are still in the same package.
Whats happening here? Is there a known issue about the #import and probably a problem in the CSSParser?
It actually is a known issue:
https://javafx-jira.kenai.com/browse/RT-40346
There is a temporary fix available and the issue should be fixed in the next build Java8_u60.
The temporary fix can be made in the CSSParser class. Link to the git diff:
http://hg.openjdk.java.net/openjfx/8u-dev/rt/rev/839912277bf0
If you dont want to try the fix or wait for u60, just add all css files to the same folder and import it like that (temporary solution!):
#import "css/test1.css";
#import "test2.css";
#import "test3.css";
#import "testX.css";
Just contributing to the discussion (not directly to your question):
You don't have to explicitly set the full .css file path. All you need is to specify the .css folder and the file name:
Original path:
#import "css/nodes/path/CssFile.css";
Full path without folder specification:
#import "../../path/CssFile.css";
Both work the same. Notice that, in the second example, "../" refers to the path level, not the specific folder name.
So in your case, that would be
#import "../common/test1.css";
I have installed font-awesome 4.0.3 icons using npm install.
If I need to use it from node-modules how should I use it in html file?
If I need to edit the less file do I need to edit it in node-modules?
Install as npm install font-awesome --save-dev
In your development less file, you can either import the whole font awesome less using #import "node_modules/font-awesome/less/font-awesome.less", or look in that file and import just the components that you need. I think this is the minimum for basic icons:
/* adjust path as needed */
#fa_path: "../node_modules/font-awesome/less";
#import "#{fa_path}/variables.less";
#import "#{fa_path}/mixins.less";
#import "#{fa_path}/path.less";
#import "#{fa_path}/core.less";
#import "#{fa_path}/icons.less";
As a note, you still aren't going to save that many bytes by doing this. Either way, you're going to end up including between 2-3k lines of unminified CSS.
You'll also need to serve the fonts themselves from a folder called/fonts/ in your public directory. You could just copy them there with a simple gulp task, for example:
gulp.task('fonts', function() {
return gulp.src('node_modules/font-awesome/fonts/*')
.pipe(gulp.dest('public/fonts'))
})
You have to set the proper font path. e.g.
my-style.scss
$fa-font-path:"../node_modules/font-awesome/fonts";
#import "../node_modules/font-awesome/scss/font-awesome";
.icon-user {
#extend .fa;
#extend .fa-user;
}
Add the below to your .css stylesheet.
/* You can add global styles to this file, and also import other style files */
#import url('../node_modules/font-awesome/css/font-awesome.min.css');
You will need to copy the files as part of your build process. For example, you can use a npm postinstall script to copy the files to the correct directory:
"postinstall": "cp -R node_modules/font-awesome/fonts ./public/"
For some build tools, there are preexisting font-awesome packages. For example, webpack has font-awesome-webpack which lets you simple require('font-awesome-webpack').
Using webpack and scss:
Install font-awesome using npm (using the setup instructions on https://fontawesome.com/how-to-use)
npm install #fortawesome/fontawesome-free
Next, using the copy-webpack-plugin, copy the webfonts folder from node_modules to your dist folder during your webpack build process. (https://github.com/webpack-contrib/copy-webpack-plugin)
npm install copy-webpack-plugin
In webpack.config.js, configure copy-webpack-plugin. NOTE: The default webpack 4 dist folder is "dist", so we are copying the webfonts folder from node_modules to the dist folder.
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
plugins: [
new CopyWebpackPlugin([
{ from: './node_modules/#fortawesome/fontawesome-free/webfonts', to: './webfonts'}
])
]
}
Lastly, in your main.scss file, tell fontawesome where the webfonts folder has been copied to and import the SCSS files you want from node_modules.
$fa-font-path: "/webfonts"; // destination folder in dist
//Adapt the path to be relative to your main.scss file
#import "../node_modules/#fortawesome/fontawesome-free/scss/fontawesome";
//Include at least one of the below, depending on what icons you want.
//Adapt the path to be relative to your main.scss file
#import "../node_modules/#fortawesome/fontawesome-free/scss/brands";
#import "../node_modules/#fortawesome/fontawesome-free/scss/regular";
#import "../node_modules/#fortawesome/fontawesome-free/scss/solid";
#import "../node_modules/#fortawesome/fontawesome-free/scss/v4-shims"; // if you also want to use `fa v4` like: `fa fa-address-book-o`
and apply the following font-family to a desired region(s) in your html document where you want to use the fontawesome icons.
Example:
body {
font-family: 'Font Awesome 5 Free'; // if you use fa v5 (regular/solid)
// font-family: 'Font Awesome 5 Brands'; // if you use fa v5 (brands)
}
With expressjs, public it:
app.use('/stylesheets/fontawesome', express.static(__dirname + '/node_modules/#fortawesome/fontawesome-free/'));
And you can see it at: yourdomain.com/stylesheets/fontawesome/css/all.min.css
You could add it between your <head></head> tag like so:
<head>
<link href="./node_modules/font-awesome/css/font-awesome.css" rel="stylesheet" type="text/css">
</head>
Or whatever your path to your node_modules is.
Edit (2017-06-26) - Disclaimer: THERE ARE BETTER ANSWERS. PLEASE DO NOT USE THIS METHOD. At the time of this original answer, good tools weren't as prevalent. With current build tools such as webpack or browserify, it probably doesn't make sense to use this answer. I can delete it, but I think it's important to highlight the various options one has and the possible dos and do nots.
Since I'm currently learning node js, I also encountered this problem. All I did was, first of all, install the font-awesome using npm
npm install font-awesome --save-dev
after that, I set a static folder for the css and fonts:
app.use('/fa', express.static(__dirname + '/node_modules/font-awesome/css'));
app.use('/fonts', express.static(__dirname + '/node_modules/font-awesome/fonts'));
and in html:
<link href="/fa/font-awesome.css" rel="stylesheet" type="text/css">
and it works fine!
I came upon this question having a similar problem and thought I would share another solution:
If you are creating a Javascript application, font awesome icons can also be referenced directly through Javascript:
First, do the steps in this guide:
npm install #fortawesome/fontawesome-svg-core
Then inside your javascript:
import { library, icon } from '#fortawesome/fontawesome-svg-core'
import { faStroopwafel } from '#fortawesome/free-solid-svg-icons'
library.add(faStroopwafel)
const fontIcon= icon({ prefix: 'fas', iconName: 'stroopwafel' })
After the above steps, you can insert the icon inside an HTML node with:
htmlNode.appendChild(fontIcon.node[0]);
You can also access the HTML string representing the icon with:
fontIcon.html
If you're using npm you could use Gulp.js a build tool to build your Font Awesome packages from SCSS or LESS. This example will compile the code from SCSS.
Install Gulp.js v4 locally and CLI V2 globally.
Install a plugin called gulp-sass using npm.
Create a main.scss file in your public folder and use this code:
$fa-font-path: "../webfonts";
#import "fontawesome/fontawesome";
#import "fontawesome/brands";
#import "fontawesome/regular";
#import "fontawesome/solid";
#import "fontawesome/v4-shims";
Create a gulpfile.js in your app directory and copy this.
const { src, dest, series, parallel } = require('gulp');
const sass = require('gulp-sass');
const fs = require('fs');
function copyFontAwesomeSCSS() {
return src('node_modules/#fortawesome/fontawesome-free/scss/*.scss')
.pipe(dest('public/scss/fontawesome'));
}
function copyFontAwesomeFonts() {
return src('node_modules/#fortawesome/fontawesome-free/webfonts/*')
.pipe(dest('public/dist/webfonts'));
}
function compileSCSS() {
return src('./public/scss/theme.scss')
.pipe(sass()).pipe(dest('public/css'));
}
// Series completes tasks sequentially and parallel completes them asynchronously
exports.build = parallel(
copyFontAwesomeFonts,
series(copyFontAwesomeSCSS, compileSCSS)
);
Run 'gulp build' in your command line and watch the magic.
SASS modules version
Soon, using #import in sass will be depreciated. SASS modules configuration works using #use instead.
#use "../node_modules/font-awesome/scss/font-awesome" with (
$fa-font-path: "../icons"
);
.icon-user {
#extend .fa;
#extend .fa-user;
}