Build a Multi-Page Business Website

Build a Professional Multi-Page Business Website | No Frameworks

Advertisements

In this tutorial, you’ll build a fully functional, multi-page business website using only HTML and modern CSS — no frameworks, no JavaScript libraries. We’ll add the About, Services, and Contact pages to the homepage we built in Part 1, creating a complete website that real businesses can launch immediately.

In Part 1, we built a polished homepage — index.html — with a hero section, services overview, and a “Why Choose Us” layout. That homepage exists as a single file. But a real business website needs multiple pages: one to tell the company’s story (About), one to detail its offerings (Services), and one so visitors can get in touch (Contact).

Section 1: Building the Multi-Page Site Architecture

This section covers the architecture of that expansion. Before writing a single line of content for those pages, we need to get the structure right — the folder layout, the file naming, and how every page uses the same navigation and footer without duplicating code.

This is important because browsers serve files, not applications. When a user clicks “About” in your nav bar, the browser literally loads a different file. Getting your folder structure and relative paths right from the start prevents broken links, missing stylesheets, and hours of debugging later.


Step 1: Setting Up the Multi-Page Folder Structure

Your project folder from Part 1 should already look something like this: Business-site (the root folder) with index.html file, then css folder with styles.css file, and images folder with hero-bg.jpg, and why-choose-us.jpg files.

We are going to extend this — not restructure it. The new HTML pages will stay in the project root folder as index.html.

Some tutorials place pages inside a /pages/ subfolder. We deliberately keep them in the root because it keeps all relative paths simple and predictable. The css/ and images/ paths will remain identical on every page. Moving pages into a subfolder adds ../ complexity with no real benefit for a small business site.

The Updated Folder Structure would now look like this:

  1. Business-site
    1. Index.html
    1. About.html
    1. Services.html
    1. Contact.html
    1. css/
      1. styles.css
    1. images/
      1. hero-bg.jpg
      1. why-choose-us.jpg
      1. about-team.jpg
      1. og-image.jpg

Let’s go ahead and create the three new HTML files now –  about.htmlservices.html, and contact.html – in the project root (business-site folder). Leave them empty for now. We will fill them in step by step. You can create them in VS Code as we did in part 1.


Step 2: Creating about.html, services.html, and contact.html

Copy and paste each of the following code in each of the new files we created in the project root – about.html, services.html, and contact.html files respectively.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Learn about Kmacims Web Solutions — our mission, values, and the team behind every project." />
<title>About Us | Kmacims Web Solutions</title>
<link rel="stylesheet" href="css/styles.css" />
</head>
<body>

