Weekend Project: Create a Complete, Responsive Website

Week 4: Web Fundamentals - Comprehensive Application of HTML, CSS, and JavaScript

Project Overview

Welcome to your weekend project! This is your opportunity to consolidate everything you've learned this week about HTML, CSS, and JavaScript by creating a complete, responsive website from scratch. Think of this project as building a digital house—you'll lay the foundation with HTML, design the aesthetics with CSS, and add functionality with JavaScript.

Unlike previous assignments that focused on specific aspects of web development, this project requires you to integrate all three technologies into a cohesive, functioning website. This reflects real-world development, where these technologies work together to create comprehensive user experiences.

Learning Objectives

  • Apply semantic HTML to create well-structured, accessible content
  • Implement responsive CSS layouts that work on devices of all sizes
  • Add interactive features using JavaScript to enhance user experience
  • Practice organizing files in a professional project structure
  • Experience the full development cycle from planning to implementation
  • Create a portfolio-worthy project that demonstrates your skills

Step 1: Understanding the Problem

Before writing any code, let's clarify what we're trying to build and what success looks like. This first step in Polya's problem-solving method ensures we have a clear vision before proceeding.

Project Requirements

Your website must include:

Theme Options

You may choose from the following website themes:

  1. Portfolio Website: Showcase your skills, projects, and background
  2. Small Business Site: A website for a fictional local business (restaurant, salon, store, etc.)
  3. Educational Resource: An informational site about a topic you're knowledgeable about
  4. Community Organization: A website for a fictional community group or non-profit
  5. Product Showcase: A site featuring a fictional product or service

Choose a theme that interests you, as your enthusiasm will drive better results. Consider what type of content you'll need to generate and what interactive elements would make sense for your chosen theme.

Clarifying Questions

Before proceeding, consider these questions:

  • Who is the target audience for my website?
  • What are the primary goals visitors should accomplish on my site?
  • What content will I need to create or gather?
  • What interactive elements would enhance the user experience for my chosen theme?
  • What design aesthetic fits my chosen theme?

Expected Outcomes

By the end of this project, you should have:

  • A complete, multi-page website with consistent styling
  • A responsive design that works well on different devices
  • Interactive features that enhance user experience
  • A well-organized project with clean, efficient code
  • A deeper understanding of how HTML, CSS, and JavaScript work together
  • A project you can proudly add to your portfolio

Step 2: Devising a Plan

Now that we understand what we're building, let's create a systematic plan for development. This exemplifies the second step of Polya's problem-solving method.

Project Whiteboard Plan

  1. Choose a theme and sketch the basic layout for each page
  2. Set up project folder structure and create necessary files
  3. Build the HTML structure for all pages with proper semantic elements
  4. Create the CSS styling, starting with global styles and then page-specific styles
  5. Implement responsive design using media queries
  6. Add JavaScript interactivity for key features
  7. Test the site across different devices and browsers
  8. Optimize and refine the code

Project Structure

Let's establish a professional folder and file organization:

project_folder/
│
├── index.html                 (Home page)
├── about.html                 (About page)
├── services.html              (Services/Products page)
├── contact.html               (Contact page)
│
├── css/
│   ├── styles.css             (Main CSS file)
│   └── responsive.css         (Responsive styles)
│
├── js/
│   ├── main.js                (Main JavaScript file)
│   ├── validation.js          (Form validation)
│   └── slider.js              (Image slider or carousel)
│
├── images/
│   ├── logo.png               (Website logo)
│   ├── banner.jpg             (Hero/banner image)
│   ├── product1.jpg           (Product/service images)
│   ├── product2.jpg
│   └── team.jpg               (Team or about page image)
│
└── favicon.png                (Website favicon)

Planned Interactive Features

Consider implementing these JavaScript features (choose at least 3):

Responsive Design Approach

We'll use a mobile-first approach, designing for small screens first and then adding complexity for larger screens:

Helpful Tools and Resources

  • Design Inspiration: Dribbble, Behance, or Awwwards for visual ideas
  • Color Schemes: Coolors.co or Adobe Color
  • Typography: Google Fonts for web-safe fonts
  • Icons: Font Awesome or Material Icons
  • Placeholder Images: Unsplash, Pexels, or Lorem Picsum
  • Placeholder Text: Lorem Ipsum generators
  • Testing: Browser dev tools for responsive testing

Step 3: Executing the Plan

Now we'll implement our plan, following Polya's third step. I'll provide guidance for each major component of the project.

Setting Up the Project

File path: Create a new folder named weekend_project on your computer.

Inside this folder, create the following structure:

Building the HTML Structure

Let's create a template for our HTML pages to ensure consistency. Here's a basic structure for index.html that you can adapt for other pages:

