Building consistent, accessible, and connected multi-page websites — shared structure, working navigation, and relative paths that hold together
Until now, most of your work has lived on a single page. You have built good HTML structure, added CSS styling, and made pages interactive with JavaScript. But real websites are not single pages. They are systems of connected pages that share common structure, consistent navigation, and a unified visual identity.
In this chapter, you will move from building individual pages to building small multi-page sites. You will learn how headers, footers, and navigation menus work across an entire site, how to manage relative paths in folders, how to mark the current page in a navigation menu, and how to keep shared sections consistent without a framework. By the end of this chapter, you will be able to plan, build, and link a small multi-page website with shared structure and working navigation.
Open any well-built website and click through five or six pages. The header stays in the same place. The navigation menu lists the same links in the same order. The footer looks identical from page to page. Only the content in the middle changes. How does a site built from separate HTML files manage to feel like one continuous place, rather than five or six unrelated documents? By the end of this chapter, you will know exactly how — and you will have built a five-page site that does it correctly.
By the end of this chapter, you should be able to:
aria-current attribute, and a JavaScript-based approach.aria-current.When you open a website and click through different pages, something stays the same and something changes. The header at the top stays. The navigation stays. The footer stays. What changes is the main content in the middle. That pattern is not a coincidence. It is an intentional design decision that developers make on purpose.
A multi-page site is a collection of HTML files linked together through navigation. Each file is a separate web page. The pages share a visual identity and structure, but each page has its own content.
Think about the Student Learning Site you have been building throughout this course. It has several planned pages:
index.html ← Home
about.html ← About
lessons.html ← Lessons
resources.html ← Resources
contact.html ← Contact
Each of these is a separate HTML file. Each file needs a proper document skeleton, its own <title>, its own <main> content, and links to the shared CSS stylesheet. But each page also needs a header and navigation menu that looks and works the same across every page. That is the central challenge of multi-page development without a framework: keeping things consistent when each page is its own file.
Imagine navigating a website where the header was in a different place on every page, the navigation links were in a different order, and the footer used different fonts. Even if the design was attractive, the site would feel disorienting and untrustworthy. Users depend on consistent structure to know where they are and where they can go. Designers depend on consistent structure to build a recognizable visual identity.
Consistency also matters for maintenance. If your navigation is copied into ten different HTML files and you add a new page to the site, you need to update ten files. If your CSS is organized carefully and you keep your HTML structure clean, updates become manageable.
Over the sections that follow, you will build a complete five-page site with a consistent shared header and site logo; a navigation menu that marks the current active page; a consistent footer with contact information and links; properly organized folders and working relative paths; a breadcrumb system for deeper pages; and clean, readable CSS that keeps the site maintainable. Every skill you practice here applies directly to every multi-page website you build in the future.
A header is the section at the top of every page that identifies the site. It typically contains the site name or logo, the main navigation, and sometimes a tagline or utility links. In HTML, the <header> element marks this content.
You first met <header> in Chapter 6. On a multi-page site, the <header> at the top of the <body> is the site header, not a section header buried inside an article. The site header should appear on every page and contain identical or near-identical content.
Here is a typical site header:
<header class="site-header">
<div class="header-inner">
<a href="index.html" class="site-logo">
<img src="images/logo.png" alt="Student Learning Site">
</a>
<nav class="main-nav" aria-label="Main navigation">
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="about.html">About</a></li>
<li><a href="lessons.html">Lessons</a></li>
<li><a href="resources.html">Resources</a></li>
<li><a href="contact.html">Contact</a></li>
</ul>
</nav>
</div>
</header>
Notice several things about this header. The logo is wrapped in an anchor link pointing to index.html. This follows the convention that clicking the site logo returns the user to the home page — it is so common that users expect it.
The <nav> has an aria-label attribute with the value "Main navigation". This label helps screen readers distinguish the main navigation from other navigation elements that might appear elsewhere on the page, such as a footer navigation or a sidebar navigation.
The navigation links are written as an unordered list. This is correct semantic HTML. A list of links is literally a list — do not skip the list markup to save a few lines of code. The list structure communicates meaning.
The paths are relative: index.html, about.html, and so on. This works as long as all pages are in the same folder. Section 26.7 discusses how paths change when pages are in subfolders.
If your logo is an image, the alt text should give the name of the site. The alt text does not need to say "logo." Screen readers already identify images as images. Write alt="Student Learning Site", not alt="Student Learning Site logo image".
If the logo is text rendered in a custom font using CSS, you can use an <a> element wrapping plain text, and you do not need an image at all. CSS-rendered text is accessible by default and scales well across screen sizes.
<a href="index.html" class="site-logo">Student Learning Site</a>
Then style the .site-logo class in CSS to use a custom font, a particular size, and whatever visual treatment fits your design. This approach keeps the site name in the HTML where it belongs.
Here is foundational CSS for a clean, responsive site header:
.site-header {
background-color: var(--color-primary);
color: var(--color-white);
padding: var(--space-md) 0;
}
.header-inner {
max-width: 1100px;
margin: 0 auto;
padding: 0 var(--space-md);
display: flex;
align-items: center;
justify-content: space-between;
}
.site-logo {
font-size: 1.4rem;
font-weight: 700;
color: var(--color-white);
text-decoration: none;
}
.site-logo:hover {
color: var(--color-accent);
}
The max-width and margin: 0 auto on .header-inner centers the content and prevents it from stretching too wide on large screens. The display: flex and justify-content: space-between push the logo to the left and the navigation to the right. This is one of the most common header layout patterns on the web.
When a user is on the About page, the About link in the navigation should look different from the other links. This is called an active navigation state. It tells the user where they are in the site. Without it, navigation loses an important wayfinding signal.
The active state is a CSS class, typically named .active or .current, applied to the navigation link that corresponds to the current page. In the HTML for about.html, the navigation would look like this:
<nav class="main-nav" aria-label="Main navigation">
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="about.html" class="active" aria-current="page">About</a></li>
<li><a href="lessons.html">Lessons</a></li>
<li><a href="resources.html">Resources</a></li>
<li><a href="contact.html">Contact</a></li>
</ul>
</nav>
Notice two things. First, the .active class is added to the link for the current page. Second, aria-current="page" is added to the same link. The aria-current attribute is an accessibility attribute. It communicates to screen readers that this link represents the page currently being viewed. Use both the visual CSS class and aria-current together.
.main-nav a.active,
.main-nav a[aria-current="page"] {
background-color: var(--color-primary-dark);
color: var(--color-white);
border-bottom: 3px solid var(--color-accent);
}
On a static site where each page is a separate HTML file, you must manually add the .active class and aria-current attribute to the correct link on each page. This means the navigation HTML on about.html is slightly different from the navigation HTML on lessons.html. This is one of the real maintenance costs of static multi-page sites without a template system.
There are three approaches to managing this:
href and add the .active class dynamically. This means all pages share identical navigation HTML, and JavaScript handles the active state at page load.For the Student Learning Site, Approach 2 is recommended. It keeps your HTML clean, your navigation consistent, and your JavaScript skills in practice.
function setActiveNavLink() {
const currentPage = window.location.pathname.split('/').pop() || 'index.html';
const navLinks = document.querySelectorAll('.main-nav a');
navLinks.forEach(function(link) {
const linkPage = link.getAttribute('href').split('/').pop();
if (linkPage === currentPage) {
link.classList.add('active');
link.setAttribute('aria-current', 'page');
}
});
}
setActiveNavLink();
Place this function in your main.js file. It runs when the page loads, finds the link whose href matches the current filename, and adds the .active class and aria-current attribute automatically. This is a clean, practical solution for a small static site.
A breadcrumb is a secondary navigation element that shows the user's current location within the hierarchy of the site. Breadcrumbs look like this:
Home › Lessons › Lesson 3: The Box Model
Each item except the last is a link. The last item is the current page, shown as plain text. Breadcrumbs answer the question: "How did I get here, and how do I get back?"
Breadcrumbs are most useful on sites with more than two levels of hierarchy. If your site has a lessons/ folder with individual lesson pages inside it, breadcrumbs help users navigate back to the lessons index or to the home page. On a flat site where all pages are at the same level, breadcrumbs add little value.
The Student Learning Site has a relatively flat structure. But if you added individual lesson pages like lessons/lesson-01.html, lessons/lesson-02.html, and so on, breadcrumbs would become useful on those detail pages.
Breadcrumbs use an ordered list inside a <nav> element with an appropriate aria-label. The current page should be marked with aria-current="page".
<nav class="breadcrumbs" aria-label="Breadcrumb">
<ol>
<li><a href="../../index.html">Home</a></li>
<li><a href="../lessons.html">Lessons</a></li>
<li aria-current="page">Lesson 3: The Box Model</li>
</ol>
</nav>
Using an ordered list <ol> is correct here because breadcrumbs have an explicit order: they represent a path, not an arbitrary collection. The reason the paths use ../../ is that this page is two folders deep — see Section 26.7 for the full explanation.
.breadcrumbs {
padding: var(--space-sm) 0;
font-size: 0.875rem;
color: var(--color-muted);
}
.breadcrumbs ol {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-wrap: wrap;
gap: 0;
}
.breadcrumbs li {
display: flex;
align-items: center;
}
/* Add the › separator after each item except the last */
.breadcrumbs li:not(:last-child)::after {
content: '›';
margin: 0 var(--space-xs);
color: var(--color-muted);
}
.breadcrumbs a {
color: var(--color-primary);
text-decoration: none;
}
.breadcrumbs a:hover {
text-decoration: underline;
}
.breadcrumbs [aria-current="page"] {
color: var(--color-text);
font-weight: 500;
}
The ::after pseudo-element adds the separator character between items without requiring you to put the separator in the HTML. This is cleaner because the separator is a visual convention, not meaningful content. Using CSS to insert it keeps the HTML semantic.
Search engines understand breadcrumbs. You can add structured data to your breadcrumb navigation to help search engines display breadcrumb trails in their results. This is an introductory topic for this course, but it is worth knowing the technique exists. Look for "breadcrumb structured data schema.org" when you are ready to explore it further.
Chapter 3 introduced relative paths. This section returns to them in the context of a multi-page site with folders, because paths are one of the most common sources of broken links and broken styles in student projects.
Here is a realistic folder structure for the Student Learning Site with individual lesson pages:
student-learning-site/
index.html
about.html
lessons.html
resources.html
contact.html
css/
main.css
js/
main.js
images/
logo.png
hero.jpg
about-photo.jpg
lessons/
lesson-01.html
lesson-02.html
lesson-03.html
data/
resources.json
Pages at the root level (directly inside student-learning-site/) can link to each other with simple filenames: href="about.html". They can link to the CSS file with href="css/main.css". They can link to images with src="images/logo.png".
Pages in subfolders (lessons/lesson-01.html) must account for their position one level deeper. The path ../ means "go up one folder level."
From lessons/lesson-01.html:
| What you are linking to | Correct relative path |
|---|---|
| Home page | ../index.html |
| About page | ../about.html |
| Lessons index | ../lessons.html |
| CSS file | ../css/main.css |
| JavaScript file | ../js/main.js |
| Logo image | ../images/logo.png |
| Another lesson | lesson-02.html (same folder, no ../ needed) |
The rule is: count how many folders deep the current file is, then use ../ that many times to get back to the root.
From a file two levels deep (for example, lessons/unit-1/intro.html):
| What you are linking to | Correct relative path |
|---|---|
| Home page | ../../index.html |
| CSS file | ../../css/main.css |
| Logo image | ../../images/logo.png |
After writing a page in a subfolder, open it in the browser and check four things: does the page title appear in the browser tab (this always works, since <title> needs no path); does the CSS load (check for styled text, colors, and layout — an unstyled page means a broken CSS path); do images appear (broken image icons mean broken image paths); and do navigation links go to the correct pages. Checking these four things immediately after creating a new page will catch path errors early.
<link rel="stylesheet" href="/Users/student/Documents/student-learning-site/css/main.css">
../ when inside a subfolder<link rel="stylesheet" href="css/main.css">
<link rel="stylesheet" href="../css/main.css">
lessons/ folder.
../../, your path will still be wrong. Count the levels carefully — one ../ per folder level you need to climb.<img src="images\logo.png" alt="Logo">
<img src="images/logo.png" alt="Logo">
A site map is a document or diagram that shows all the pages on a site and how they relate to each other. Site maps exist at two levels: the information architecture level (planning) and the technical level (implementation).
Before you write a single line of code for a multi-page site, it is worth sketching the site's structure. Which pages exist? Which pages link to which? What is the hierarchy?
For the Student Learning Site, the information architecture is flat: all main pages are at the same level with no deep hierarchy. But if the site grew, it might look like this:
Home
├── About
├── Lessons
│ ├── Lesson 01: Intro to HTML
│ ├── Lesson 02: CSS Basics
│ └── Lesson 03: The Box Model
├── Resources
└── Contact
This is called a tree structure or hierarchy. The home page is the root. The main section pages (About, Lessons, Resources, Contact) are one level down. Individual lesson pages are two levels down.
Understanding the hierarchy helps you name your folders consistently (lessons/), write correct relative paths (root pages use ../ to reach subfolders; subpages use ../../ to reach the root), design navigation that reflects the hierarchy, and write breadcrumbs that match the hierarchy.
When a site is published on a web server, it can include a sitemap.xml file. This file lists every page on the site in a format that search engines can read. Search engines use the sitemap to discover and index all pages, even pages that are not directly linked from the home page.
Writing XML sitemaps is beyond the scope of this chapter — it is introduced in Chapter 30 as part of the publishing process. What matters here is understanding that sitemaps serve two different audiences: the visual site map is for you and your team, and the XML sitemap is for search engines.
A site where every page links to every other page is easy to navigate but can feel overwhelming if the site grows large. A site where some pages are hard to find because they are only linked from one obscure location loses users. Good information architecture means every page is reachable from the main navigation, from the footer, or through a clear path of links; related pages link to each other within their content; the home page links to the main sections; section pages link to their subsection pages; and users can always find a path back to the home page.
This section walks through building the Student Learning Site as a complete five-page static site. Work through each step in sequence. By the end, you will have a working multi-page site with shared navigation, active states, a footer, and correct relative paths.
css/main.css, including colors, spacing tokens, and the flex-column body for the sticky footer pattern.js/main.js, using the DOMContentLoaded event.index.html, with the skip link, header, navigation, main content, footer, and script tag all in place.index.html to create about.html, lessons.html, resources.html, and contact.html. Update each page's title, description, and main content.student-learning-site/
index.html
about.html
lessons.html
resources.html
contact.html
css/
main.css
js/
main.js
images/
(place your image files here)
data/
resources.json
Open css/main.css. Define your CSS custom properties at the top, then write base styles for the body and typography.
/* ===================================
CSS Variables
=================================== */
:root {
/* Colors */
--color-primary: #1a4e8a;
--color-primary-dark: #133d6e;
--color-accent: #f5a623;
--color-white: #ffffff;
--color-dark: #1c1c1e;
--color-light: #f5f5f7;
--color-text: #2c2c2e;
--color-muted: #6e6e73;
--color-border: rgba(255, 255, 255, 0.15);
--color-hover-bg: #f0f4fa;
/* Spacing */
--space-xs: 0.25rem;
--space-sm: 0.5rem;
--space-md: 1rem;
--space-lg: 1.5rem;
--space-xl: 2.5rem;
--space-xxl: 4rem;
}
/* ===================================
Base Styles
=================================== */
*, *::before, *::after {
box-sizing: border-box;
}
body {
font-family: Georgia, 'Times New Roman', serif;
font-size: 1rem;
line-height: 1.7;
color: var(--color-text);
background-color: var(--color-white);
margin: 0;
display: flex;
flex-direction: column;
min-height: 100vh;
}
img {
max-width: 100%;
height: auto;
display: block;
}
a {
color: var(--color-primary);
}
a:hover {
color: var(--color-primary-dark);
}
main {
flex: 1;
}
.page-container {
max-width: 1100px;
margin: 0 auto;
padding: var(--space-xl) var(--space-md);
}
/* ===================================
Skip Link
=================================== */
.skip-link {
position: absolute;
top: -100%;
left: var(--space-md);
background-color: var(--color-primary);
color: var(--color-white);
padding: var(--space-sm) var(--space-md);
border-radius: 0 0 4px 4px;
font-weight: 700;
text-decoration: none;
z-index: 1000;
transition: top 0.2s;
}
.skip-link:focus {
top: 0;
}
/* ===================================
Site Header
=================================== */
.site-header {
background-color: var(--color-primary);
color: var(--color-white);
padding: var(--space-md) 0;
position: sticky;
top: 0;
z-index: 100;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}
.header-inner {
max-width: 1100px;
margin: 0 auto;
padding: 0 var(--space-md);
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-md);
}
.site-logo {
font-size: 1.25rem;
font-weight: 700;
color: var(--color-white);
text-decoration: none;
white-space: nowrap;
}
.site-logo:hover {
color: var(--color-accent);
}
/* ===================================
Main Navigation
=================================== */
.main-nav ul {
list-style: none;
padding: 0;
margin: 0;
display: flex;
gap: var(--space-xs);
}
.main-nav a {
display: block;
color: var(--color-white);
text-decoration: none;
font-size: 0.9375rem;
padding: var(--space-xs) var(--space-sm);
border-radius: 4px;
transition: background-color 0.2s;
}
.main-nav a:hover {
background-color: var(--color-primary-dark);
color: var(--color-white);
}
.main-nav a.active,
.main-nav a[aria-current="page"] {
background-color: var(--color-primary-dark);
color: var(--color-accent);
font-weight: 600;
}
/* ===================================
Site Footer
=================================== */
.site-footer {
background-color: var(--color-dark);
color: var(--color-light);
padding: var(--space-xl) 0 var(--space-lg);
}
.footer-inner {
max-width: 1100px;
margin: 0 auto;
padding: 0 var(--space-md);
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--space-lg);
}
@media (max-width: 600px) {
.footer-inner {
grid-template-columns: 1fr;
}
}
.footer-site-name {
font-size: 1.1rem;
font-weight: 700;
margin: 0 0 var(--space-xs);
}
.footer-tagline {
font-size: 0.875rem;
color: var(--color-muted);
margin: 0;
}
.footer-nav ul {
list-style: none;
padding: 0;
margin: 0;
}
.footer-nav li {
margin-bottom: var(--space-xs);
}
.footer-nav a {
color: var(--color-light);
text-decoration: none;
font-size: 0.9375rem;
}
.footer-nav a:hover {
color: var(--color-accent);
text-decoration: underline;
}
.footer-copyright {
grid-column: 1 / -1;
border-top: 1px solid rgba(255, 255, 255, 0.1);
padding-top: var(--space-md);
margin-top: var(--space-md);
font-size: 0.875rem;
color: var(--color-muted);
}
Open js/main.js and add the following function:
/* ===================================
Active Navigation State
=================================== */
function setActiveNavLink() {
// Get the current page filename
// For the home page (index.html or just /), fall back to 'index.html'
const pathParts = window.location.pathname.split('/');
const currentPage = pathParts[pathParts.length - 1] || 'index.html';
// Select all links in the main navigation
const navLinks = document.querySelectorAll('.main-nav a');
navLinks.forEach(function(link) {
// Get the filename from the link's href
const hrefParts = link.getAttribute('href').split('/');
const linkPage = hrefParts[hrefParts.length - 1];
if (linkPage === currentPage) {
link.classList.add('active');
link.setAttribute('aria-current', 'page');
}
});
}
// Run when the page loads
document.addEventListener('DOMContentLoaded', setActiveNavLink);
The function splits the current URL's pathname to get the filename of the current page. It then compares that filename to each navigation link's href. When it finds a match, it adds the .active class and the aria-current attribute. The DOMContentLoaded event ensures the function runs after the HTML has fully loaded but before images and stylesheets finish loading, so the active state is applied as soon as the navigation is available.
Open index.html and write the complete page. Notice that the navigation HTML is identical on every page — the active state is set by JavaScript, not by hand:
<!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="A learning resource for MGU web development students.">
<title>Home — Student Learning Site</title>
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<a href="#main-content" class="skip-link">Skip to main content</a>
<header class="site-header">
<div class="header-inner">
<a href="index.html" class="site-logo">Student Learning Site</a>
<nav class="main-nav" aria-label="Main navigation">
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="about.html">About</a></li>
<li><a href="lessons.html">Lessons</a></li>
<li><a href="resources.html">Resources</a></li>
<li><a href="contact.html">Contact</a></li>
</ul>
</nav>
</div>
</header>
<main id="main-content">
<div class="page-container">
<h1>Welcome to the Student Learning Site</h1>
<p>This site is a resource for students learning web development. Explore the lessons, browse the resources, and use the contact page to get in touch.</p>
<p>Start with the <a href="lessons.html">Lessons page</a> or browse the <a href="resources.html">Resources</a>.</p>
</div>
</main>
<footer class="site-footer">
<div class="footer-inner">
<div class="footer-info">
<p class="footer-site-name">Student Learning Site</p>
<p class="footer-tagline">A resource for MGU web development students.</p>
</div>
<nav class="footer-nav" aria-label="Footer navigation">
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="about.html">About</a></li>
<li><a href="lessons.html">Lessons</a></li>
<li><a href="resources.html">Resources</a></li>
<li><a href="contact.html">Contact</a></li>
</ul>
</nav>
<p class="footer-copyright">© 2025 Student Learning Site. All rights reserved.</p>
</div>
</footer>
<script src="js/main.js"></script>
</body>
</html>
Copy index.html to about.html, lessons.html, resources.html, and contact.html. Then in each copy: update the <title> element to match the page name — for example, <title>About — Student Learning Site</title>; update the <meta name="description"> to a description appropriate for that page; replace the <main> content with the actual content for that page; and verify that all CSS, JavaScript, and image paths are correct for a root-level page.
Because JavaScript handles the active navigation state, you do not need to change the navigation HTML on any page. Every page shares exactly the same header and footer markup.
Open index.html in the browser and verify the header appears on every page; the active navigation link is highlighted on each page (check by clicking through all five pages); every navigation link goes to the correct page; the footer appears on every page; the footer navigation links work; no CSS or JavaScript errors appear in the browser console; and on short-content pages, the footer sits at the bottom of the viewport.
<header> to hold a logo linking back to the home page and a <nav> with an aria-label distinguishing it from other navigation on the page. Navigation links belong in a list, since a list of links is exactly that — a list.<footer> to hold secondary navigation, contact information, and a copyright line. CSS Grid creates clean footer layouts, and the flex-column body with flex: 1 on <main> keeps the footer at the bottom of short pages.#main-content.aria-current="page". Static sites either repeat slightly different navigation HTML on each page or use a small JavaScript function that compares the URL to each link's href and applies the active state automatically.aria-current="page" for the final, non-linked item.../ per folder level. Common mistakes include absolute filesystem paths, missing or miscounted ../ segments, and backslashes, which never work in HTML paths.<nav> elements on the same page.<footer> element at the bottom of every page, containing contact information, secondary navigation, copyright, and supporting links.<header> element at the top of every page, containing the site logo, primary navigation, and page identification.../ to navigate up folder levels.position: sticky) that keeps an element fixed in view as the user scrolls until it reaches the edge of its containing element. Useful for headers.sitemap.xml at the root of a published website that lists all pages for search engines to discover and index.Read the following navigation markup carefully, then answer the questions below.
<a href="#main-content" class="skip-link">Skip to main content</a>
<header class="site-header">
<div class="header-inner">
<a href="index.html" class="site-logo">Brightfield Academy</a>
<nav class="main-nav" aria-label="Main navigation">
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="courses.html">Courses</a></li>
<li><a href="instructors.html">Instructors</a></li>
<li><a href="blog.html">Blog</a></li>
<li><a href="contact.html">Contact</a></li>
</ul>
</nav>
</div>
</header>
aria-label="Main navigation" on the <nav> element? When would this label be especially important?href="#main-content". For the skip link to work, what must exist elsewhere in the HTML? Write the opening tag of the element it would need to target.courses.html. The JavaScript active-state function runs. Which <a> element will receive the .active class and aria-current="page" attribute? Write what that element looks like after JavaScript modifies it.<a> with text content), not an image. What advantage does this approach have over using an <img> element for the logo?courses/ subfolder containing courses/intro-html.html, and this page needs to link to the same CSS file at css/main.css, what relative path should it use for the stylesheet link?Trace the following JavaScript function step by step. The current page being viewed is resources.html.
function setActiveNavLink() {
const pathParts = window.location.pathname.split('/');
const currentPage = pathParts[pathParts.length - 1] || 'index.html';
const navLinks = document.querySelectorAll('.main-nav a');
navLinks.forEach(function(link) {
const hrefParts = link.getAttribute('href').split('/');
const linkPage = hrefParts[hrefParts.length - 1];
if (linkPage === currentPage) {
link.classList.add('active');
link.setAttribute('aria-current', 'page');
}
});
}
The navigation contains these links in order: <a href="index.html">Home</a>, <a href="about.html">About</a>, <a href="lessons.html">Lessons</a>, <a href="resources.html">Resources</a>, and <a href="contact.html">Contact</a>. Assume window.location.pathname returns /student-learning-site/resources.html.
window.location.pathname.split('/') produce? Write the resulting array.pathParts[pathParts.length - 1] evaluate to?currentPage?linkPage and whether the if condition is true or false..active added to its class list and aria-current="page" added as an attribute?Look at the following CSS and HTML. Predict what the breadcrumb trail will look like in the browser.
.breadcrumbs ol {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-wrap: wrap;
}
.breadcrumbs li:not(:last-child)::after {
content: '›';
margin: 0 0.5rem;
color: #888;
}
.breadcrumbs a {
color: #1a4e8a;
text-decoration: none;
}
.breadcrumbs [aria-current="page"] {
color: #2c2c2e;
font-weight: 500;
}
<nav class="breadcrumbs" aria-label="Breadcrumb">
<ol>
<li><a href="../../index.html">Home</a></li>
<li><a href="../lessons.html">Lessons</a></li>
<li aria-current="page">Lesson 4: Flexbox</li>
</ol>
</nav>
Describe: Which items are links and which are plain text? What color are the links? What color is the current page item? What character appears between each item, and what color is it?
Each of the following samples contains one or more errors. Identify the error and explain how to fix it.
A page located at lessons/lesson-02.html links to the stylesheet like this:
<link rel="stylesheet" href="css/main.css">
The page loads with no styles applied. What is the problem, and how do you fix it?
A developer adds two <nav> elements to the page but gives both the same aria-label:
<nav aria-label="Main navigation">
<!-- main nav links -->
</nav>
<!-- later in the footer -->
<nav aria-label="Main navigation">
<!-- footer nav links -->
</nav>
Why is this a problem for accessibility, and what should the developer change?
A developer writes the following skip link, but pressing Tab does not reveal it, and pressing Enter does not move focus to the main content.
<a href="main-content" class="skip-link">Skip to main content</a>
<!-- ... later ... -->
<main class="main-content">
There are two errors. Identify both and explain the corrections.
A developer wants the footer to stay at the bottom of the viewport even on short pages. They write:
body {
min-height: 100vh;
}
.site-footer {
position: absolute;
bottom: 0;
}
The footer does sit at the bottom of the viewport, but now it overlaps the main content on short pages. What is the correct approach, and why does position: absolute cause this problem?
index.html; a skip link pointing to #main-content; and a <nav> with five links: Home, Exhibits, Events, Education, and Visit. Use appropriate semantic HTML and ARIA attributes.#1a4e8a); on hover, links show a darker blue background (#133d6e); the active link is visually distinct (your choice of style); links have adequate padding for a comfortable click target (at minimum 0.5rem top/bottom and 0.75rem left/right); no bullet points or underlines on the links.index.html at the root, section pages like exhibits/index.html one level deep, and detail pages like exhibits/dinosaurs/triceratops.html two levels deep. Write the relative href paths, all written from inside exhibits/dinosaurs/triceratops.html, for: a link to the home page; a link to the exhibits section index; a link to the CSS file at css/main.css; a link to a nearby page at exhibits/dinosaurs/brachiosaurus.html; and a link to a page at events/upcoming.html.DOMContentLoaded event. Add a comment to each meaningful line explaining what it does.aria-current, use appropriate paths (assume two levels deep), and give the <nav> an appropriate aria-label.Build a complete five-page static website using everything covered in this chapter and the chapters before it. You may build the Student Learning Site as specified, or choose an alternative theme: a school club site (Drama Club, Science Club, Photography Club), a small community organization site, a personal portfolio site, or a hobby or interest site on a topic of your choice.
Required pages: Home, About, a content section page (Lessons, Projects, Gallery, or equivalent), a Resources or Links page, and a Contact page.
<header> on every page with a text-based or image-based logo and main navigation.<footer> on every page with copyright, a site description, and footer navigation links.css/main.css) with CSS custom properties used throughout.js/main.js) with the active navigation state function.aria-label attributes on both the main navigation and the footer navigation.body flex layout that keeps the footer at the bottom of short pages.position: sticky.alt text.<h1> per page, headings in descending order).Review a partner's five-page site or review your own site using the following questions. Mark each item as Met, Partially Met, or Not Met, and note specific issues where you find them.
<main>?aria-label present on both the main navigation and the footer navigation, with different labels on each?aria-current="page" for the current page?<h1> that identifies the page's main topic?<h1> → <h2> → <h3>) with no levels skipped?alt attributes? Are the alt texts descriptive and meaningful?These questions review skills from earlier chapters alongside the new material from this chapter.
lessons/unit-2/lesson-05.html needs to display an image stored at images/diagrams/flexbox.png from the root of the project. Write the correct <img> tag with the path, an appropriate alt attribute, and a width of 700 and height of 400.<h1>, followed by three <h3> elements. What is wrong with this structure and how do you fix it?.main-nav a.active in CSS. Explain how CSS reads this selector. Which elements will it match and which will it not match?display: flex and justify-content: space-between are used on .header-inner in this chapter. What does each declaration do, and what visual result do they produce together?position: sticky; top: 0. Explain what position: sticky does differently from position: fixed. Why might you prefer sticky over fixed for a site header?setActiveNavLink() function uses document.querySelectorAll('.main-nav a'). What does querySelectorAll return? How does it differ from querySelector?setActiveNavLink() function uses navLinks.forEach(function(link) { ... }). Explain what forEach does and why it is appropriate here instead of a regular for loop..active and aria-current by hand in the HTML on each page). Describe the maintenance problem this creates. What happens when they add a sixth page to the site?../ segments.Chapter 27 introduces common user interface patterns: card grids, image galleries, accordions, tabbed content, and show/hide behaviors. These patterns appear on nearly every real website, and building them requires combining everything you have learned about HTML structure, CSS styling, and JavaScript interaction.
You will learn how to toggle CSS classes with JavaScript to show and hide content, how to build an accordion where only one item is open at a time, how to build a tabbed interface that switches between sections without a page reload, and how keyboard interaction works for these components. Accessibility returns to the center of attention: interactive patterns that work with a mouse but not a keyboard exclude many users, so Chapter 27 introduces the fundamental ARIA roles and keyboard behaviors that make interactive patterns inclusive.
The mini-project in Chapter 27 will be a FAQ accordion or a tabbed lesson guide — both components you can add directly to your Student Learning Site.