How do you generate bootstrap.css file from the variables.less and bootstrap.less files from http://bootswatch.com/ ?
Compiling using lessC, I get a css file but that is way smaller than bootstrap.css. How am I supposed to change the colour in one of the themes?
Thanks a ton.
Bootswatch Swatchmaker is great and all but sometimes you are trying include Bootswatch themes in a more scriptable environment or need a better understanding of how Bootswatch themes are put together. Here is my method for manually compiling a Bootswatch Theme.
Download Twitter Bootstrap from the source and uncompress.
Move the Bootswatch files variables.less and bootswatch.less to the less/ folder, replacing the existing variables.less file.
At the end of bootstrap.less, append #import "bootswatch.less";.
Compile bootstrap.less. I recommend using the grunt task provided by Bootstrap.
Bootswatch Swatchmaker
Thomas Park, the maker and maintainer of Bootswatch, made a little kit called Swatchmaker specifically for the purposes of customizing themes from Bootswatch or creating new ones.
Check out the Swatchmaker readme in his Bootswatch repo on GitHub for more info.
Once you get that set up, just add the LESS files for the theme you want to edit to the swatch directory, editing the variables.less with your customizations.
The contents of the swatchmaker.less gives a decent summary of what it does:
#import "bootstrap/less/bootstrap.less";
#import "swatch/variables.less";
#import "swatch/bootswatch.less";
#import "bootstrap/less/utilities.less";
Then bootstrap.css is generated from lessc swatchmaker.less > bootstrap.css.
Not sure how to do this as a "supplemental" answer (#merv has already given the correct answer!), but just in case it's useful to anyone:
My problem was that I want to use just the bootstrap.less and variables.less file to generate a new theme in a way that simply used the Grunt tasks already developed in the Bootstrap distribution. I didn't want to install any Bootswatch-specific tools to compile a new theme.
I already have a modified build script that uses the core bootstrap from path /lib/bootstrap. I consider the theme to be a part of the lib as well, but I gave it its own directory: /lib/theme
Inside the theme directory, I put the two files downloaded from http://bootswatch.com -- namely, "bootswatch.less" and "variables.less". Thing is, these two files don't really "do anything" by themselves; they still rely on Bootstrap. So hooking it all up meant CREATING a third file, which I called "theme.less". The contents of theme.less are as described by #merv above:
#import "../bootstrap/less/bootstrap.less";
#import "variables.less";
#import "bootswatch.less";
#import "../bootstrap/less/utilities.less";
Your paths will be different depending on how you've structured your project. Then, in the Gruntfile.js (modified from the one included in Bootstrap), you locate the compileTheme configuration object and modify it to point to this new theme.less file:
compileTheme: {
options: {
strictMath: true,
sourceMap: true,
outputSourceFiles: true,
sourceMapURL: '<%= pkg.name %>-theme.css.map',
sourceMapFilename: 'dist/css/<%= pkg.name %>-theme.css.map'
},
src: 'lib/theme/theme.less',
dest: 'dist/css/<%= pkg.name %>-theme.css'
}
It's only the "src" line that has changed.
Now when you run > grunt dist (or any other related grunt tasks) it will pick up the theme from the new location, apply the appropriate parts of Bootstrap's included files, and produce a new theme.
Hope that's helpful to anyone. It doesn't answer the OP directly since it's a bootstrap-theme.css file rather than a bootstrap.css file, but it's more in line with what people tend to do with Bootstrap 3.2+ as of this writing. And more importantly, for those who are relative newcomers to all things LESS and Grunt, it's a fairly pain-free way to modify the build script without overwriting files in the bootstrap directory.
Related
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
I created an Angular project using Yeoman's generator, and now I am trying to add the Font Awesome to the project. I installed it using Bower using
bower install fontawesome --save
then it automatically added to my app/index.html the following code:
<!-- build:css(.) styles/vendor.css -->
<!-- bower:css -->
<link rel="stylesheet" href="bower_components/fontawesome/css/font-awesome.css" />
<!-- endbower -->
<!-- endbuild -->
But I didn't want to use it as CSS, but as a SCSS import (to be able to change the URL of font files). So I deleted the above code from the HTML page and added the proper code into app/styles/main.scss:
$icon-font-path: "../bower_components/bootstrap-sass-official/assets/fonts/bootstrap/";
$fa-font-path: "../bower_components/fontawesome/fonts/"; // <==== here
// bower:scss
#import "bootstrap-sass-official/assets/stylesheets/_bootstrap.scss";
#import "fontawesome/scss/font-awesome.scss"; // <==== and here
// endbower
Then I run grunt build, but something (Grunt?) edited my files back to the original ones. The index.html got the <link> again and mine main.scss was kept only with the Bootstrap import.
Ok, we are almost there.
So I looked at the Bootstrap's bower.json and compared to the Font Awesome's bower.json and I saw the following difference:
// Bootstrap
"main": [
"assets/stylesheets/_bootstrap.scss", // it's SCSS
...
],
// Font Awesome
"main": [
"./css/font-awesome.css", // it's CSS
...
],
Then I found a way to properly (not sure) override the Font Awesome's bower configuration using my app's bower.json, and added the following code into it
"overrides": {
"fontawesome": {
"main": [
"./scss/font-awesome.scss", // now it's SCSS
"./fonts/*"
]
}
}
Question: Is this the correct way to use Font Awesome as a SCSS import and avoid Grunt of changing my files when building the project? By overriding its default "main" property?
Judging by your question I think you may be new to the web frontend build process. Unfortunately it can be a headache at times.
First off, note that SCSS != CSS and browsers do not know how to use SCSS. Including <link rel="stylesheet" href="main.scss"> in your HTML <head> tag will not work. We can enjoy the various perks of SCSS (e.g. variables, imports, etc.) during development, but to use these styles in the browser we must transpile SCSS into CSS (which the browser recognises).
To make developer's lives easier, it is common for seed projects (such as the one you are using) to include some kind of automated build process which includes transpiling SCSS into CSS. The build process is typically executed via a task runner, such as Grunt or Gulp. These seed projects/templates also typically include a task to inject your project's dependencies (as declared in your bower.json file) into your index.html automatically. A tool called wiredep is used to read through your bower.json files to determine these dependencies, in particularly, it will look for the 'main' attribute to determine which files a particular package requires. It will then inject the appropriate <script/> and <link> tags.
To explain this further, when you execute bower -install font-aweseome --save a few things happen:
The package is downloaded and added to your project (usually to bower_components/).
An entry is added to your bower.json file adding the package to your project's dependencies.
Each package includes its own bower.json file which describes its various properties, the most important of which (after name) is main. You can see the font-awesome bower.json file here. As you can see, it's main attribute references several files. These are the files that wiredep uses to determine which <script/> and <link> tags to inject into your index.html.
By specifying an override in your project's bower.json like this:
"overrides": {
"fontawesome": {
"main": [
"./scss/font-awesome.scss", // now it's SCSS
"./fonts/*"
]
}
}
You are specifying to wiredep that ./scss/font-awesome.scss and ./fonts/* are the files required by your project, and to ignore those listed in the font-awesome bower.json file.
Regarding SCSS: take a look at the Sass guide, in particular the section on imports. The Sass #import lets you split your styles across several smaller SCSS files (partials) that, upon transpilation, are combined and included into a single (optionally minified) CSS file. This includes any third party SCSS files that you import into your main.scss. For example, if you imported font-awesome.scss into your main.scss file, then transpiled it into CSS, the resulting CSS file would include all styles contained within font-awesome.scss.
To include and customize a third party SCSS file, what I do is:
Specify an import in my own custom main.scss file.
Make any customizations to variables I want.
Transpile main.scss into CSS.
Include a <link> tag to the transpiled CSS file in my index.html file.
I have asked to clean up the LESS library and style file referenced in the head section of the application for redundancy and decreasing load time. The style file is basically style.less file and it is containing all other less files, I need to come up with single CSS file that could be style.css so everything is fine like I am getting the CSS output as style.css but there are a couple of files which are not compiling and changing in CSS. Below is a preview of style.less with other imported less files.
content of style.less
#import url('variables.less');
#import url('mixins.less');
#import url('base.less');
#import url('kendo.less');
#import url('header.less');
#import url('navigation.less');
#import url('lists.less');
#import url('treeview.less');
Where that variables.less and mixins.less are not compiling in CSS I don't know what is missing, there are nested rules applied in them may be they are making errors as I heard that there is a need for a config file to process nested variables and mixins when imported and used for plain CSS. I am unable to find the solutions to this, your help will be highly appreciated. Many thanks.
Here are my settings for the Web Essentials LESS Compiler:
OPTIONS > WEB ESSENTIALS > LESS
Auto-compile dependent files on save: TRUE
Compile files on build: TRUE
Compile files on save: TRUE
Create source map files: TRUE
Custom output directory: _PATH_TO_OUTPUT_YOUR_ONE_CSS_FILE
Don't save raw compilation output: FALSE
Process source maps: TRUE
Strict Math: FALSE
Show Preview Pane: TRUE
ALL of your LESS files except the main import LESS file should be prefixed with "_". So for example:
_base.less
_variables.less
style.less (holds the imports for base and variables).
Make sure you are using Web Essentials version 2.5. There was an error in the version after 2.5 that mucked up the precompiler. I don't know if they have updated with fixes yet.
I have a bootstrap.css file which I want to compile with my custom styles from style.sass into single output file, for example - style.css.
For sass compilation I use gruntjs with grunt-contrib-sass extension. My Gruntfile.js config for sass looks like this:
sass: {
dist: {
options: {
//style: 'compressed',
style: 'expanded',
lineNumbers: true
},
files: {
'build/styles/style.css': 'src/styles/style.sass'
}
}
}
I've tried to import bootstrap.css into sass file, but instead it only generates next code in output css (which is correct behavior http://sass-lang.com/documentation/file.SASS_REFERENCE.html#import):
#import url(bootstrap.css);
.....
/*my style.sass rules*/
I even tried to list multiple files in order of concatination and processing, like in uglifier settings:
files: {
'build/styles/style.css': ['src/styles/bootstrap.css', 'src/styles/style.sass']
}
But this only adds bootstrap.css into final style.css file ignoring style.sass existence.
As I'm new in gruntjs, I can't figure out how this should be done properly.
The Grunt configuration is correct. The reason your file is not being imported is because of the way SASS is designed to work.
The SASS documentation states:
By default, it looks for a Sass file to import directly, but there are a few circumstances under which it will compile to a CSS #import rule:
If the file’s extension is .css.
If the filename begins with http://.
If the filename is a url().
If the #import has any media queries.
Since the file you are importing has a .css extension it will therefore not be imported directly but remain a standard CSS #import.
You have three options to resolve this:
Rename the included file to _bootstrap.scss. (If you don't add the underscore a bootstrap.css will be created along with your main output file which is unnecessary.)
Include the Bootstrap SCSS source as a dependency of your project and build against that. Install the Bootstrap source using Bower by typing $ bower install bootstrap-sass-official in your project root folder. (For instructions on setting up Bower see the Bower website.) Then you can replace your import above with #import 'bower_components/bootstrap-sass-official/assets/stylesheets/bootstrap';.
Use a concatenation library such as grunt-contrib-concat to combine Bootstrap.css and your main style sheet during your build process.
This first option is fine if you downloaded the bootstrap CSS file into your project manually, however, if you are including it as a dependency with npm/bower it is not ideal.
I would recommend the second option since building Bootstrap from source will not only solve your problem but allow for customization of Bootstrap variables to fit your theme rather than overwriting them with subsequent style rules as well. The only downside is that your build process might be slightly longer due to the rather large SASS build of the Bootstrap source.
I'm using Bower to manage Bootstrap and would like to make some changes (colours, font size etc) to the default Bootstrap look and feel. Here's my workflow:
Edit bower_components/bootstrap/less/variables.less
Recompile bootstrap using grunt build
The problem is that I want to be able to upgrade bootstrap when a new version comes out and presumably I'll lose my changes to variables.less.
Is there a way I can keep my changes outside of bower_components and also avoid having bower_components in source control since it's 122MB?
you can create a variables-custom.less and import it into theme.less like this:
//
// Load core variables and mixins
// --------------------------------------------------
#import "variables.less";
//import custom-variables after variables so the values will override.
#import "custom-variables.less"; //only has variables that have changed.
#import "mixins.less";
IMO this is a little bit better than the first solution because you wont have to load two (almost) identical CSS files on the client.
I'm sorry I cant help you with what to to about Bower and your source control as I do not use Bower
Here's the solution which worked for me:
Use bower to install all UI packages e.g. bower install bootstrap chosen
Create a separate folder less which contains all the LESS modifications. This article was very helpful here.
Here's my less/styles.less file:
#import "../bower_components/bootstrap/less/bootstrap.less";
#import "../bower_components/bootstrap-chosen/bootstrap-chosen.less";
//My custom variables - overrides the bootstrap variables file
#import "variables-custom.less";
Use grunt to monitor changes within the less folder and compile them into .css
Here's my Gruntfile.js (thanks to this answer):
module.exports = function(grunt) {
grunt.initConfig({
less: {
development: {
options: {
paths: ["./less"],
yuicompress: true
},
files: {
"./static/css/styles.css": "./less/styles.less"
}
}
},
watch: {
files: "./less/*",
tasks: ["less"]
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
};
This is indeed the best customization method. You create a theme.less and pull in original Bootstrap files (which can get upgraded in the future) and in the same file you call your own custom overrides. Either you #import them from a custom file which is not in the Bower directory or you just write your custom rules in your theme.less itself. You'll find this technique explained in this tutorial as well.
With Grunt, custom setups can get tricky. But with Brunch it's a piece of cake (yes!) and all pretty much goes automatically. Your grandma could do it.
As for avoiding the inclusion of bower_components in source control: with Git it's easy. You just check-in your bower.json but make sure to add /bower_components to your .gitignore file.
You should just create your own style sheet, use both with your custom one listed secondly. That way you can make changes but not change bootstrap at all.
Also, when you update, you keep your style sheet the same.
This allows you to change bits and pieces of Bootstrap but not actually changing the file, you're overriding it.
To be clear, your second CSS file would be SIGNIFICANTLY smaller... Only putting things your needed to change in it.