This is a walk-through for styling your own static blog from scratch. We will be using Middleman for our framework and Bourbon, Neat, and Bitters for our Sass libraries.
Middleman is a lightweight static site framework built using Ruby. It compiles Markdown into HTML and is easily deployed to S3, Heroku, or GitHub Pages.
Middleman can also host a blog nicely like this blog.
The following steps will include instructions for installation, setup, deployment, and adding some very basic styles.
Installation
First, we install the Middleman gem and the blog extension gem. We can then initialize the project:
gem install middleman-blog
middleman init my_blog --template=blog --rack
Let’s start the server and take a look at what we’ve got:
cd my_blog
bundle exec middleman
open http://localhost:4567
You should see something like this in your browser:
Middleman gives us a default post and just the default styles, which is a great place to start.
Configuration
We’ll be doing a lot of browser refreshing to see our progress, so let’s automate the process. We can use the built-in Livereload service to auto-refresh the page whenever we save. Let’s add the gem:
In the Gemfile
:
# ...
group :development do
gem 'middleman-livereload'
end
And enable the service by uncommenting the configuration line:
In config.rb
:
# ...
configure :development do
activate :livereload
end
Livereload will begin working as soon as you run bundle
and restart your
server.
ctrl + c //shuts down Middleman server
bundle
bundle exec middleman
Prepare to Deploy
Our blog won’t run on Heroku as-is, but we only need to do a few things to change that.
First, we need to add some code to config.rb that will tell Middleman to put
the files Heroku needs in a folder named tmp
:
# ...
set :build_dir, 'tmp'
# ...
Next, we will create a file that tells Heroku how to build our source files. We
will create a file named Rakefile
in the root directory of our project and add
the code below:
The Rakefile
:
namespace :assets do
task :precompile do
sh "middleman build"
end
end
In config.ru
:
require 'rack/contrib/try_static'
use Rack::Deflater
use Rack::TryStatic,
root: 'tmp',
urls: %w[/],
try: %w[.html index.html /index.html]
FIVE_MINUTES=300
run lambda { |env|
[
404,
{
'Content-Type' => 'text/html',
'Cache-Control' => "public, max-age=#{FIVE_MINUTES}"
},
['File not found']
]
}
We’ll also need to include the rack-contrib
gem in our Gemfile
. Be sure to
bundle
and restart your server after this step.
The Gemfile
:
gem 'rack-contrib'
The final step is initializing Git, which we will do next.
Initialize Git
To be able to track our changes and push our blog to Heroku, we need to initialize a Git repo.
git init
git add .
git commit -m 'initial commit'
To commit changes as we continue to work, we’ll run git add .
to track new
files and stage changes to files already being tracked. Then we can run git
commit -m 'your commit message'
and we’ll be able to push our latest changes
to the remote.
It’s a good idea to commit changes to git at the end of each section of this post.
We’ll be using Heroku as a remote repository.
It would be beneficial to also set up a remote like GitHub for remote version tracking, but it’s not necessary.
We’ll just focus on Heroku for now. If you don’t already have a Heroku account,
you’ll need to sign up for one before running heroku create
.
heroku create
git push heroku master
And now, we can run heroku open
in the terminal to open the page in our
browser. We’ve just created a blog and pushed it live. Next is to add our own
styles to customize the design.
Install Libraries
Our goal is to add a custom design to this blog, so let’s install our Sass
toolkit and bundle
:
The Gemfile
:
gem 'bitters'
gem 'bourbon'
gem 'neat'
Bourbon is a library of vanilla Sass mixins, Neat gives us a responsive grid system, and Bitters sets default styles for Bourbon projects. These gems will make the assets available to our site through Middleman’s asset pipeline.
Since we’ve updated our Gemfile, we’ll need to bundle
and restart our server
again.
Bourbon and Neat are included by the gem, but Bitters requires an additional install in your stylesheets folder:
$ cd source/stylesheets
$ bitters install
Bitters files installed to /base
Next, we need to create a stylesheet manifest with the correct character encoding and import our design libraries:
In source/stylesheets/all.css.scss
:
@charset "utf-8";
@import "bourbon";
@import "base/base"; /* Bitters needs to be imported before Neat */
@import "neat";
Include all of the stylesheets to be used in this site by adding the link to
the manifest in the <head>
section of layout.erb
:
In source/layout.erb
:
<head>
<%= stylesheet_link_tag "all" %>
Let’s see how it looks now:
Already, we see improvement. What did Bitters just set up for us?
- Typography - Uses Helvetica as default font-family and sets the sizes for
various header elements on a modular scale (e.g.
<h1>
‘s and family) - Color - uses variables to systematize colors.
- Lists - strips all styles from lists including bullets
- Flash notice styles - very useful in Rails
- Grid settings to accompany Neat
- Some basic form styles
Get Stylish
We’ll need to customize a few things in Bitters to optimize our styles for a
blog. First, let’s add our own Google font to layout.erb
:
In source/layout.erb
:
<head>
...
<link href='http://fonts.googleapis.com/css?family=Oxygen:400,300,700'
rel='stylesheet' type='text/css'>
...
</head>
To make use of this font, all we need to do is change the $sans-serif
variable in _variables.scss
:
In source/stylesheets/base/_variables.scss
:
$sans-serif: 'Oxygen', $helvetica;
By changing the $sans-serif
variable, we’ve quickly and easily changed the
font family globally.
Comfortable Reading
Let’s create a partial that will contain all of the layout related styles. We’ll need to import it in our manifest:
In source/stylesheets/all.css.scss
:
@import "partials/layout";
Add the outer-container()
mixin to the layout to center it in the viewport.
In source/stylesheets/partials/_layout.scss
:
#main {
@include outer-container;
}
For a good reading experience, we want to keep the length of the lines of text a comfortable length. If the lines are too long, the reader will have a hard time following the flow of the text.
Neat makes this easy to accomplish in as little as two steps. We’ll adjust the
max-width
property of the outer-container()
mixin.
The first step will be to import _grid-settings.scss
into Bitters. We
can just uncomment that line in _base.scss
:
In source/stylesheets/base/_base.scss
:
@import "grid-settings";
The second step is to edit _grid-settings.scss
. Uncomment the $max-width
variable and change its value to em(700)
. This should give us a comfortable
line-length for reading.
In source/stylesheets/base/_grid-settings.scss
:
$max-width: em(700);
Let’s see what our blog looks like now that we’ve added a few styles of our own:
We see that Bitters has successfully applied our chosen font and centered our content. Don’t worry about some of the content being misaligned. We’re about to fix that.
Modular Structure
Our readers need to be able to easily move around the site, so we’ll add some helpful links in a navigation and footer.
To keep our code modular, we will break up the navigation and footer into separate partials. It’s good practice to make a folder to keep your partials in.
We’ll edit a group of new files:
- source/partials/_nav.erb
- source/partials/_footer.erb
- source/stylesheets/partials/_nav.scss
- source/stylesheets/partials/_footer.scss
Now that we’ve added some structure to our code we can import these partials
into layout.erb
and our Sass partials into all.css.scss
.
In source/layout.erb
<div id="main" role="main">
<%= partial "partials/nav" %>
<%= yield %>
<%= partial "partials/footer" %>
</div>
Improved Markup
We are ready to improve the overall layout of our index page. A few small adjustments to the markup will make it more semantic and easier to style.
Paste the code below into _nav.erb
:
In source/_nav.erb
:
<nav>
<ul>
<li>
<%= link_to "Blog Title", "index.html", :class => 'blog-title' %>
</li>
</ul>
</nav>
We will move some of the content from layout.erb
into the footer. Paste the
code below into _footer.erb
and remove it from layout.erb
:
In source/_footer.erb
:
<footer>
<ul class="large-column">
<li><h5 class="heading">Recent Articles</h5></li>
<li>
<ol>
<% blog.articles[0...10].each do |article| %>
<li>
<%= link_to article.title, article %>
<span><%= article.date.strftime('%b %e') %></span>
</li>
<% end %>
</ol>
</li>
</ul>
<ul class="small-column">
<li><h5 class="heading">Tags</h5></li>
<li>
<ol>
<% blog.tags.each do |tag, articles| %>
<li><%= link_to "#{tag} (#{articles.size})", tag_path(tag) %></li>
<% end %>
</ol>
</li>
<ul>
</footer>
Additionally, we’ll improve the markup in index.html.erb
:
In source/index.html.erb
:
<ul>
<% page_articles.each_with_index do |article, i| %>
<li>
<h3><%= link_to article.title, article %></h3>
<h5><%= article.date.strftime('%b %e') %></h5>
<p><%= article.body %></p>
</li>
<% end %>
</ul>
Adding Custom Styles
As a finishing touch, we’ll add some custom styles to our navigation, footer, and layout: For consistency, we will also create Sass partials for the nav and the footer.
In source/stylesheets/all.css.scss
:
@import "partials/nav";
@import "partials/footer";
In source/stylesheets/partials/_nav.scss
:
nav {
border-bottom: 1px solid $base-border-color;
margin: em(30) 0;
ul {
display: inline-block;
margin-bottom: em(10);
}
}
.blog-title {
font-size: 1.4em;
font-weight: 700;
letterspacing: 4px;
text-transform: uppercase;
}
In source/stylesheets/partials/_footer.scss
:
footer {
border-top: 1px solid $base-border-color;
margin: 2em 0;
padding-top: 2em;
}
Some styles are providing a style pattern we’ll use throughout the blog. We’ll
place these styles in the _layout.scss
stylesheet since they create a
reusable layout pattern.
In source/stylesheets/partials/_layout.scss
:
ol {
font-size: 1em;
font-weight: 500;
li {
margin: .5em 0;
span {
display: inline-block;
&:before {
content: '/';
margin: 0 .3em;
}
}
}
}
Using the mixin @include span-columns()
, Neat will calculate the width of the
div based on the number of columns you specify in the argument.
In source/stylesheets/partials/_layout.scss
.large-column {
@include span-columns(8 of 12);
}
.small-column {
@include span-columns(4 of 12);
}
Now we have a basic template set up for our very own blog.
All that’s left to do is make sure all of our changes have been committed to Git and then deploy these updates to Heroku.
git push heroku master
Completion
Now we have a good foundation upon which to publish our own blog.