<!-- Header will go here (Step 4 -->

<main>
<!-- About page content will go here (Section 2) -->
</main>

<!-- Footer will go here (Step 5) -->

</body>
</html>

<!-- services — Full Starter Template -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Explore the full range of web design, development, and consulting services offered by Kmacims Web Solutions." />
<title>Our Services | Kmacims Web Solutions</title>
<link rel="stylesheet" href="css/styles.css" />
</head>
<body>

<!-- Header will go here (Step 4) -->

<main>
<!-- Services page content will go here (Section 2) -->
</main>

<!-- Footer will go here (Step 5) -->

</body>
</html>

<!-- contact — Full Starter Template -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content=<="" span="" style="box-sizing: border-box; margin: 0px; padding: 0px;"> />
<meta name="description" content="Get in touch with Kmacims Web Solutions. We're ready to discuss your next web project." />
<title>Contact Us | Kmacims Web Solutions</title>
<link rel="stylesheet" href="css/styles.css" />
</head>
<body>

<!-- Header will go here (Step 4) -->

<main>
<!-- Contact page content will go here (Section 2) -->
</main>

<!-- Footer will go here (Step 5) -->

</body>
</html>

Every new page begins with the same HTML boilerplate we established in Part 1, with three important updates to the <head>: a page-specific <title>, a page-specific <meta name=”description”>, and (later in Section 6) page-specific Open Graph tags. The <link> to our shared stylesheet remains identical on every page.

Notice the consistent title pattern: Page Name | Brand Name. This is the industry-standard format.

Because browser tabs are narrow, showing the page name first tells users which tab is which. The brand name at the end provides consistent identity. Search engines display the title in results, so putting the most descriptive word first improves click-through rates.


Step 3: Understanding Relative Paths Across Pages

This is the most technically important concept in multi-page architecture and the most common source of broken links, missing styles, and broken images. Let’s get it right once and for all.

What Is a Relative Path?

relative path tells the browser where to find a file relative to the current page’s location. Since all our HTML pages live in the same root folder, their relative paths to shared resources (CSS, images, etc) are all identical.

In practice, because index.html, about.html, services.html, and contact.html all stay in the project root, they all reference the stylesheet with the exact same path: href=”css/styles.css”. And they all reference images like src=”images/hero-bg.jpg”.

Thus, when one page links to another, we use the filename directly as the href value. The browser resolves it relative to the current page’s location. Here is what the nav links will look like across all pages:

<a href="index.html">Home</a>
<a href="about.html">About</a>
<a href="services.html">Services</a>
<a href="contact.html">Contact</a>

Step 4: Building a Consistent Header and Navigation

In Part 1, our navigation bar linked to # (placeholder) – when you click on the page links, it does nothing. Now we connect every link to its real destination page. We also add an active state — a visual indicator showing which page the user is currently on. This is a key UX pattern for multi-page sites.

When a user lands on your About page, they should immediately see “About” highlighted in the navigation. This orientation cue reduces cognitive load and tells the user where they are without them having to read the page title. It also provides a secondary affordance confirming the link they clicked worked.

Since we are building with HTML and CSS only, we add the active state manually on each page using an aria-current=”page” attribute. This is the semantically correct, accessible way to indicate the current page. Screen readers announce it automatically, and we style it with CSS.

Copy the following HTML code and paste it in the <header> section of each of the pages, including the index.html page. For index.html, replace the existing header with this HTML code.

<!-- Updated Header — index.html (Home active) -->
<header>
<nav aria-label="Main navigation">
<a href="index.html" class="logo">Kmacims EAT</a>
<ul class="nav-links">
<li><a href="index.html" aria-current="page">Home</a></li>
<li><a href="about.html">About</a></li>
<li><a href="services.html">Services</a></li>
<li><a href="contact.html">Contact</a></li>
</ul>
</nav>
</header>

<!-- Header — about.html (About active) -->
<header>
<nav aria-label="Main navigation">
<a href="index.html" class="logo">Kmacims EAT</a>
<ul class="nav-links">
<li><a href="index.html">Home</a></li>
<li><a href="about.html" aria-current="page">About</a></li>
<li><a href="services.html">Services</a></li>
<li><a href="contact.html">Contact</a></li>
</ul>
</nav>
</header>

<!-- Header — services.html (Services active) -->
<header>
<nav aria-label="Main navigation">
<a href="index.html" class="logo">Kmacims EAT</a>
<ul class="nav-links">
<li><a href="index.html">Home</a></li>
<li><a href="about.html">About</a></li>
<li><a href="services.html" aria-current="page">Services</a></li>
<li><a href="contact.html">Contact</a></li>
</ul>
</nav>
</header>

<!-- Header — contact.html (Contact active) -->
contact.html — <header>
<header>
<nav aria-label="Main navigation">
<a href="index.html" class="logo">Kmacims EAT</a>
<ul class="nav-links">
<li><a href="index.html">Home</a></li>
<li><a href="about.html">About</a></li>
<li><a href="services.html">Services</a></li>
<li><a href="contact.html" aria-current="page">Contact</a></li>
</ul>
</nav>
</header>

The above header code has two major changes from the one used in Part 1.

First, the logo <div class=”logo”> is now an <a> tag with href=”index.html”. This makes it a clickable logo. A clickable logo is a universal web convention — users expect the logo to bring them home.

Second, the <nav> now has aria-label=”Main navigation”, which helps screen readers distinguish this nav from other navigation elements (like a footer nav) on the same page.


Step 5: Building a Consistent Footer Across All Pages

In Part 1 we built a minimal footer — a centred copyright line. We will use that same footer as a placeholder across all pages now, and upgrade it to a full multi-column layout in Section 5 of this tutorial. For consistency, every page should use the exact same footer markup.

Inconsistent footers are a common sign of amateur-built sites. Every page should have the same footer structure, the same links, and the same legal copy. It signals professionalism, ensures users can always find contact info or copyright notices no matter where they are, and helps search engines understand your site’s structure. Copy and paste this code in the footer section of all the pages, including index.html page.

<!-- Updated Footer for all pages -->
<footer class="site-footer">
<div class="footer-inner">
<p>&copy; 2026 Kmacims Web Solutions. All rights reserved.</p>
</div>
</footer>

You should notice two small but meaningful changes made to the code in Part 1.  Now, we added a class site-footer to the <footer> element and wrapped the content in a footer-inner div. Both classes give us hooks for the multi-column upgrade in Section 5 without breaking anything now.

Step 6: Updating the CSS to Support Shared Components

Now, let’s switch to the styles.css file. Open css/styles.css. We need to make three targeted updates: style the logo as a link (replacing the old .logo div style), add the active nav state, and add base styles for the new page components we’ll build throughout Part 2.

Update 1: Style the Logo Link

The logo is now an <a> tag. We need to remove the default link underline and give it the correct weight and colour so it looks great and clean.

Copy the code and paste it under the header styles immediately after .nav-links a.

/* Style logo as an anchor tag */
.logo {
text-decoration: none;
font-size: 1.25rem;
font-weight: 800;
color: var(--text-color);
letter-spacing: -0.02em;
}

Update 2: Active Navigation State

Add these rules after your existing .nav-links a styles. The [aria-current=”page”] selector targets any link with that attribute — no extra classes needed. Copy and paste the following code after the .logo styles.

/* Active page indicator */
.nav-links a[aria-current="page"] {
color: var(--primary-color);
font-weight: 600;
}

.nav-links a[aria-current="page"]::after {
width: 100%;
background: var(--primary-color);
}

Update 3: Shared Page Hero (or Page Banner)

The full-image hero from index.html is specific to the homepage. The inner pages (About, Services, Contact) each need a compact page-top banner — a simpler coloured block with the page title. We call this a page hero. Add these styles now; they’ll be ready when we build the content in Section 2.

Copy and paste this immediately after the hero section styles.

/* Page Banner used on About, Services, and Contact pages */
.page-hero {
background: linear-gradient(135deg, #1e3a8a 0%, var(--primary-color) 100%);
color: white;
padding: 4rem 1rem;
text-align: center;
}

.page-hero h1 {
font-size: clamp(1.75rem, 4vw, 2.75rem);
font-weight: 800;
margin-bottom: 0.75rem;
}

.page-hero p {
font-size: 1.1rem;
opacity: 0.88;
max-width: 600px;
margin: 0 auto;
}

Update 4: A Shared Content Container

Each inner page will have content sections that need consistent max-width and horizontal padding. Rather than repeating this on every section, we add a reusable .page-content container class.

/* Shared Page Content Container */
.page-content {
max-width: var(--max-width);
margin: 0 auto;
padding: 4rem 1rem;
}

Update 5: Footer Inner Class Add a base style for the .site-footer and .footer-inner classes we added to the footer markup. This keeps the current appearance identical to Part 1 while setting up for the full multi-column upgrade. Add the following styles to replace the old footer styles.

/* Updated Footer Styles */
.site-footer {
background: #111827;
color: white;
padding: 2rem 1rem;
}

.footer-inner {
max-width: var(--max-width);
margin: 0 auto;
text-align: center;
font-size: 0.9rem;
color: #9ca3af;
}

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top