Home About Me

Rebuilding Milligram’s Navigation Bar by Hand, One Step at a Time

A while ago, someone in a chat group recommended a CSS framework called Milligram. It’s tiny—only 2kb gzipped—so I took a look.

My first impression was good: lightweight, clean, and visually simple in a way that feels very deliberate. The navigation bar on the homepage especially caught my attention. I liked the click effect, and I wanted to study how it was built.

Over the past couple of days I’ve been reflecting on my own front-end basics, and honestly my self-assessment is: weak, weak, weak.

I’ve learned a lot of individual concepts, but when it comes to actually applying them, I often don’t know where to start. Even when I manage to build the effect I want, the result still feels messy. It works—but the code looks chaotic.

The nice thing about front-end work is that good examples are right there in the browser. If I come across a site that looks well made, I can open Chrome DevTools, inspect it piece by piece, and learn by imitating it. That turns out to be a pretty efficient way to study. I’ve also discovered that unchecking CSS rules in the inspector and watching the page change is strangely satisfying.

So this time I decided to rebuild the navigation based on what I saw, step by step.

milligram

This is a classic horizontal navigation layout: logo on the left, links on the right. You see this pattern everywhere—homepages, documentation sites, product pages. It’s simple, but there’s a lot to learn from how cleanly it’s put together.

milligram

The page uses HTML5 structure throughout. Most of the content is wrapped in a main element, and the top navigation sits inside a nav. Inside that nav, instead of putting everything directly in place, there’s a section element acting as the inner container.

I remember seeing people advise against styling section directly when learning HTML5, but in this case it works fine. Adding another div just for structure would make the markup feel heavier than necessary.

Inside the section, the content is split into two parts:

  • a logo link on the left
  • a list of navigation links on the right

The logo area is a clickable a element containing an img for the logo and an h1 for the site title. The links on the right are organized with ul and li.

Building it from scratch

Since the goal here is to strengthen the basics, I wanted to type everything out manually instead of copying and pasting blindly. That makes it much easier to understand what each property is doing.

Without any CSS, the page is just structure. That old distinction—HTML for content, CSS for presentation, JavaScript for behavior—feels much more real when you actually strip everything down and build upward again.

Template

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <link rel="stylesheet" href="http://fonts.useso.com/css?family=Roboto:300,300italic,700,700italic">
  <link rel="stylesheet" href="http://cdn.bootcss.com/normalize/3.0.3/normalize.min.css">
  <!-- <link rel="stylesheet" href="/css/milligram.min.css"> -->
  <link rel="stylesheet" href="/css/style.css">
</head>
<body>
  <main class="wrapper">
    <nav class="navigation">
      <section class="container">
        <a class="navigation-title" href="#">
          <img class="img" height="30px" src="/imgs/hexo.png">
          <h1 class="title">Hello</h1>
        </a>
        <ul class="navigation-list float-right">
          <li class="navigation-item">
            <a class="navigation-link" href="#">Docs</a>
          </li>
          <li class="navigation-item">
            <a class="navigation-link" href="#">Login</a>
          </li>
        </ul>
      </section>
    </nav>
  </main>
</body>
</html>

That’s the HTML. In style.css, I started adding styles bit by bit.

The page uses a Google Fonts CDN mirror from useso, along with normalize.css from BootCDN. normalize.css helps browsers render elements more consistently and brings things closer to modern standards, so it makes sense to include it early.

As for Milligram itself, I left it commented out at first. Since the goal was to study the layout from the ground up, its default styles would only interfere with the first pass.

With only the HTML in place, the page looks like this:

milligram


First, draw the navigation frame

Before worrying about precise alignment, I started by building the outer shape of the navigation bar.

style.css

html {
  font-size: 62.5%;
}

body {
  font-size: 1.6em;
}

.navigation {
  background: #f4f5f6;
  border-bottom: .1rem solid #d1d1d1;
  height: 5.2rem;
  width: 100%;
}

The first two rules establish a rem baseline. With this setup, the body text ends up at 16px.

