Skip to content
nuggetof joy

Post · October 31, 2026

Final Project Enhancement Toolkit

AMDE 355 · Advanced Web Design · Final Project Resource

Final Project Enhancement Toolkit

Small details can make a website feel complete. This toolkit introduces practical HTML, CSS, and ready-to-use JavaScript patterns for improving navigation, image presentation, motion, and usability.

LESSON GOAL

You do not need to write JavaScript from scratch. Your job is to understand where each piece goes, adapt it to your project, and verify that it works on desktop, mobile, and with a keyboard.

Learning objectives

  • Implement reusable enhancements with semantic HTML and CSS.
  • Install and configure a lightweight JavaScript feature.
  • Improve mobile navigation and image presentation.
  • Test interaction, accessibility, and responsive behavior.

01 / Getting set up

In a typical project, put page structure in index.html, styles in style.css, and JavaScript in script.js. Add this line just before the closing </body> tag:

<script src="script.js" defer></script>

In CodePen, use the HTML, CSS, and JS panels instead. Important: examples below are separate features. Only copy the features you want, and keep the corresponding HTML/CSS/JS together.

02 / A forgiving image lightbox

Try it / Image lightbox

Select an image to open it. Close with Escape, the close button, or the background. This demonstration also works without an external library.

Click outside the image to close.

Demo photographs: Lorem Picsum. Student project: use your own images and the GLightbox implementation shown below.

A lightbox opens a larger image without leaving the gallery. For this lesson, use GLightbox: a lightweight, dependency-free library that recognizes ordinary image links. It supports touch navigation, keyboard controls, captions, and multiple images. You are installing a library, not writing a lightbox yourself.

Why “forgiving”? Students only need a valid image URL inside a link, a thumbnail image, and the class glightbox. The library handles the overlay and navigation. A broken image URL will still need to be fixed.

Step A — Add library files

Place the CSS link in the HTML <head> and the JavaScript before </body>. These examples use a pinned version; internet access is required when loading from the CDN.

<!-- In the head -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/glightbox@3.3.1/dist/css/glightbox.min.css">

<!-- Before the closing body tag -->
<script src="https://cdn.jsdelivr.net/npm/glightbox@3.3.1/dist/js/glightbox.min.js"></script>
<script>
  const galleryLightbox = GLightbox({ selector: '.glightbox', loop: true });
</script>

Step B — Mark up your images

<div class="project-gallery">
  <a href="images/project-01-large.jpg" class="glightbox"
     data-gallery="final-project" data-title="Project 01">
    <img src="images/project-01-thumb.jpg" alt="Describe the first project image" loading="lazy">
  </a>
  <a href="images/project-02-large.jpg" class="glightbox"
     data-gallery="final-project" data-title="Project 02">
    <img src="images/project-02-thumb.jpg" alt="Describe the second project image" loading="lazy">
  </a>
</div>

For a quick test, the thumbnail and full-size image may use the same image URL. Later, replace the thumbnail with a smaller optimized version. Group related images with the same data-gallery value.

Step C — Add the gallery CSS

