Create a template using Bulma CSS framework
Bulma is a free, open source CSS framework based on Flexbox. It’s the new kid on the block in the field competing directly with the old man and the sea: Twitter Bootstrap.
There are vary ways to install it from CDN to install it as npm package: Install Bulma. There is even an interesting bulma-start package.
After trying the CDN easy way, I decided to install it using npm. Why? I can work offline, I can customize which components to add or exclude, I need to work with SASS npm package anyway.
Create the package.json file: npm init
. There is an interactive questionaire to fill in. When prompted for an entry point, enter sass/styles.scss.
I created a new folder: mkdir bulma-template-html
and inside I run:
npm install node-sass --save-dev
npm install bulma --save-dev
Create a sass folder in which you add a file called styles.scss:
@charset "utf-8";
@import "../node_modules/bulma/bulma.sass";
Now I create the basic index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My custom Bulma website</title>
<link rel="stylesheet" href="css/mystyles.css">
</head>
<body>
<h1 class="title">
Bulma
</h1>
<p class="subtitle">
Modern CSS framework based on <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox">Flexbox</a>
</p>
<div class="field">
<div class="control">
<input class="input" type="text" placeholder="Input">
</div>
</div>
<div class="field">
<p class="control">
<span class="select">
<select>
<option>Select dropdown</option>
</select>
</span>
</p>
</div>
<div class="buttons">
<a class="button is-primary">Primary</a>
<a class="button is-link">Link</a>
</div>
</body>
</html>
If you can see some color on page then you are set with Bulma!
Prepare working with SASS
To build a CSS file from a Sass file, we can use node scripts. In package.json, add the following:
{
"name": "bulmaloo",
"version": "1.0.0",
"description": "A bulma powered template.",
"main": "sass/styles.scss",
"scripts": {
"css-build": "node-sass --omit-source-map-url sass/styles.scss css/styles.css",
"css-watch": "npm run css-build -- --watch",
"start": "npm run css-watch"
},
"keywords": [
"bulma",
"template"
],
"author": "Ovi Farcas",
"license": "MIT",
"devDependencies": {
"bulma": "^0.9.1",
"node-sass": "^5.0.0"
}
}
Do a test:
$ npm run css-build
Rendering Complete, saving .css file...
Wrote CSS to /path/to/mybulma/css/styles.css
It will create the final css file.
To watch for changes, just launch the following command:
npm start
This command will run the ‘start’ script defined in your package.json file and thus having a watcher executing the conversion sass>css in real time. If still prefer to run manually use the npm run css-build
as before.
Note: There are other ways to install bulma with sass gem install sass
. There are other ways: Customize Install.
Build markup with Bulma
Now we can proceed building up a template. Create a folder assets/images to place your images there.
Now scrap the scaffolding of a page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Flowera</title>
<link rel="stylesheet" href="css/styles.css">
<script defer src="https://use.fontawesome.com/releases/v5.14.0/js/all.js"></script>
</head>
<body>
<!--YOUR BULMA CODE HERE-->
</body>
</html>
I scrap the navigation with a burger menu for the small handhelds.
<nav class="navbar" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a class="navbar-item" href="/">
<img src="assets/images/watermark.png">
</a>
<a role="button" class="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div id="navbarBasicExample" class="navbar-menu">
<div class="navbar-end has-text-weight-semibold">
<a class="navbar-item">
Home
</a>
<a class="navbar-item">
About
</a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link">
Products
</a>
<div class="navbar-dropdown">
<a class="navbar-item">
BusinessWallTattoo
</a>
<a class="navbar-item">
WallTattoo
</a>
<a class="navbar-item">
BusinessTattoo
</a>
<hr class="navbar-divider">
<a class="navbar-item">
Customized request
</a>
</div>
</div>
<a class="navbar-item">
Blog
</a>
</div>
</div>
</nav>
For the dropdown this javascript will do the functionality and set the active element:
<script>
document.addEventListener('DOMContentLoaded', () => {
// Get all "navbar-burger" elements
const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);
// Check if there are any navbar burgers
if ($navbarBurgers.length > 0) {
// Add a click event on each of them
$navbarBurgers.forEach( el => {
el.addEventListener('click', () => {
// Get the target from the "data-target" attribute
const target = el.dataset.target;
const $target = document.getElementById(target);
// Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
el.classList.toggle('is-active');
$target.classList.toggle('is-active');
});
});
}
});
</script>
Let’s build a hero with flexbox with 3 or more columns. The pattern is:
columns
column
column
column
...
Here is the code:
<section class="hero">
<div class="hero-body">
<div class="container">
<div class="columns">
<div class="column">
<figure class="image">
<img src="assets/images/tuscan-valley.png" alt="Image">
</figure>
</div>
<div class="column">
<figure class="image">
<img src="assets/images/tuscan-valley.png" alt="Image">
</figure>
</div>
<div class="column">
<figure class="image">
<img src="assets/images/tuscan-valley.png" alt="Image">
</figure>
</div>
</div>
</div>
</div>
</section>
The container has to purpose to coagulate the page on the center instead of overflowing over all page width.
<section class="hero">
<div class="hero-body">
<div class="container">
<div class="columns is-vcentered">
<div class="column">
<figure class="image">
<img src="assets/images/myface.png">
</figure>
</div>
<div class="column">
<h1 class="title titled is-1 mb-6">
Hello!.
</h1>
<h3 class="is-2 is-size-3 mb-6">
This is a sample text.
</h3>
<div class="buttons">
<button class="button is-warning is-large is-uppercase has-text-weight-semibold">How do we work</button>
</div>
</div>
</div>
</div>
</div>
</section>
Various labels are easy to remember and are extremely useful. They are either prefixed with is- or has- following by a very intuitive name.
Worth mentioning is the fact tags h1…h6 are being reset, in term of default styling thus is-1 is necessary to style its markup to a big size text.
mb-6
has to meaning of spacing middle bottom with size factor 6. Button labels set a customize shape. No css styling is needed.
The following piece of code is set in full width with text centered.
<div class="container is-widescreen has-text-centered my-6 ">
<h3 class="is-1"><strong>SO GLAD YOU’RE HERE!</strong> Pick an option below to get started:</h3>
</div>
<section class="hero">
<div class="hero-body">
<div class="container">
<div class="columns is-1-mobile is-3-desktop">
<!-- HERO SECONDARY 1ST COLUMN -->
<div class="column">
<div class="card">
<div class="card-image">
<figure class="image">
<img src="assets/images/map_bruxelles_mur.png" alt="Placeholder image">
</figure>
</div>
<div class="card-content">
<div class="content">
<h2 class="is-1">WallTattoo for Business</h2>
<p>Do you have a business place with walls? The art applied directly on the walls will make your place unforgettable.</p>
<a href="#" class="button is-warning is-medium is-uppercase has-text-weight-semibold">Find more</a>
</div>
</div>
</div>
</div>
<!-- HERO SECONDARY 2ND COLUMN -->
<div class="column">
<div class="card">
<div class="card-image">
<figure class="image">
<img src="assets/images/map_bruxelles_mur.png" alt="Placeholder image">
</figure>
</div>
<div class="card-content">
<div class="content">
<h2 class="is-2">WallTattoo for Business</h2>
<p>Do you have a business place with walls? The art applied directly on the walls will make your place unforgettable.</p>
<a href="#" class="button is-warning is-medium is-uppercase has-text-weight-semibold">Find more</a>
</div>
</div>
</div>
</div>
<!-- HERO SECONDARY 3RD COLUMN -->
<div class="column">
<div class="card">
<div class="card-image">
<figure class="image">
<img src="assets/images/map_bruxelles_mur.png" alt="Placeholder image">
</figure>
</div>
<div class="card-content">
<div class="content">
<h2 class="is-2">WallTattoo for Business</h2>
<p>Do you have a business place with walls? The art applied directly on the walls will make your place unforgettable.</p>
<a href="#" class="button is-warning is-medium is-uppercase has-text-weight-semibold">Find more</a>
</div>
</div>
</div>
</div>
</div> <!-- columns-->
</div>
</div>
</section>
<section class="hero">
<div class="hero-body">
<div class="container">
<div class="columns is-1-mobile is-2-desktop is-vcentered">
<div class="column">
<div class="box">
<article class="media">
<div class="media-left">
<figure class="image">
<img src="assets/images/louise-cat.png" alt="Image">
</figure>
</div>
<div class="media-content">
<div class="content">
<a href="#" class="button is-warning is-medium is-uppercase has-text-weight-semibold">shop</a>
</div>
</div>
</article>
</div>
</div>
<div class="column">
<div class="box">
<article class="media">
<div class="media-left">
<figure class="image">
<img src="assets/images/covrig.png" alt="Image">
</figure>
</div>
<div class="media-content">
<div class="content">
<a href="#" class="button is-warning is-medium is-uppercase has-text-weight-semibold">portfolio</a>
</div>
</div>
</article>
</div>
</div>
</div>
</div></div></div>
</section>
The footer has set levels which are small horizontal pouches. I used the fontawesome to have ready shaped social network icons.
<footer class="footer">
<div class="content has-text-centered">
<nav class="level">
<!-- Left side -->
<div class="level-left">
<div class="level-item">
Copyright 2020 <img src="assets/images/watermark.png">
</div>
<div class="level-item">
<a href="#">Terms of Use</a>
</div>
<div class="level-item">
<a href="#">Privacy Policy</a>
</div>
</div>
<!-- Right side -->
<div class="level-right">
<p class="level-item"><a href="#"><span class="icon">
<i class="fab fa-circle fa-2x fa-instagram"></i></span></a></p>
<p class="level-item"><a href="#"><span class="icon"><i class="fab fa-circle fa-2x fa-linkedin"></i></span></a></p>
<p class="level-item"><a href="#"><span class="icon"><i class="fab fa-circle fa-2x fa-pinterest"></i></span></a></p>
<p class="level-item"><a href="#"><span class="icon"><i class="fab fa-circle fa-2x fa-youtube"></i></span></a></p>
<p class="level-item"><a href="#"><span class="icon"><i class="fab fa-circle fa-2x fa-twitter"></i></span></a></p>
</div>
</nav>
</div>
</footer>
APPENDIX Alterntively, get started with bulma-start package
bulma-start is a tiny npm package that includes the npm
dependencies you need to build your own website with Bulma.
npm install bulma-start
or yarn add bulma-start
.
Now, that you prepared the groundwork for your project, set up Bulma and run the watchers:
npm install
npm start
Use npm run
to show all available commands:
Lifecycle scripts included in bulma-start:
available via `npm run-script`:
css-build
node-sass _sass/main.scss css/main.css
css-deploy
npm run css-build && npm run css-postcss
css-postcss
postcss --use autoprefixer --output css/main.css css/main.css
css-watch
npm run css-build -- --watch
deploy
npm run css-deploy && npm run js-build
js-build
babel _javascript --out-dir lib
js-watch
npm run js-build -- --watch