# Creating the base template and navbar

Let's get started by creating a base template for all our other templates.

In our base template, we'll link the CSS file and add the navigation bar. Then we'll use a Jinja block to define where child templates may include their content:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta name="viewport" content="width=device-width">
    <title>Bob Smith | Portfolio</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Lato:[email protected];700&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}" />
</head>

<body>
    <header class="header">
        <h1>Bob Smith</h1>

        <nav class="nav">
            <a href="{{ url_for('home') }}" class="nav__link">
                Projects
            </a>
            <a href="{{ url_for('about') }}" class="nav__link">
                About
            </a>
            <a href="{{ url_for('contact') }}" class="nav__link">
                Contact
            </a>
        </nav>
    </header>

    {% block content %}
    {% endblock %}
</body>

</html>

Let's look at some of this base template in detail.

# Loading fonts

In the template we've got this code:

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lato:[email protected];700&display=swap" rel="stylesheet">

This is copy-pasted from Google Fonts when you select a certain font and font family that you want to use in your application. This just loads a font from their servers so your users' browser will download it.

Then in our CSS we can make use of the font.

All the navigation in the navbar is using the url_for function, which generates a relative URL path to the appropriate endpoint.

Remember that using url_for is better than hardcoding endpoints and makes it easier to pass in arguments should the endpoint need any!

# Highlighting the currently active page

There's one more thing we can do in the navbar, which is to highlight the currently active page.

For example, if we're in the "Contact" page, it would be good if the navbar showed that. That way users can more easily tell where in the site they currently are.

To highlight the current page, all we have to do is give the link that sends us to the current page a special class.

<nav class="nav">
    <a href="{{ url_for('home') }}" class="nav__link {{ 'nav__link--active' if request.path == url_for('home') }}">
        Projects
    </a>
    <a href="{{ url_for('about') }}" class="nav__link {{ 'nav__link--active' if request.path == url_for('about') }}">
        About
    </a>
    <a href="{{ url_for('contact') }}" class="nav__link {{ 'nav__link--active' if request.path == url_for('contact') }}">
        Contact
    </a>
</nav>

With Jinja, we can do this:

{{ 'nav__link--active' if request.path == url_for('contact') }}

Which will return 'nav__link--active if the current path in the user's browser is equal to what is generated by the url_for function.

I.e. if the user is currently in the "contact" page, we will give the Contact link a class of nav__link--active (in addition to the nav__link class that all links in the navbar have).

# The CSS for navbar and base template

We'll start by setting the box-sizing to border-box, as we basically should always do.

Then we can set the font family to "Lato". If it's not available, we'll fall back to "sans-serif", which is the default system sans-serif font.

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  font-family: Lato, "sans-serif";
}

body {
  margin-top: 80px;
}

.header {
  text-align: center;
}

.nav {
  margin-bottom: 3rem;
  font-size: 1.2rem;
}

.nav__link {
  text-decoration: none;
  color: #1c2023;
}

.nav__link:not(:last-of-type) {
  margin-right: 2.5rem;
}

.nav__link--active,
.nav__link:hover {
  font-weight: bold;
}

The :not(:last-of-type) selector will give us all the elements with .nav__link class, except the last one within a single parent[1].

We give those elements a margin-right but not the last one, so that the last one isn't too separated from the side of the screen.


  1. :last-of-type (MDN Documentation) (opens new window) ↩ī¸Ž