.project-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1rem;
}
.project-gallery a { display: block; overflow: hidden; border-radius: 10px; }
.project-gallery img {
  display: block; width: 100%; aspect-ratio: 4 / 3;
  object-fit: cover; transition: transform .3s ease;
}
.project-gallery a:hover img { transform: scale(1.04); }
.project-gallery a:focus-visible { outline: 3px solid #66c9f1; outline-offset: 4px; }
@media (prefers-reduced-motion: reduce) {
  .project-gallery img { transition: none; }
}

Test: Click a thumbnail, press Escape, navigate with arrow keys, and test on a phone. If nothing happens, check that the library script loads, the class is spelled correctly, and the initialization runs after the library.

Library documentation: GLightbox on GitHub.

03 / Responsive mobile navigation

Try it / Mobile menu

Click the menu button to expand or collapse the navigation, even on desktop for testing.

Use a real <button> for the menu toggle. The JavaScript only switches the expanded state; CSS controls how the menu looks.

HTML

<header class="site-header">
  <a class="site-logo" href="#home">Studio Site</a>
  <button class="menu-toggle" type="button" aria-expanded="false"
          aria-controls="site-nav">Menu</button>
  <nav class="site-nav" id="site-nav" aria-label="Main navigation">
    <a href="#home">Home</a>
    <a href="#work">Work</a>
    <a href="#about">About</a>
    <a href="#contact">Contact</a>
  </nav>
</header>

CSS

.site-header { display:flex; align-items:center; justify-content:space-between; gap:1rem; padding:1rem; }
.site-nav { display:flex; gap:1.25rem; }
.menu-toggle { display:none; }
@media (max-width: 700px) {
  .site-header { flex-wrap:wrap; }
  .menu-toggle { display:block; cursor:pointer; }
  .site-nav { display:none; flex-basis:100%; flex-direction:column; }
  .site-nav.is-open { display:flex; }
}

JavaScript — copy into your JS file

const menuButton = document.querySelector('.menu-toggle');
const siteNav = document.querySelector('#site-nav');
if (menuButton && siteNav) {
  function closeMenu() {
    siteNav.classList.remove('is-open');
    menuButton.setAttribute('aria-expanded', 'false');
  }
  menuButton.addEventListener('click', () => {
    const isOpen = siteNav.classList.toggle('is-open');
    menuButton.setAttribute('aria-expanded', String(isOpen));
  });
  siteNav.querySelectorAll('a').forEach(link => {
    link.addEventListener('click', closeMenu);
  });
  document.addEventListener('keydown', event => {
    if (event.key === 'Escape') { closeMenu(); }
  });
}

Test: Narrow the browser below 700px. Open the menu, click a link, and confirm it closes. Check that Tab reaches the button and its links.

04 / Anchor links and smooth scrolling

Try it / Smooth scrolling

This is a miniature scrollable webpage. Click the anchor link to jump to its section.

Jump to project details ↓

Imagine this is the top of a long portfolio page.

You reached the project details using an anchor link.

Anchor links connect a navigation item to an element with a matching ID. This is native HTML; smooth scrolling only needs CSS.

<a href="#projects">See Projects</a>

<section id="projects">
  <h2>Selected Projects</h2>
</section>
html { scroll-behavior: smooth; }
section[id] { scroll-margin-top: 5rem; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

If your header is sticky, adjust scroll-margin-top so headings are not hidden. IDs must be unique. Try this page’s anchor link: return to the top.

05 / CSS animations and transitions

Try it / Motion and hover

Hover over or keyboard-focus the card. Use Replay to restart the entrance animation.

Featured project ↗

Use motion to guide attention, not distract. A hover transition is ideal for buttons and cards; a short entrance animation can introduce a hero headline.

Hover effect

.project-card {
  transition: transform .25s ease, box-shadow .25s ease;
}
.project-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 12px 30px rgb(0 0 0 / .18);
}
.project-card:focus-within { outline: 2px solid #66c9f1; }

Entrance animation

.hero-title { animation: rise-in .7s ease-out both; }
@keyframes rise-in {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .hero-title { animation: none; }
  .project-card { transition: none; }
}

Live example: This panel uses a gentle entrance animation when the page loads.

Explore the next feature

Design advice: Prefer animating transform and opacity. Avoid constant movement and respect reduced-motion settings.

07 / Expandable FAQ or project details

Try it / Native disclosure

Click either question. No JavaScript is needed.

What belongs in a portfolio case study?

Project goals, your role, process images, and the final result.

Can I use this on mobile?

Yes. The HTML details element works with touch and keyboard controls.

The native <details> element gives you an interactive disclosure without JavaScript. It is useful for process notes, project descriptions, FAQs, and credits.

<details class="faq">
  <summary>What was the design process?</summary>
  <p>Research, wireframes, prototypes, and testing.</p>
</details>
.faq { border-bottom:1px solid #aaa; padding:1rem 0; }
.faq summary { cursor:pointer; font-weight:700; }
.faq summary:focus-visible { outline:3px solid #66c9f1; }
Try it: What makes this feature useful?

It works without a library, supports keyboard activation, and keeps optional information available without making the page overly long.

08 / Small details that improve a final website

Try it / Sticky navigation and responsive type

Responsive heading

The heading scales with the viewport. Scroll inside this box to watch the header stay visible.

Sticky project navigation

Project overview and introduction.

Research and sketches.

Design iterations.

Final presentation.

Reflection and credits.

Sticky header

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgb(255 255 255 / .96);
}

Responsive type

h1 { font-size: clamp(2rem, 5vw, 4.5rem); }
body { line-height: 1.6; }

Visible keyboard focus

a:focus-visible, button:focus-visible {
  outline: 3px solid #087eac;
  outline-offset: 3px;
}

Better image performance

<img src="images/project.webp" alt="Describe the image"
     width="1200" height="800" loading="lazy">

Provide accurate intrinsic dimensions to reduce layout shifting. Do not lazy-load the primary image that appears immediately at the top of the page.

Optional stretch ideas

  • Back-to-top link: a simple anchor to #top.
  • CSS variables: define reusable colors, spacing, and border radii in :root.
  • Dark/light theme: use prefers-color-scheme for an automatic theme.
  • Embedded media: add a captioned video or an accessible iframe where relevant.

09 / Final project implementation checklist

Suggested goal: Implement at least three purposeful enhancements from this toolkit, or comparable techniques suited to your design. Quality and usability matter more than quantity.

  • All navigation links and anchors lead to the correct sections.
  • Mobile menu works at narrow widths, including keyboard navigation.
  • Lightbox images open, close, and display at useful sizes.
  • Images have appropriate alt text and reasonable file sizes.
  • Motion is subtle and reduced-motion preferences are respected.
  • Layout works on desktop, tablet, and phone without horizontal overflow.
  • External libraries load correctly on the published site, not just CodePen.
  • Every feature supports the purpose of the site.

Suggested student workflow

  1. Choose features that support your site’s content and audience.
  2. Copy one example into a test page or CodePen.
  3. Replace placeholder text, links, and images with your own assets.
  4. Move the working feature into your final project.
  5. Test on desktop and mobile; fix any broken interactions.
  6. Document which enhancements you implemented and why.

Instructor note: Students are responsible for integrating and testing JavaScript, not memorizing its syntax. Encourage incremental testing: add one feature, verify it, then move to the next. This toolkit is a resource, not a requirement to use every effect.

Reference links

MDN: details element · MDN: scroll-behavior · MDN: reduced motion · GLightbox documentation