HTML Template (index.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Your Site Name | Home</title>
    <meta name="description" content="Description of your website">
    
    <!-- CSS Files -->
    <link rel="stylesheet" href="css/styles.css">
    <link rel="stylesheet" href="css/responsive.css">
    
    <!-- Favicon -->
    <link rel="icon" href="favicon.png">
    
    <!-- Optional: Google Fonts -->
    <link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700&family=Playfair+Display:wght@700&display=swap" rel="stylesheet">
</head>
<body>
    <!-- Skip Navigation for Accessibility -->
    <a href="#main-content" class="skip-link">Skip to main content</a>
    
    <header>
        <div class="container">
            <div class="logo">
                <a href="index.html">
                    <img src="images/logo.png" alt="Your Site Name">
                </a>
            </div>
            
            <nav>
                <button class="mobile-menu-toggle" aria-label="Toggle navigation menu">
                    <span></span>
                    <span></span>
                    <span></span>
                </button>
                
                <ul class="nav-menu">
                    <li><a href="index.html" class="active">Home</a></li>
                    <li><a href="about.html">About Us</a></li>
                    <li><a href="services.html">Services</a></li>
                    <li><a href="contact.html">Contact</a></li>
                </ul>
            </nav>
        </div>
    </header>

    <main id="main-content">
        <section class="hero">
            <div class="container">
                <h1>Welcome to Your Site Name</h1>
                <p>A brief tagline or value proposition</p>
                <a href="contact.html" class="btn primary-btn">Get Started</a>
            </div>
        </section>
        
        <section class="features">
            <div class="container">
                <h2>Our Features</h2>
                
                <div class="feature-grid">
                    <div class="feature-item">
                        <img src="images/feature1.jpg" alt="Feature 1">
                        <h3>Feature 1</h3>
                        <p>Description of this feature or service.</p>
                    </div>
                    
                    <div class="feature-item">
                        <img src="images/feature2.jpg" alt="Feature 2">
                        <h3>Feature 2</h3>
                        <p>Description of this feature or service.</p>
                    </div>
                    
                    <div class="feature-item">
                        <img src="images/feature3.jpg" alt="Feature 3">
                        <h3>Feature 3</h3>
                        <p>Description of this feature or service.</p>
                    </div>
                </div>
            </div>
        </section>
        
        <section class="testimonials">
            <div class="container">
                <h2>What Our Clients Say</h2>
                
                <div class="testimonial-slider">
                    <div class="testimonial">
                        <p>"Testimonial text goes here. Make it compelling and authentic."</p>
                        <cite>— Client Name, Position</cite>
                    </div>
                    
                    <div class="testimonial">
                        <p>"Another testimonial text. Focus on specific results or benefits."</p>
                        <cite>— Another Client, Position</cite>
                    </div>
                    
                    <div class="testimonial">
                        <p>"A third testimonial for good measure."</p>
                        <cite>— Third Client, Position</cite>
                    </div>
                    
                    <div class="slider-controls">
                        <button class="prev-btn" aria-label="Previous testimonial">&larr;</button>
                        <button class="next-btn" aria-label="Next testimonial">&rarr;</button>
                    </div>
                </div>
            </div>
        </section>
        
        <section class="cta">
            <div class="container">
                <h2>Ready to Get Started?</h2>
                <p>Call-to-action text encouraging the user to take the next step.</p>
                <a href="contact.html" class="btn primary-btn">Contact Us Today</a>
            </div>
        </section>
    </main>

    <footer>
        <div class="container">
            <div class="footer-grid">
                <div class="footer-col">
                    <h3>Your Site Name</h3>
                    <p>Short description or mission statement.</p>
                </div>
                
                <div class="footer-col">
                    <h3>Quick Links</h3>
                    <ul>
                        <li><a href="index.html">Home</a></li>
                        <li><a href="about.html">About Us</a></li>
                        <li><a href="services.html">Services</a></li>
                        <li><a href="contact.html">Contact</a></li>
                    </ul>
                </div>
                
                <div class="footer-col">
                    <h3>Contact Info</h3>
                    <address>
                        123 Main Street<br>
                        City, State ZIP<br>
                        <a href="tel:+11234567890">(123) 456-7890</a><br>
                        <a href="mailto:info@yoursite.com">info@yoursite.com</a>
                    </address>
                </div>
                
                <div class="footer-col">
                    <h3>Follow Us</h3>
                    <div class="social-links">
                        <a href="#" aria-label="Facebook">Facebook</a>
                        <a href="#" aria-label="Twitter">Twitter</a>
                        <a href="#" aria-label="Instagram">Instagram</a>
                        <a href="#" aria-label="LinkedIn">LinkedIn</a>
                    </div>
                </div>
            </div>
            
            <div class="copyright">
                <p>&copy; 2025 Your Site Name. All rights reserved.</p>
            </div>
        </div>
    </footer>

    <!-- JavaScript Files -->
    <script src="js/main.js"></script>
    <script src="js/slider.js"></script>
</body>
</html>

HTML Explanation:

  • The document begins with the DOCTYPE declaration and includes proper language attributes.
  • The head section contains meta tags for character encoding, viewport settings, and page description.
  • External CSS files are linked, and a favicon is specified.
  • The semantic structure includes header, nav, main, section, and footer elements.
  • A skip link is provided for accessibility, allowing keyboard users to bypass navigation.
  • The navigation is structured as an unordered list with links to all pages.
  • Content sections use descriptive class names for styling.
  • JavaScript files are linked at the bottom of the body for better performance.

Use this template as a starting point for all your pages, modifying the main content as appropriate for each page. For example:

Contact Form HTML (for contact.html)

<section class="contact-form">
    <div class="container">
        <h2>Contact Us</h2>
        <p>Fill out the form below to get in touch with us.</p>
        
        <form id="contactForm" action="#" method="POST" novalidate>
            <div class="form-group">
                <label for="name">Your Name</label>
                <input type="text" id="name" name="name" required>
                <span class="error-message" id="nameError"></span>
            </div>
            
            <div class="form-group">
                <label for="email">Email Address</label>
                <input type="email" id="email" name="email" required>
                <span class="error-message" id="emailError"></span>
            </div>
            
            <div class="form-group">
                <label for="phone">Phone Number (optional)</label>
                <input type="tel" id="phone" name="phone">
                <span class="error-message" id="phoneError"></span>
            </div>
            
            <div class="form-group">
                <label for="subject">Subject</label>
                <select id="subject" name="subject" required>
                    <option value="">Please select...</option>
                    <option value="general">General Inquiry</option>
                    <option value="support">Technical Support</option>
                    <option value="billing">Billing Question</option>
                    <option value="other">Other</option>
                </select>
                <span class="error-message" id="subjectError"></span>
            </div>
            
            <div class="form-group">
                <label for="message">Your Message</label>
                <textarea id="message" name="message" rows="5" required></textarea>
                <span class="error-message" id="messageError"></span>
            </div>
            
            <div class="form-group checkbox-group">
                <input type="checkbox" id="consent" name="consent" required>
                <label for="consent">I agree to the privacy policy and terms of service.</label>
                <span class="error-message" id="consentError"></span>
            </div>
            
            <button type="submit" class="btn primary-btn">Send Message</button>
        </form>
    </div>
</section>

Creating the CSS Styling

Let's implement our CSS styles, starting with a reset and global styles. Here's the structure for styles.css:

Basic CSS Styling (css/styles.css)

/* 
 * styles.css
 * Main styles for Your Site Name
 */

/* 
 * TABLE OF CONTENTS
 * 
 * 1. CSS Reset and Base Styles
 * 2. Typography
 * 3. Layout & Containers
 * 4. Header and Navigation
 * 5. Buttons and Forms
 * 6. Hero Section
 * 7. Features Section
 * 8. Testimonials Section
 * 9. CTA Section
 * 10. Footer Styles
 * 11. About Page Styles
 * 12. Services Page Styles
 * 13. Contact Page Styles
 * 14. Utilities
 */

/* ========================================
   1. CSS Reset and Base Styles
   ======================================== */

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

/* Remove default margin */
body, h1, h2, h3, h4, p, ul, ol, figure, blockquote, dl, dd {
    margin: 0;
}

/* Set core body defaults */
body {
    min-height: 100vh;
    scroll-behavior: smooth;
    text-rendering: optimizeSpeed;
    line-height: 1.6;
    font-family: 'Open Sans', sans-serif;
    color: #333;
    background-color: #fff;
}

/* Remove list styles on ul, ol elements with a class */
ul, ol {
    list-style: none;
}

/* Make images easier to work with */
img {
    max-width: 100%;
    display: block;
}

/* Inherit fonts for inputs and buttons */
input, button, textarea, select {
    font: inherit;
}

/* Accessibility: Skip to content link */
.skip-link {
    position: absolute;
    top: -40px;
    left: 0;
    background: #000;
    color: white;
    padding: 8px;
    z-index: 100;
}

.skip-link:focus {
    top: 0;
}

/* ========================================
   2. Typography
   ======================================== */

h1, h2, h3, h4 {
    font-family: 'Playfair Display', serif;
    line-height: 1.2;
    margin-bottom: 1rem;
}

h1 {
    font-size: 2.5rem;
}

h2 {
    font-size: 2rem;
    margin-bottom: 2rem;
}

h3 {
    font-size: 1.5rem;
}

p {
    margin-bottom: 1rem;
}

a {
    color: #0066cc;
    text-decoration: none;
    transition: color 0.3s ease;
}

a:hover, a:focus {
    color: #004999;
    text-decoration: underline;
}

/* ========================================
   3. Layout & Containers
   ======================================== */

.container {
    width: 90%;
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 15px;
}

section {
    padding: 3rem 0;
}

/* Grid layouts */
.feature-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 2rem;
}

