5 Steps To Add Bootstrap 4 To Jekyll The Right Way
Overview
One of the keys to use Bootstrap successfully is to be able to use and redefine its variables in our custom designs. We should not simply add Bootstrap’s javascript and CSS stylesheets to use its components, we need to change them and not making all the web look boringly the same.
This is a guide to make it easy to use Bootstrap 4 with a Jekyll website and be able to use and customize its variables as well as defining new ones.
Background
Jekyll provides built-in support for syntactically awesome stylesheets (Sass).
Sass is a CSS extension language, it provides:
- Variables
- Nesting elements
- Loops
- Arguments
- Selector inheritance
It consists of two syntaxes:
- the original, indented, syntax uses the
.sass
extension. - the newer syntax, more similar to CSS, uses
.scss
extension.
To make Jekyll process these SASS files, we need to create files with
the proper extension name (.scss
or .sass
) and start the file
contents with two lines of triple dashes.
A file named assets/main.scss
will be rendered like assets/main.css
.
As Bootstrap switched from Less
to Sass
1 now we can use
it directly without relying in parallel projects like bootstrap-sass
needed for Bootstrap 3.
Installing Bootstrap 4
We will be using the package manager npm to install Bootstrap and a fresh Jekyll installation without any theme.
First we create an empty Jekyll instance and initialize npm installing Bootstrap and its dependencies.
$ jekyll new mysite --blank $ cd mysite $ npm init --force Wrote to /tmp/mysite/package.json: { "name": "mysite", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" } $ npm install bootstrap npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN bootstrap@4.1.3 requires a peer of jquery@1.9.1 - 3 but none is installed. You must install peer dependencies yourself. npm WARN bootstrap@4.1.3 requires a peer of popper.js@^1.14.3 but none is installed. You must install peer dependencies yourself. npm WARN mysite@1.0.0 No description npm WARN mysite@1.0.0 No repository field. + bootstrap@4.1.3 added 1 package in 6.096s $ npm install jquery npm WARN bootstrap@4.1.3 requires a peer of popper.js@^1.14.3 but none is installed. You must install peer dependencies yourself. npm WARN mysite@1.0.0 No description npm WARN mysite@1.0.0 No repository field. + jquery@3.3.1 added 1 package in 1.712s $ npm install popper.js npm WARN mysite@1.0.0 No description npm WARN mysite@1.0.0 No repository field. + popper.js@1.14.4 added 1 package in 1.455s
So far, we have added this structure (excluding jekyll files):
$ tree -L 2
.
βββ node_modules
βΒ Β βββ bootstrap
βΒ Β βββ jquery
βΒ Β βββ popper.js
βββ package.json
βββ package-lock.json
4 directories, 2 files
If you aren’t working in a Jekyll project, you can add it now to the current directory with jekyll new . –force.
Adding Sass load paths
We need to tell Jekyll the path of our Sass files.
Jekyll will look at the folder specified by the sass_dir
configuration key (/_sass
by default), but it also supports extending
it, so it will process other folders too.
Instead of setting a custom sass folder with:
sass:
sass_dir: _sass
we use the load-paths
2 key in _config.yml
to include
the node_modules
directory:
sass:
load_paths:
- _sass
- node_modules
load_paths
only works when not in safe mode[^safe-mode] (i.e. it
won't work natively with Github Pages.), if you use Github Pages you
need to process the site locally and upload the resulting site with a
`.nojekyll`.Whitelist node_modules
Jekyll 3.3 started excluding the node_modules
directory by default,
so we have to make sure it is included in the final site to be able to
use its files:
exclude: []
Add javascript
Add Bootstrap JavaScript at the end of the document so the pages load
faster, just before the </body>
HTML tag.
We add them in the default layout at _layouts/default.html
or in
footer.html
in the _includes
folder:
<html>
<body>
...
<script src="{{'/node_modules/jquery/dist/jquery.min.js' | prepend: site.baseurl}}"></script>
<script src="{{'/node_modules/popper.js/dist/umd/popper.min.js' | prepend: site.baseurl}}"></script>
<script src="{{'/node_modules/bootstrap/dist/js/bootstrap.min.js' | prepend: site.baseurl}}"></script>
</body>
</html>
Import Bootstrap and use Sass variables
Create variables Sass partial
To be able to define new variables and reuse the ones defined in
Bootstrap, we create a new partial Sass file _sass/_variables.scss
:
- define our variables
- “Overwrite” the ones we want from Bootstrap
node_modules/bootstrap/scss/_variables.scss
before loading them and then - import the Bootstrap variables.
!default
**[^scss_default]
property at the end.
When Jekyll process each Scss file, it only defines the variables that do not
have been assigned any value yet, so we can define Bootstrap's
variables before Bootstrap itself define them. It is important to do
this before importing the variables because there are many of them
depending on each other to calculate CSS properties values.In _sass/_variables.scss
:
$white: #fff;
$red: #dc3545;
$body-bg: $red;
$body-color: $white;
/* custom vars */
$custom-font-size: 20px;
Import variables from main Sass file
After we have our variables, we import them from our main style sheet:
In assets/main.scss
we import them and then work with our styles,
using the above variables (all Bootstrap variables and mixins are available):
---
---
@import "variables";
@import "bootstrap/scss/bootstrap";
.content {
font-size: $custom-font-size;
}
Add css to layout
After we have our assets/main.scss
, Jekyll will process it and
generate the final CSS file: assets/main.css
.
That is the path we need to add to our layout, in the <head>
section of _layouts/default.html
we include the css: <link rel="stylesheet" href="/assets/main.css">
<html>
<head>
<!-- site css -->
<link rel="stylesheet" href="{{'/assets/main.css' | prepend: site.baseurl}}">
</head>
...
</html>
All together
This is the basic flow Jekyll follows processing these Scss files to
generate assets/main.css
:
Now we have:
$ jekyll build
Configuration file: /tmp/mysite/_config.yml
Source: /tmp/mysite
Destination: /tmp/mysite/_site
Incremental build: disabled. Enable with --incremental
Generating...
done in 9.795 seconds.
Auto-regeneration: disabled. Use --watch to enable.
Other
Site
Youβll find a minimalistic example site hosted on Github showing the result of following this tutorial at https://github.com/marcanuy/jekyll-bootstrap4).
Skel
It is also part of a Jekyll starter site jekyll-skeleton.
OPTIONAL: Keep node_modules out of _site
Currently, all node_modules
packages are being copied to the final
site, to keep them out we will copy the files that we are including
directly from the node_modules
directory to a new one containing
just these files in each build, that means, we have to set up a script
replacement for jekyll build and jekyll serve.
In this case I will be using the classic make program, each task is pretty self explanatory and can also be ported easily to Grunt or any other task automation solution.
Script
Create a file called Makefile
at root level with this content:
SHELL := /bin/bash
NPM := npm
VENDOR_DIR = assets/vendor/
JEKYLL := jekyll
PROJECT_DEPS := package.json
.PHONY: all clean install update
all : serve
check:
$(JEKYLL) doctor
$(HTMLPROOF) --check-html \
--http-status-ignore 999 \
--internal-domains localhost:4000 \
--assume-extension \
_site
install: $(PROJECT_DEPS)
$(NPM) install
update: $(PROJECT_DEPS)
$(NPM) update
include-npm-deps:
mkdir -p $(VENDOR_DIR)
cp node_modules/jquery/dist/jquery.min.js $(VENDOR_DIR)
cp node_modules/popper.js/dist/umd/popper.min.js $(VENDOR_DIR)
cp node_modules/bootstrap/dist/js/bootstrap.min.js $(VENDOR_DIR)
build: include-npm-deps
$(JEKYLL) build
serve: include-npm-deps
JEKYLL_ENV=production $(JEKYLL) serve
It is just a wrapper of Jekyll build and install commands handling dependencies.
make
will fail.Now we will use make build
and make serve
to work with Jekyll as
wrappers of jekyll build
and jekyll serve
respectively.
Using new paths
It just remain to update our paths in the layout, in default.html
use them as:
<script src="{{'/assets/vendor/jquery.min.js' | prepend: site.baseurl}}"></script>
<script src="{{'/assets/vendor/popper.min.js' | prepend: site.baseurl}}"></script>
<script src="{{'/assets/vendor/bootstrap.min.js' | prepend: site.baseurl}}"></script>
Finally, tell Jekyll not to include the node_modules
directory in
the final site, in _config.yml
:
exclude:
- node_modules
Final
Now we are just including in our website the files we chose from the
node_modules
folder, placing them in assets/vendor
and avoiding to
have any other unnecessary files in the final website.
Conclusion
When we build our site, Jekyll will process the .scss
files with our
custom variables and we will have them in our _site/assets/main.css
. In
this example its content starts with the Bootstrap code and ending with
our custom _main.scss
processed, looking like:
/*!
* Bootstrap v4.0.0 (https://getbootstrap.com)
* Copyright 2011-2018 The Bootstrap Authors
* Copyright 2011-2018 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
:root {
--blue: #007bff;
--indigo: #6610f2;
--purple: #6f42c1;
/* rest of bootstrap code... */
/* custom style */
.content{
font-size: 20px;
}
You can watch a video implementing the above code at:
This article full code is avaiable at https://github.com/marcanuy/jekyll-bootstrap4 .
Changelog
- 2018-08-30:
- using npm instead of yarn
- using Makefile to copy assets to final site, Jekyll now keeps node_modules out of final site by default
References
- Sass (stylesheet language) https://en.wikipedia.org/wiki/Sass_(stylesheet_language)
- Sass project website http://sass-lang.com/
- Bootstrap 4 customization http://v4-alpha.getbootstrap.com/getting-started/options/
*[CSS]: Cascading Style Sheets
http://blog.getbootstrap.com/2015/08/19/bootstrap-4-alpha/
↩︎Moved from Less to Sass. Bootstrap now compiles faster than ever thanks to Libsass, and we join an increasingly large community of Sass developers.
Issue referring the code at https://github.com/jekyll/jekyll-sass-converter/blob/master/lib/jekyll/converters/scss.rb#L77 ↩︎
- Multilingual Jekyll Without PluginsMay 8, 2017
- Host a Jekyll Website With Pretty Urls In Amazon S3 and CloudfrontApril 24, 2017
- Get A List Of Categories Based In Subfolders In JekyllMarch 3, 2017
- 5 Steps To Add Bootstrap 4 To Jekyll The Right Way
- Automated Deployment Of Jekyll Websites To Github Pages With A Git Push To GithubNovember 8, 2016
- How To Use Bower Scss With JekyllJune 18, 2016
- How to implement breadcrumbs on a Jekyll site with nested categoriesJune 7, 2016
- How To Handle Adsense In A Jekyll Development EnvironmentJune 6, 2016
- How To Prevent Content Displaying In A Jekyll Development EnvironmentJune 6, 2016
Articles
Except as otherwise noted, the content of this page is licensed under CC BY-NC-ND 4.0 . Terms and Policy.
Powered by SimpleIT Hugo Theme
·