# Creating the base template and navbar
TIP
List of all code changes made in this lecture: https://diff-store.com/diff/section12__03_base_template_and_nav_bar (opens new window)
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:wght@400;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:wght@400;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.
# Navigation in the navbar
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.