.footer-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 2rem;
    margin-bottom: 2rem;
}

/* ========================================
   4. Header and Navigation
   ======================================== */

header {
    background-color: #fff;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    position: relative;
    z-index: 100;
    padding: 1rem 0;
}

header .container {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.logo img {
    max-height: 50px;
}

/* Mobile Navigation */
.mobile-menu-toggle {
    display: block;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.5rem;
}

.mobile-menu-toggle span {
    display: block;
    width: 25px;
    height: 3px;
    background-color: #333;
    margin: 5px 0;
    transition: transform 0.3s ease, opacity 0.3s ease;
}

/* Navigation menu */
.nav-menu {
    position: absolute;
    top: 100%;
    left: 0;
    width: 100%;
    background-color: #fff;
    box-shadow: 0 4px 4px rgba(0,0,0,0.1);
    padding: 1rem 0;
    transform: translateY(-100%);
    opacity: 0;
    visibility: hidden;
    transition: transform 0.3s ease, opacity 0.3s ease, visibility 0.3s ease;
}

.nav-menu.active {
    transform: translateY(0);
    opacity: 1;
    visibility: visible;
}

.nav-menu li {
    text-align: center;
    margin: 1rem 0;
}

.nav-menu a {
    color: #333;
    font-weight: 700;
    text-transform: uppercase;
    font-size: 0.9rem;
    letter-spacing: 1px;
    transition: color 0.3s ease;
}

.nav-menu a:hover, 
.nav-menu a:focus,
.nav-menu a.active {
    color: #0066cc;
}

/* ========================================
   5. Buttons and Forms
   ======================================== */

/* Button styles */
.btn {
    display: inline-block;
    padding: 0.75rem 1.5rem;
    border-radius: 5px;
    font-weight: 700;
    text-align: center;
    text-transform: uppercase;
    letter-spacing: 1px;
    cursor: pointer;
    transition: background-color 0.3s ease, color 0.3s ease, transform 0.3s ease;
}

.primary-btn {
    background-color: #0066cc;
    color: white;
    border: 2px solid #0066cc;
}

.primary-btn:hover, .primary-btn:focus {
    background-color: #004999;
    border-color: #004999;
    transform: translateY(-3px);
    text-decoration: none;
    color: white;
}

.secondary-btn {
    background-color: transparent;
    color: #0066cc;
    border: 2px solid #0066cc;
}

.secondary-btn:hover, .secondary-btn:focus {
    background-color: #0066cc;
    color: white;
    transform: translateY(-3px);
    text-decoration: none;
}

/* Form styles */
form {
    max-width: 600px;
    margin: 2rem auto;
}

.form-group {
    margin-bottom: 1.5rem;
}

label {
    display: block;
    margin-bottom: 0.5rem;
    font-weight: 600;
}

input, select, textarea {
    width: 100%;
    padding: 0.75rem;
    border: 1px solid #ddd;
    border-radius: 4px;
    transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

input:focus, select:focus, textarea:focus {
    border-color: #0066cc;
    box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.25);
    outline: none;
}

.checkbox-group {
    display: flex;
    align-items: flex-start;
}

.checkbox-group input {
    width: auto;
    margin-right: 10px;
    margin-top: 5px;
}

.checkbox-group label {
    margin-bottom: 0;
    font-weight: normal;
}

.error-message {
    color: #cc0000;
    font-size: 0.85rem;
    margin-top: 0.25rem;
    display: block;
}

/* ========================================
   6. Hero Section
   ======================================== */

.hero {
    background-color: #f8f9fa;
    text-align: center;
    padding: 5rem 0;
}

.hero h1 {
    margin-bottom: 1rem;
}

.hero p {
    font-size: 1.2rem;
    max-width: 600px;
    margin: 0 auto 2rem;
}

/* ========================================
   7. Features Section
   ======================================== */

.features {
    text-align: center;
}

.feature-item {
    padding: 1.5rem;
    border-radius: 8px;
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.feature-item:hover {
    transform: translateY(-10px);
    box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
}

.feature-item img {
    width: 100%;
    height: 200px;
    object-fit: cover;
    border-radius: 8px;
    margin-bottom: 1rem;
}

/* ========================================
   8. Testimonials Section
   ======================================== */

.testimonials {
    background-color: #f8f9fa;
    text-align: center;
}

.testimonial-slider {
    position: relative;
    max-width: 800px;
    margin: 0 auto;
    overflow: hidden;
}

.testimonial {
    padding: 2rem;
}

.testimonial p {
    font-style: italic;
    font-size: 1.1rem;
    margin-bottom: 1rem;
}

.testimonial cite {
    font-style: normal;
    font-weight: 700;
}

.slider-controls {
    margin-top: 1rem;
}

.prev-btn, .next-btn {
    background: none;
    border: none;
    font-size: 1.5rem;
    cursor: pointer;
    padding: 0.5rem 1rem;
    margin: 0 0.5rem;
    transition: color 0.3s ease;
}

.prev-btn:hover, .next-btn:hover {
    color: #0066cc;
}

/* ========================================
   9. CTA Section
   ======================================== */

.cta {
    text-align: center;
    padding: 5rem 0;
    background-color: #0066cc;
    color: white;
}

.cta h2 {
    color: white;
}

.cta .btn {
    background-color: white;
    color: #0066cc;
    border-color: white;
}

.cta .btn:hover {
    background-color: transparent;
    color: white;
}

/* ========================================
   10. Footer Styles
   ======================================== */

footer {
    background-color: #333;
    color: white;
    padding: 3rem 0 1.5rem;
}

footer h3 {
    color: white;
    margin-bottom: 1.5rem;
    font-size: 1.2rem;
}

footer a {
    color: #ccc;
}

footer a:hover {
    color: white;
}

.social-links {
    display: flex;
    gap: 1rem;
}

.copyright {
    text-align: center;
    padding-top: 1.5rem;
    border-top: 1px solid rgba(255, 255, 255, 0.1);
}

/* ========================================
   11. About Page Styles
   ======================================== */

.about-intro {
    text-align: center;
    max-width: 800px;
    margin: 0 auto 3rem;
}

.team-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 2rem;
}

.team-member {
    text-align: center;
}

.team-member img {
    width: 200px;
    height: 200px;
    object-fit: cover;
    border-radius: 50%;
    margin: 0 auto 1rem;
}

/* ========================================
   12. Services Page Styles
   ======================================== */

.service-item {
    margin-bottom: 3rem;
    padding-bottom: 3rem;
    border-bottom: 1px solid #eee;
}

.service-item:last-child {
    border-bottom: none;
}

.service-item img {
    width: 100%;
    height: 300px;
    object-fit: cover;
    border-radius: 8px;
    margin-bottom: 1.5rem;
}

/* ========================================
   13. Contact Page Styles
   ======================================== */

.contact-info {
    margin-bottom: 3rem;
}

.contact-info-item {
    display: flex;
    align-items: flex-start;
    margin-bottom: 1.5rem;
}

.contact-form {
    background-color: #f8f9fa;
    padding: 3rem 0;
}

.map-container {
    height: 400px;
    margin-top: 2rem;
}

.map-container iframe {
    width: 100%;
    height: 100%;
    border: none;
    border-radius: 8px;
}

/* ========================================
   14. Utilities
   ======================================== */

.text-center {
    text-align: center;
}

.mt-1 { margin-top: 1rem; }
.mt-2 { margin-top: 2rem; }
.mt-3 { margin-top: 3rem; }

.mb-1 { margin-bottom: 1rem; }
.mb-2 { margin-bottom: 2rem; }
.mb-3 { margin-bottom: 3rem; }

.hidden {
    display: none;
}

CSS Explanation:

  • The CSS begins with a reset to normalize browser styles and set consistent defaults.
  • The code is organized into logical sections with clear comments for maintainability.
  • Global typography styles establish a consistent hierarchy using the imported Google Fonts.
  • The .container class creates a responsive wrapper with consistent padding.
  • The mobile menu is initially hidden and appears when the .active class is added via JavaScript.
  • Buttons have hover and focus states for better interactivity.
  • Form elements are styled with clear focus states for accessibility.
  • Each section has specific styles to create visual variety and structure.
  • Utility classes provide quick styling options for common needs.

Now, let's create our responsive styles in the responsive.css file:

Responsive Styles (css/responsive.css)

/* 
 * responsive.css
 * Media queries for responsive design
 */

/* ========================================
   Media Queries
   ======================================== */

/* Small devices (landscape phones, 576px and up) */
@media screen and (min-width: 576px) {
    h1 {
        font-size: 3rem;
    }
    
    h2 {
        font-size: 2.25rem;
    }
    
    h3 {
        font-size: 1.75rem;
    }
}

/* Medium devices (tablets, 768px and up) */
@media screen and (min-width: 768px) {
    /* Grid layouts */
    .feature-grid {
        grid-template-columns: repeat(2, 1fr);
    }
    
    .footer-grid {
        grid-template-columns: repeat(2, 1fr);
    }
    
    .team-grid {
        grid-template-columns: repeat(2, 1fr);
    }
    
    /* Hero section */
    .hero {
        padding: 6rem 0;
    }
    
    /* Service items */
    .service-item {
        display: flex;
        align-items: center;
        gap: 2rem;
    }
    
    .service-item:nth-child(even) {
        flex-direction: row-reverse;
    }
    
    .service-item img {
        width: 40%;
        margin-bottom: 0;
    }
    
    .service-content {
        width: 60%;
    }
}

/* Large devices (desktops, 992px and up) */
@media screen and (min-width: 992px) {
    /* Header and navigation */
    .mobile-menu-toggle {
        display: none;
    }
    
    .nav-menu {
        position: static;
        display: flex;
        transform: none;
        opacity: 1;
        visibility: visible;
        box-shadow: none;
        padding: 0;
    }
    
    .nav-menu li {
        margin: 0 0 0 1.5rem;
    }
    
    /* Grid layouts */
    .feature-grid {
        grid-template-columns: repeat(3, 1fr);
    }
    
    .footer-grid {
        grid-template-columns: repeat(4, 1fr);
    }
    
    .team-grid {
        grid-template-columns: repeat(3, 1fr);
    }
    
    /* Contact layout */
    .contact-page-layout {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 2rem;
    }
}

/* Extra large devices (large desktops, 1200px and up) */
@media screen and (min-width: 1200px) {
    h1 {
        font-size: 3.5rem;
    }
    
    h2 {
        font-size: 2.5rem;
    }
    
    h3 {
        font-size: 2rem;
    }
    
    .container {
        padding: 0;
    }
    
    .hero {
        padding: 8rem 0;
    }
}

Responsive CSS Explanation:

  • We use a mobile-first approach, starting with styles for small screens and adding complexity for larger screens.
  • Each media query targets a common breakpoint (576px, 768px, 992px, 1200px).
  • At 768px (tablet), we introduce two-column layouts and more spacing.
  • At 992px (desktop), we transform the mobile menu into a horizontal navigation bar and create three or four-column layouts.
  • Flexible layouts like CSS Grid adapt the number of columns based on screen size.
  • Typography scales up for larger screens for better readability.

Adding JavaScript Interactivity

Now, let's implement some JavaScript features. First, the main script that handles the mobile navigation:

Main JavaScript (js/main.js)

/* 
 * main.js
 * Main JavaScript functionality for the website
 */

// Wait for the DOM to be fully loaded
document.addEventListener('DOMContentLoaded', function() {
    // Mobile navigation toggle
    const menuToggle = document.querySelector('.mobile-menu-toggle');
    const navMenu = document.querySelector('.nav-menu');
    
    if (menuToggle && navMenu) {
        // Toggle mobile menu when hamburger is clicked
        menuToggle.addEventListener('click', function() {
            navMenu.classList.toggle('active');
            
            // Toggle hamburger to X animation
            const bars = menuToggle.querySelectorAll('span');
            bars.forEach(bar => bar.classList.toggle('active'));
            
            // Toggle aria-expanded attribute for accessibility
            const isExpanded = navMenu.classList.contains('active');
            menuToggle.setAttribute('aria-expanded', isExpanded);
        });
        
        // Close mobile menu when clicking outside
        document.addEventListener('click', function(event) {
            if (!navMenu.contains(event.target) && !menuToggle.contains(event.target) && navMenu.classList.contains('active')) {
                navMenu.classList.remove('active');
                const bars = menuToggle.querySelectorAll('span');
                bars.forEach(bar => bar.classList.remove('active'));
                menuToggle.setAttribute('aria-expanded', false);
            }
        });
    }
    
    // Add active class to current navigation link
    const currentPage = window.location.pathname.split('/').pop() || 'index.html';
    const navLinks = document.querySelectorAll('.nav-menu a');
    
    navLinks.forEach(link => {
        if (link.getAttribute('href') === currentPage) {
            link.classList.add('active');
        }
    });
});

JavaScript Explanation:

  • The script waits for the DOM to be fully loaded using the DOMContentLoaded event.
  • It selects the mobile menu toggle button and the navigation menu.
  • It adds a click event listener to toggle the menu's visibility.
  • The aria-expanded attribute is updated for accessibility.
  • A click event listener on the document closes the menu when clicking outside.
  • The script also highlights the current page in the navigation by adding the active class.

Next, let's create a testimonial slider:

Testimonial Slider (js/slider.js)

/* 
 * slider.js
 * Testimonial slider functionality
 */

document.addEventListener('DOMContentLoaded', function() {
    // Select slider elements
    const slider = document.querySelector('.testimonial-slider');
    
    // Only run if slider exists on the page
    if (slider) {
        const testimonials = slider.querySelectorAll('.testimonial');
        const prevBtn = slider.querySelector('.prev-btn');
        const nextBtn = slider.querySelector('.next-btn');
        
        // If testimonials exist and there's more than one
        if (testimonials.length > 1) {
            // Initialize slider variables
            let currentIndex = 0;
            let interval;
            
            // Function to show a specific testimonial
            function showTestimonial(index) {
                // Hide all testimonials
                testimonials.forEach(testimonial => {
                    testimonial.style.display = 'none';
                });
                
                // Show the current testimonial
                testimonials[index].style.display = 'block';
                
                // Update current index
                currentIndex = index;
            }
            
            // Function to show next testimonial
            function nextTestimonial() {
                currentIndex = (currentIndex + 1) % testimonials.length;
                showTestimonial(currentIndex);
            }
            
            // Function to show previous testimonial
            function prevTestimonial() {
                currentIndex = (currentIndex - 1 + testimonials.length) % testimonials.length;
                showTestimonial(currentIndex);
            }
            
            // Add event listeners to buttons
            if (nextBtn) {
                nextBtn.addEventListener('click', function() {
                    nextTestimonial();
                    resetInterval();
                });
            }
            
            if (prevBtn) {
                prevBtn.addEventListener('click', function() {
                    prevTestimonial();
                    resetInterval();
                });
            }
            
            // Start automatic slider
            function startInterval() {
                interval = setInterval(nextTestimonial, 5000); // Change every 5 seconds
            }
            
            // Reset interval after manual navigation
            function resetInterval() {
                clearInterval(interval);
                startInterval();
            }
            
            // Initialize slider
            showTestimonial(currentIndex);
            startInterval();
            
            // Pause automatic sliding when hovering over the slider
            slider.addEventListener('mouseenter', function() {
                clearInterval(interval);
            });
            
            // Resume automatic sliding when mouse leaves
            slider.addEventListener('mouseleave', function() {
                startInterval();
            });
            
            // Add keyboard navigation for accessibility
            slider.setAttribute('tabindex', '0');
            slider.addEventListener('keydown', function(event) {
                if (event.key === 'ArrowLeft') {
                    prevTestimonial();
                    resetInterval();
                } else if (event.key === 'ArrowRight') {
                    nextTestimonial();
                    resetInterval();
                }
            });
        }
    }
});

JavaScript Explanation:

  • This script creates a simple testimonial slider that rotates through testimonials.
  • It shows one testimonial at a time and provides previous/next buttons for navigation.
  • The slider automatically advances every 5 seconds, but pauses on hover.
  • Keyboard navigation is implemented for accessibility (left/right arrow keys).
  • The script includes checks to only run if the slider exists on the current page.

Finally, let's implement form validation for the contact form:

Form Validation (js/validation.js)

/* 
 * validation.js
 * Contact form validation
 */

document.addEventListener('DOMContentLoaded', function() {
    // Select the form element
    const contactForm = document.getElementById('contactForm');
    
    // Only run if the form exists on the page
    if (contactForm) {
        // Form fields
        const nameInput = document.getElementById('name');
        const emailInput = document.getElementById('email');
        const phoneInput = document.getElementById('phone');
        const subjectInput = document.getElementById('subject');
        const messageInput = document.getElementById('message');
        const consentInput = document.getElementById('consent');
        
        // Error message elements
        const nameError = document.getElementById('nameError');
        const emailError = document.getElementById('emailError');
        const phoneError = document.getElementById('phoneError');
        const subjectError = document.getElementById('subjectError');
        const messageError = document.getElementById('messageError');
        const consentError = document.getElementById('consentError');
        
        // Validation patterns
        const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
        const phonePattern = /^[\d\s()+.-]{7,20}$/; // Basic phone format
        
        // Add form submission event listener
        contactForm.addEventListener('submit', function(event) {
            // Prevent default form submission
            event.preventDefault();
            
            // Track form validity
            let isValid = true;
            
            // Reset previous error messages
            clearErrors();
            
            // Validate name
            if (!nameInput.value.trim()) {
                showError(nameError, 'Please enter your name');
                isValid = false;
            }
            
            // Validate email
            if (!emailInput.value.trim()) {
                showError(emailError, 'Please enter your email address');
                isValid = false;
            } else if (!emailPattern.test(emailInput.value)) {
                showError(emailError, 'Please enter a valid email address');
                isValid = false;
            }
            
            // Validate phone (if provided)
            if (phoneInput.value.trim() && !phonePattern.test(phoneInput.value)) {
                showError(phoneError, 'Please enter a valid phone number');
                isValid = false;
            }
            
            // Validate subject
            if (!subjectInput.value) {
                showError(subjectError, 'Please select a subject');
                isValid = false;
            }
            
            // Validate message
            if (!messageInput.value.trim()) {
                showError(messageError, 'Please enter your message');
                isValid = false;
            } else if (messageInput.value.trim().length < 10) {
                showError(messageError, 'Your message must be at least 10 characters');
                isValid = false;
            }
            
            // Validate consent
            if (!consentInput.checked) {
                showError(consentError, 'You must agree to the terms');
                isValid = false;
            }
            
            // If form is valid, submit (or show success message for this example)
            if (isValid) {
                // In a real application, you would submit the form data to a server
                // For this example, we'll just show a success message
                contactForm.innerHTML = `
                    

Thank You!

Your message has been sent successfully. We'll get back to you shortly.

`; // Scroll to the success message contactForm.scrollIntoView({ behavior: 'smooth' }); } }); // Function to show error message function showError(errorElement, message) { if (errorElement) { errorElement.textContent = message; } } // Function to clear all error messages function clearErrors() { const errorElements = [nameError, emailError, phoneError, subjectError, messageError, consentError]; errorElements.forEach(element => { if (element) { element.textContent = ''; } }); } // Real-time validation on input const formInputs = [nameInput, emailInput, phoneInput, subjectInput, messageInput]; formInputs.forEach(input => { if (input) { input.addEventListener('input', function() { // Clear the error message when user starts typing const errorId = input.id + 'Error'; const errorElement = document.getElementById(errorId); if (errorElement) { errorElement.textContent = ''; } }); } }); // Special handling for checkbox if (consentInput) { consentInput.addEventListener('change', function() { if (consentError) { consentError.textContent = ''; } }); } } });

JavaScript Explanation:

  • This script implements form validation for the contact form.
  • It checks for required fields, proper email format, minimum message length, and consent checkbox.
  • Error messages appear below each invalid field when the form is submitted.
  • Real-time validation clears error messages as the user corrects issues.
  • A success message replaces the form when it's successfully submitted.
  • Regular expressions validate email and phone formats.

Testing and Optimization

After building your website, it's crucial to test it thoroughly:

  1. Cross-Browser Testing: Test in Chrome, Firefox, Safari, and Edge to ensure consistent rendering.
  2. Responsive Testing: Use browser developer tools to test various screen sizes and orientations.
  3. Functionality Testing: Verify all links, form validation, and JavaScript features work correctly.
  4. Accessibility Testing: Check keyboard navigation, screen reader compatibility, and appropriate contrast.
  5. Performance Optimization:
    • Optimize images by compressing them without losing quality
    • Minify CSS and JavaScript files
    • Check for any render-blocking resources

Use browser developer tools to identify and fix any issues that arise during testing.

Step 4: Looking Back and Learning

In the final step of Polya's method, we reflect on our work and consider what we've learned.

Project Review Checklist

Use this checklist to evaluate your completed website:

Learning Outcomes

By completing this project, you've demonstrated your ability to:

What Could Be Improved?

As with any project, there's always room for improvement. Here are some ways you could enhance your website in the future:

Beyond the Basics: Advanced Concepts

If you enjoyed this project and want to take your web development skills further, consider exploring these advanced topics:

Advanced CSS Techniques

Example: CSS Animation with Keyframes

/* Define the animation */
@keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Apply the animation to elements */
.animate-on-scroll {
    opacity: 0;
}

.animate-on-scroll.visible {
    animation: fadeIn 0.8s ease forwards;
}

Advanced JavaScript Patterns

Example: Intersection Observer for Scroll Animations

// Create an observer
const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
        // If the element is in view
        if (entry.isIntersecting) {
            // Add the 'visible' class
            entry.target.classList.add('visible');
            // Stop observing the element
            observer.unobserve(entry.target);
        }
    });
}, {
    threshold: 0.1 // Trigger when 10% of the element is visible
});

// Observe all elements with the 'animate-on-scroll' class
document.querySelectorAll('.animate-on-scroll').forEach(element => {
    observer.observe(element);
});

Performance Optimization

Example: Responsive Images

<picture>
    <source srcset="image-large.webp" media="(min-width: 1024px)" type="image/webp">
    <source srcset="image-medium.webp" media="(min-width: 640px)" type="image/webp">
    <source srcset="image-small.webp" type="image/webp">
    <img src="image-fallback.jpg" alt="Description" loading="lazy">
</picture>

Accessibility Enhancements

Example: Accessible Modal Dialog

<div id="modal" class="modal" role="dialog" aria-labelledby="modalTitle" aria-modal="true" aria-hidden="true">
    <div class="modal-content">
        <h2 id="modalTitle">Modal Title</h2>
        <p>Modal content goes here.</p>
        <button class="close-button" aria-label="Close dialog">×</button>
    </div>
</div>

Additional Resources

Documentation and References

Tools

Learning Platforms

Community Forums

Final Thoughts

Creating a complete, responsive website from scratch is a significant achievement! You've applied HTML, CSS, and JavaScript together to build a professional web presence that works across devices and provides a good user experience.

Remember that web development is an iterative process. Even professional websites are continually refined and improved. Don't worry if your site isn't perfect—focus on what you've learned and the skills you've developed.

This project represents a solid foundation for your web development journey. As you continue to learn and practice, you'll build on these basics to create increasingly sophisticated and polished websites. Each new technique you master opens up new possibilities for creativity and functionality.

Congratulations on completing this comprehensive weekend project! Be sure to add it to your portfolio as a demonstration of your frontend web development skills.

What's Next?

As we move forward in the course, we'll build on these fundamentals to explore:

  • Server-side programming with Python and Flask
  • Database integration and management
  • Full-stack web application development
  • API creation and consumption
  • Deployment and hosting

These skills will further enhance your ability to create dynamic, interactive web applications.