In .navigation, I set the bar’s height and width, then added a light bottom border and background color. That’s enough to make the outer navigation area visible.

Result:

milligram

Make the title and list sit in the same line

The title uses an h1, and the menu is a ul. Both are block-level elements by default, so naturally they don’t line up the way a horizontal navigation needs them to.

To fix that, I changed their display behavior:

.navigation .title {
  display: inline;
 }

.navigation-list {
  display: inline;
  float: right;
}

Using float pushes the list to the right. At this point, all the elements are at least inside the navigation bar.

milligram

Bring Milligram back in

Next I uncommented the Milligram stylesheet in index.html and removed float: right; from the custom CSS, because the HTML already includes the float-right class, and Milligram defines that utility for us.

After doing that, the layout suddenly changed:

milligram

The list moved out again, and both the logo area and the link area seemed to pull inward toward the center. The list issue can wait a moment—the first thing worth checking is the .container class defined by Milligram.

Its defaults look like this:

.container {
  box-sizing: border-box;
  margin: 0 auto;
  max-width: 112rem;
  padding: 0 2rem;
  position: relative;
  width: 100%;
}

Here, margin: 0 auto centers the element, and max-width: 112rem limits how wide it can become. That explains why the content looks pulled inward.

To better match the layout I wanted, I overrode the maximum width in my own stylesheet:

max-width: 80.0rem;

Once that was set, I could start fine-tuning the logo area.

Adjust the logo and title

The title needed to be smaller. The color needed to match the original style more closely. The logo image also had to be scaled down and aligned vertically with the text.

.navigation .title, .navigation-title {
  color: #606c76;
  font-family: 'Gotham Rounded A', 'Gotham Rounded B', 'Helvetica Neue', Arial, sans-serif;
  display: inline;
  font-size: 1.6rem;
  line-height: 5.2rem;

}

.navigation .img {
  position: relative;
  top: 0.4rem;
  height: 2.0rem;
}

Result:

milligram

The text is vertically centered with line-height, while the image is nudged into place using relative positioning.

Turn the right-side links into a horizontal menu

The last step is styling the list itself.

.navigation-list {
  display: inline;
  list-style: none;
  margin-bottom: 0;
}

.navigation-item {
  float: left;
  margin-left: 2.5rem;
  margin-bottom: 0;
}

.navigation-link {
  line-height: 5.2rem;
}

A few important things are happening here:

  • list-style: none; removes the default bullets from the ul
  • the earlier “overflow” feeling came from floating only the ul to the right while the li items still behaved like a vertical list
  • once .navigation-item is also floated, the list items line up horizontally
  • setting the same line-height on .navigation-link centers the links vertically inside the bar

That’s enough to produce a clean, simple navigation bar.

milligram

Complete CSS

html {
  font-size: 62.5%;
}

body {
  font-size: 1.6em;
}

.navigation {
  background: #f4f5f6;
  border-bottom: .1rem solid #d1d1d1;
  height: 5.2rem;
  width: 100%;
}

.container {
  max-width: 80.0rem;
}

.navigation .title, .navigation-title {
  color: #606c76;
  font-family: 'Gotham Rounded A', 'Gotham Rounded B', 'Helvetica Neue', Arial, sans-serif;
  display: inline;
  font-size: 1.6rem;
  line-height: 5.2rem;

}

.navigation .img {
  position: relative;
  top: 0.4rem;
  height: 2.0rem;
}

.navigation-list {
  display: inline;
  list-style: none;
  margin-bottom: 0;
}

.navigation-item {
  float: left;
  margin-left: 2.5rem;
  margin-bottom: 0;
}

.navigation-link {
  line-height: 5.2rem;
}

Typing it all out by hand made the structure much clearer.

A navigation bar like this isn’t nearly as intimidating as it first seems. Most of the difficulty comes from not being familiar enough with a few basic CSS behaviors—block elements, floats, line-height, container width, and default list styling.

The click interaction on Milligram’s navigation is also really nice, so the next thing worth digging into would be the JavaScript behind that behavior.