Skip to content
IRC-CodingIRC-Coding
web development basicsHTML CSS JavaScriptDOM manipulationresponsive designfrontend

Web Development Basics: HTML, CSS, JavaScript & DOM

Learn web development fundamentals: HTML5, CSS3, JavaScript ES6+, DOM manipulation, and responsive design with practical examples.

S

schutzgeist

21 min read
Web Development Basics: HTML, CSS, JavaScript & DOM

Web Development Fundamentals: HTML, CSS, JavaScript, DOM Manipulation & Responsive Design

This guide offers a comprehensive introduction to web development fundamentals – covering HTML5, CSS3, JavaScript ES6+, DOM manipulation, and responsive design with practical examples.

In a Nutshell

Web development rests on three core technologies: HTML for structure, CSS for styling, and JavaScript for interactivity. Responsive design ensures your site looks great across all devices.

Core Technical Overview

Web development is the process of building web applications by combining markup, style, and programming languages.

Core Technologies:

HTML5 (HyperText Markup Language)

  • Structure: Semantic markup of content
  • Elements: Header, nav, main, section, article, footer
  • Forms: Input types, validation, accessibility
  • Multimedia: Audio, video, canvas, SVG

CSS3 (Cascading Style Sheets)

  • Styling: Colors, typefaces, layout, animations
  • Layout: Flexbox, Grid, positioning, responsive design
  • Pseudo-classes: :hover, :active, :focus, :nth-child
  • Media Queries: Responsive design, breakpoints

JavaScript ES6+

  • Interactivity: DOM manipulation, event handling
  • Features: Arrow functions, template literals, destructuring
  • DOM API: Select, manipulate, and listen to elements
  • Asynchronous: Promises, async/await, Fetch API

Key Takeaways

  • HTML5: Semantic markup language for web content
  • CSS3: Stylesheet language for design and layout
  • JavaScript: Programming language for web interactivity
  • DOM: Document Object Model for dynamic manipulation
  • Responsive Design: Adaptation to different screen sizes
  • Media Queries: CSS conditions for device properties
  • Flexbox/Grid: Modern layout techniques
  • Industry Standard: Foundation for all web development roles

Core Components

  1. HTML5: Semantic structure and content
  2. CSS3: Visual design and layout
  3. JavaScript: Dynamic functionality
  4. DOM: Programmable interface
  5. Responsive Design: Cross-device compatibility
  6. Accessibility: Barrier-free web development
  7. Performance: Load times and optimization
  8. Best Practices: Modern development standards

Practical Examples

1. HTML5 Basic Structure

<!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="Modern web application with HTML5, CSS3 and JavaScript">
    <title>Web Development Demo</title>
    
    <!-- CSS -->
    <link rel="stylesheet" href="styles.css">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap" rel="stylesheet">
    
    <!-- Favicon -->
    <link rel="icon" type="image/svg+xml" href="favicon.svg">
    
    <!-- Open Graph Meta Tags -->
    <meta property="og:title" content="Web Development Demo">
    <meta property="og:description" content="Modern web application">
    <meta property="og:type" content="website">
</head>
<body>
    <!-- Skip Navigation for Accessibility -->
    <a href="#main-content" class="skip-link">Skip to main content</a>
    
    <!-- Header with Navigation -->
    <header class="header">
        <nav class="nav" aria-label="Main navigation">
            <div class="nav-container">
                <div class="nav-brand">
                    <a href="#" class="brand-link">
                        <img src="logo.svg" alt="Logo" class="brand-logo">
                        <span class="brand-text">WebDev</span>
                    </a>
                </div>
                
                <button class="nav-toggle" aria-expanded="false" aria-controls="nav-menu">
                    <span class="hamburger"></span>
                    <span class="visually-hidden">Menu</span>
                </button>
                
                <ul id="nav-menu" class="nav-menu">
                    <li><a href="#home" class="nav-link">Home</a></li>
                    <li><a href="#features" class="nav-link">Features</a></li>
                    <li><a href="#contact" class="nav-link">Contact</a></li>
                </ul>
            </div>
        </nav>
    </header>
    
    <!-- Main Content -->
    <main id="main-content" class="main">
        <!-- Hero Section -->
        <section class="hero" id="home">
            <div class="container">
                <h1 class="hero-title">Modern Web Development</h1>
                <p class="hero-subtitle">HTML5, CSS3 and JavaScript in action</p>
                
                <div class="hero-actions">
                    <button class="btn btn-primary" data-action="start">Get Started</button>
                    <a href="#features" class="btn btn-secondary">Learn more</a>
                </div>
                
                <!-- Interactive Demo -->
                <div class="demo-section">
                    <div class="demo-container">
                        <canvas id="demo-canvas" width="400" height="200"></canvas>
                        <div class="demo-controls">
                            <button class="demo-btn" data-action="clear">Clear</button>
                            <button class="demo-btn" data-action="animate">Animate</button>
                            <input type="color" id="color-picker" value="#3b82f6">
                        </div>
                    </div>
                </div>
            </div>
        </section>
        
        <!-- Features Section -->
        <section class="features" id="features">
            <div class="container">
                <h2 class="section-title">Features</h2>
                
                <div class="features-grid">
                    <article class="feature-card">
                        <div class="feature-icon">
                            <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                <path d="M12 2L2 7v10c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V7l-10-5z"/>
                            </svg>
                        </div>
                        <h3 class="feature-title">Security</h3>
                        <p class="feature-description">Modern security standards and best practices</p>
                    </article>
                    
                    <article class="feature-card">
                        <div class="feature-icon">
                            <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                <rect x="2" y="3" width="20" height="14" rx="2" ry="2"/>
                                <line x1="8" y1="21" x2="16" y2="21"/>
                                <line x1="12" y1="17" x2="12" y2="21"/>
                            </svg>
                        </div>
                        <h3 class="feature-title">Responsive</h3>
                        <p class="feature-description">Optimal display across all devices</p>
                    </article>
                    
                    <article class="feature-card">
                        <div class="feature-icon">
                            <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                <path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/>
                            </svg>
                        </div>
                        <h3 class="feature-title">Performance</h3>
                        <p class="feature-description">Fast load times and smooth interactions</p>
                    </article>
                </div>
            </div>
        </section>
        
        <!-- Contact Form -->
        <section class="contact" id="contact">
            <div class="container">
                <h2 class="section-title">Contact</h2>
                
                <form class="contact-form" novalidate>
                    <div class="form-group">
                        <label for="name" class="form-label">Name *</label>
                        <input type="text" id="name" name="name" class="form-input" required>
                        <span class="form-error" id="name-error">Please enter your name</span>
                    </div>
                    
                    <div class="form-group">
                        <label for="email" class="form-label">Email *</label>
                        <input type="email" id="email" name="email" class="form-input" required>
                        <span class="form-error" id="email-error">Please enter a valid email</span>
                    </div>
                    
                    <div class="form-group">
                        <label for="message" class="form-label">Message</label>
                        <textarea id="message" name="message" class="form-textarea" rows="4"></textarea>
                    </div>
                    
                    <div class="form-actions">
                        <button type="submit" class="btn btn-primary">Send</button>
                        <button type="reset" class="btn btn-secondary">Reset</button>
                    </div>
                </form>
            </div>
        </section>
    </main>
    
    <!-- Footer -->
    <footer class="footer">
        <div class="container">
            <p>&copy; 2024 Web Development Demo. All rights reserved.</p>
            <div class="footer-links">
                <a href="#impressum">Imprint</a>
                <a href="#datenschutz">Privacy</a>
            </div>
        </div>
    </footer>
    
    <!-- JavaScript -->
    <script src="script.js"></script>
</body>
</html>

2. CSS3 with Responsive Design

/* CSS Reset und Basis-Styles */
*,
*::before,
*::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

/* CSS Custom Properties (Variables) */
:root {
    /* Farben */
    --color-primary: #3b82f6;
    --color-primary-dark: #2563eb;
    --color-primary-light: #60a5fa;
    --color-secondary: #64748b;
    --color-success: #10b981;
    --color-error: #ef4444;
    --color-warning: #f59e0b;
    
    /* Neutral */
    --color-white: #ffffff;
    --color-gray-50: #f8fafc;
    --color-gray-100: #f1f5f9;
    --color-gray-900: #0f172a;
    
    /* Typography */
    --font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --font-size-xs: 0.75rem;
    --font-size-sm: 0.875rem;
    --font-size-base: 1rem;
    --font-size-lg: 1.125rem;
    --font-size-xl: 1.25rem;
    --font-size-2xl: 1.5rem;
    --font-size-3xl: 1.875rem;
    --font-size-4xl: 2.25rem;
    
    /* Spacing */
    --spacing-xs: 0.25rem;
    --spacing-sm: 0.5rem;
    --spacing-md: 1rem;
    --spacing-lg: 1.5rem;
    --spacing-xl: 2rem;
    --spacing-2xl: 3rem;
    
    /* Border Radius */
    --radius-sm: 0.25rem;
    --radius-md: 0.5rem;
    --radius-lg: 1rem;
    --radius-full: 9999px;
    
    /* Shadows */
    --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
    --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
    --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
    --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1);
    
    /* Transitions */
    --transition-fast: 150ms ease-in-out;
    --transition-normal: 300ms ease-in-out;
    --transition-slow: 500ms ease-in-out;
}

/* Base Styles */
html {
    font-size: 16px;
    scroll-behavior: smooth;
}

body {
    font-family: var(--font-family);
    font-size: var(--font-size-base);
    line-height: 1.6;
    color: var(--color-gray-900);
    background-color: var(--color-white);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Utility Classes */
.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 var(--spacing-md);
}

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.skip-link {
    position: absolute;
    top: -40px;
    left: 0;
    background: var(--color-primary);
    color: var(--color-white);
    padding: var(--spacing-sm) var(--spacing-md);
    text-decoration: none;
    border-radius: var(--radius-md);
    z-index: 100;
    transition: top var(--transition-fast);
}

.skip-link:focus {
    top: var(--spacing-sm);
}

/* Header & Navigation */
.header {
    background-color: var(--color-white);
    box-shadow: var(--shadow-sm);
    position: sticky;
    top: 0;
    z-index: 50;
}

.nav-container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--spacing-md) 0;
}

.brand-link {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    text-decoration: none;
    color: var(--color-gray-900);
    font-weight: 600;
    transition: color var(--transition-fast);
}

.brand-link:hover {
    color: var(--color-primary);
}

.brand-logo {
    width: 32px;
    height: 32px;
}

.nav-toggle {
    display: none;
    background: none;
    border: none;
    padding: var(--spacing-sm);
    cursor: pointer;
}

.hamburger {
    display: block;
    width: 24px;
    height: 2px;
    background-color: var(--color-gray-900);
    position: relative;
    transition: background-color var(--transition-fast);
}

.hamburger::before,
.hamburger::after {
    content: '';
    position: absolute;
    width: 24px;
    height: 2px;
    background-color: var(--color-gray-900);
    transition: transform var(--transition-fast);
}

.hamburger::before {
    top: -8px;
}

.hamburger::after {
    top: 8px;
}

.nav-toggle[aria-expanded="true"] .hamburger {
    background-color: transparent;
}

.nav-toggle[aria-expanded="true"] .hamburger::before {
    transform: rotate(45deg);
    top: 0;
}

.nav-toggle[aria-expanded="true"] .hamburger::after {
    transform: rotate(-45deg);
    top: 0;
}

.nav-menu {
    display: flex;
    list-style: none;
    gap: var(--spacing-lg);
}

.nav-link {
    text-decoration: none;
    color: var(--color-gray-700);
    font-weight: 500;
    padding: var(--spacing-sm) var(--spacing-md);
    border-radius: var(--radius-md);
    transition: all var(--transition-fast);
}

.nav-link:hover {
    color: var(--color-primary);
    background-color: var(--color-gray-50);
}

/* Hero Section */
.hero {
    background: linear-gradient(135deg, var(--color-gray-50) 0%, var(--color-white) 100%);
    padding: var(--spacing-2xl) 0;
    text-align: center;
}

.hero-title {
    font-size: var(--font-size-4xl);
    font-weight: 700;
    color: var(--color-gray-900);
    margin-bottom: var(--spacing-md);
    line-height: 1.2;
}

.hero-subtitle {
    font-size: var(--font-size-xl);
    color: var(--color-secondary);
    margin-bottom: var(--spacing-xl);
    max-width: 600px;
    margin-left: auto;
    margin-right: auto;
}

.hero-actions {
    display: flex;
    gap: var(--spacing-md);
    justify-content: center;
    margin-bottom: var(--spacing-2xl);
}

/* Buttons */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: var(--spacing-md) var(--spacing-lg);
    font-size: var(--font-size-base);
    font-weight: 600;
    text-decoration: none;
    border: none;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all var(--transition-fast);
    min-width: 120px;
}

.btn-primary {
    background-color: var(--color-primary);
    color: var(--color-white);
}

.btn-primary:hover {
    background-color: var(--color-primary-dark);
    transform: translateY(-2px);
    box-shadow: var(--shadow-lg);
}

.btn-secondary {
    background-color: var(--color-gray-100);
    color: var(--color-gray-900);
}

.btn-secondary:hover {
    background-color: var(--color-gray-200);
    transform: translateY(-2px);
}

/* Demo Section */
.demo-section {
    margin-top: var(--spacing-2xl);
}

.demo-container {
    background-color: var(--color-white);
    border-radius: var(--radius-lg);
    padding: var(--spacing-lg);
    box-shadow: var(--shadow-md);
    max-width: 500px;
    margin: 0 auto;
}

#demo-canvas {
    border: 2px solid var(--color-gray-200);
    border-radius: var(--radius-md);
    width: 100%;
    height: auto;
    display: block;
    margin-bottom: var(--spacing-md);
}

.demo-controls {
    display: flex;
    gap: var(--spacing-sm);
    flex-wrap: wrap;
    align-items: center;
}

.demo-btn {
    padding: var(--spacing-sm) var(--spacing-md);
    background-color: var(--color-gray-100);
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: var(--font-size-sm);
    transition: all var(--transition-fast);
}

.demo-btn:hover {
    background-color: var(--color-gray-200);
}

#color-picker {
    width: 50px;
    height: 36px;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
}

/* Features Section */
.features {
    padding: var(--spacing-2xl) 0;
    background-color: var(--color-gray-50);
}

.section-title {
    font-size: var(--font-size-3xl);
    font-weight: 700;
    text-align: center;
    margin-bottom: var(--spacing-2xl);
    color: var(--color-gray-900);
}

.features-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: var(--spacing-xl);
}

.feature-card {
    background-color: var(--color-white);
    padding: var(--spacing-xl);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    text-align: center;
    transition: transform var(--transition-normal), box-shadow var(--transition-normal);
}

.feature-card:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow-xl);
}

.feature-icon {
    display: flex;
    justify-content: center;
    margin-bottom: var(--spacing-lg);
    color: var(--color-primary);
}

.feature-title {
    font-size: var(--font-size-xl);
    font-weight: 600;
    margin-bottom: var(--spacing-md);
    color: var(--color-gray-900);
}

.feature-description {
    color: var(--color-secondary);
    line-height: 1.6;
}

/* Contact Form */
.contact {
    padding: var(--spacing-2xl) 0;
}

.contact-form {
    max-width: 600px;
    margin: 0 auto;
}

.form-group {
    margin-bottom: var(--spacing-lg);
}

.form-label {
    display: block;
    font-weight: 600;
    margin-bottom: var(--spacing-sm);
    color: var(--color-gray-900);
}

.form-input,
.form-textarea {
    width: 100%;
    padding: var(--spacing-md);
    border: 2px solid var(--color-gray-200);
    border-radius: var(--radius-md);
    font-size: var(--font-size-base);
    transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.form-input:focus,
.form-textarea:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px rgb(59 130 246 / 0.1);
}

.form-input:invalid,
.form-textarea:invalid {
    border-color: var(--color-error);
}

.form-error {
    display: none;
    color: var(--color-error);
    font-size: var(--font-size-sm);
    margin-top: var(--spacing-xs);
}

.form-input:invalid ~ .form-error {
    display: block;
}

.form-actions {
    display: flex;
    gap: var(--spacing-md);
    justify-content: flex-end;
}

/* Footer */
.footer {
    background-color: var(--color-gray-900);
    color: var(--color-gray-100);
    padding: var(--spacing-xl) 0;
    text-align: center;
}

.footer-links {
    margin-top: var(--spacing-md);
    display: flex;
    gap: var(--spacing-lg);
    justify-content: center;
}

.footer-links a {
    color: var(--color-gray-400);
    text-decoration: none;
    transition: color var(--transition-fast);
}

.footer-links a:hover {
    color: var(--color-white);
}

/* Responsive Design */

/* Mobile First Approach */
/* Small Tablets and Large Phones */
@media (min-width: 640px) {
    .container {
        padding: 0 var(--spacing-lg);
    }
    
    .hero-title {
        font-size: var(--font-size-5xl);
    }
    
    .features-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* Tablets */
@media (min-width: 768px) {
    .nav-toggle {
        display: none;
    }
    
    .nav-menu {
        display: flex;
    }
    
    .hero-actions {
        flex-direction: row;
    }
    
    .demo-controls {
        justify-content: center;
    }
}

/* Desktop */
@media (min-width: 1024px) {
    .hero {
        padding: var(--spacing-3xl) 0;
    }
    
    .features-grid {
        grid-template-columns: repeat(3, 1fr);
    }
    
    .form-actions {
        justify-content: flex-start;
    }
}

/* Large Desktop */
@media (min-width: 1280px) {
    .container {
        padding: 0 var(--spacing-xl);
    }
    
    .hero-title {
        font-size: var(--font-size-6xl);
    }
}

/* Dark Mode Support */
@media (prefers-color-scheme: dark) {
    :root {
        --color-white: #0f172a;
        --color-gray-50: #1e293b;
        --color-gray-100: #334155;
        --color-gray-900: #f8fafc;
        --color-gray-700: #cbd5e1;
        --color-gray-200: #475569;
    }
    
    .header {
        background-color: var(--color-gray-50);
    }
    
    .hero {
        background: linear-gradient(135deg, var(--color-gray-50) 0%, var(--color-white) 100%);
    }
    
    .features {
        background-color: var(--color-white);
    }
    
    .btn-secondary {
        background-color: var(--color-gray-200);
        color: var(--color-gray-900);
    }
    
    .btn-secondary:hover {
        background-color: var(--color-gray-100);
    }
}

/* Print Styles */
@media print {
    .nav-toggle,
    .hero-actions,
    .demo-section,
    .contact-form {
        display: none;
    }
    
    .hero {
        padding: var(--spacing-lg) 0;
    }
    
    body {
        font-size: 12pt;
        line-height: 1.4;
    }
    
    h1, h2, h3 {
        page-break-after: avoid;
    }
    
    .feature-card {
        break-inside: avoid;
    }
}

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

.fade-in {
    animation: fadeIn 0.6s ease-out;
}

@keyframes pulse {
    0%, 100% {
        transform: scale(1);
    }
    50% {
        transform: scale(1.05);
    }
}

.pulse {
    animation: pulse 2s infinite;
}

/* Focus Styles for Accessibility */
.btn:focus,
.nav-link:focus,
.form-input:focus,
.form-textarea:focus {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

/* High Contrast Mode */
@media (prefers-contrast: high) {
    :root {
        --color-primary: #0000ff;
        --color-secondary: #000000;
        --color-gray-900: #000000;
        --color-gray-100: #ffffff;
    }
    
    .btn {
        border: 2px solid currentColor;
    }
    
    .form-input,
    .form-textarea {
        border-width: 3px;
    }
}

/* Reduced Motion */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

3. JavaScript ES6+ with DOM Manipulation

// Modern JavaScript with ES6+ features

// Select DOM elements
const elements = {
    // Navigation
    navToggle: document.querySelector('.nav-toggle'),
    navMenu: document.querySelector('#nav-menu'),
    navLinks: document.querySelectorAll('.nav-link'),
    
    // Hero Section
    heroTitle: document.querySelector('.hero-title'),
    heroActions: document.querySelector('.hero-actions'),
    
    // Demo
    canvas: document.querySelector('#demo-canvas'),
    demoButtons: document.querySelectorAll('.demo-btn'),
    colorPicker: document.querySelector('#color-picker'),
    
    // Form
    contactForm: document.querySelector('.contact-form'),
    formInputs: document.querySelectorAll('.form-input'),
    
    // Features
    featureCards: document.querySelectorAll('.feature-card')
};

// State Management
const state = {
    isNavOpen: false,
    currentColor: '#3b82f6',
    isDrawing: false,
    lastX: 0,
    lastY: 0
};

// Utility Functions
const utils = {
    // Debounce for performance
    debounce(func, wait) {
        let timeout;
        return function executedFunction(...args) {
            const later = () => {
                clearTimeout(timeout);
                func(...args);
            };
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
        };
    },
    
    // Throttle for events
    throttle(func, limit) {
        let inThrottle;
        return function() {
            const args = arguments;
            const context = this;
            if (!inThrottle) {
                func.apply(context, args);
                inThrottle = true;
                setTimeout(() => inThrottle = false, limit);
            }
        };
    },
    
    // Fade in element with animation
    animateIn(element, animation = 'fade-in') {
        element.style.opacity = '0';
        element.classList.add(animation);
        
        // Force reflow
        element.offsetHeight;
        
        element.style.opacity = '1';
        
        setTimeout(() => {
            element.classList.remove(animation);
            element.style.opacity = '';
        }, 600);
    },
    
    // Smooth scroll to element
    smoothScroll(target) {
        const element = document.querySelector(target);
        if (element) {
            element.scrollIntoView({
                behavior: 'smooth',
                block: 'start'
            });
        }
    },
    
    // Local Storage
    saveToLocalStorage(key, data) {
        try {
            localStorage.setItem(key, JSON.stringify(data));
        } catch (error) {
            console.warn('LocalStorage unavailable:', error);
        }
    },
    
    getFromLocalStorage(key) {
        try {
            const data = localStorage.getItem(key);
            return data ? JSON.parse(data) : null;
        } catch (error) {
            console.warn('LocalStorage read error:', error);
            return null;
        }
    }
};

// Navigation
class Navigation {
    constructor() {
        this.init();
    }
    
    init() {
        // Mobile navigation toggle
        if (elements.navToggle) {
            elements.navToggle.addEventListener('click', this.toggleNav.bind(this));
        }
        
        // Navigation links
        elements.navLinks.forEach(link => {
            link.addEventListener('click', this.handleNavClick.bind(this));
        });
        
        // Close on Escape key
        document.addEventListener('keydown', (e) => {
            if (e.key === 'Escape' && state.isNavOpen) {
                this.closeNav();
            }
        });
        
        // Close on outside click
        document.addEventListener('click', (e) => {
            if (state.isNavOpen && !elements.navMenu.contains(e.target) && !elements.navToggle.contains(e.target)) {
                this.closeNav();
            }
        });
    }
    
    toggleNav() {
        state.isNavOpen = !state.isNavOpen;
        this.updateNavUI();
    }
    
    openNav() {
        state.isNavOpen = true;
        this.updateNavUI();
    }
    
    closeNav() {
        state.isNavOpen = false;
        this.updateNavUI();
    }
    
    updateNavUI() {
        elements.navToggle.setAttribute('aria-expanded', state.isNavOpen);
        elements.navMenu.classList.toggle('nav-open', state.isNavOpen);
        
        // Lock body scroll
        document.body.style.overflow = state.isNavOpen ? 'hidden' : '';
    }
    
    handleNavClick(e) {
        e.preventDefault();
        const href = e.target.getAttribute('href');
        
        if (href && href.startsWith('#')) {
            utils.smoothScroll(href);
            this.closeNav();
        }
    }
}

// Canvas Demo
class CanvasDemo {
    constructor(canvas) {
        this.canvas = canvas;
        this.ctx = canvas.getContext('2d');
        this.init();
    }
    
    init() {
        this.setupCanvas();
        this.bindEvents();
        this.drawInitialContent();
    }
    
    setupCanvas() {
        // High DPI support
        const dpr = window.devicePixelRatio || 1;
        const rect = this.canvas.getBoundingClientRect();
        
        this.canvas.width = rect.width * dpr;
        this.canvas.height = rect.height * dpr;
        
        this.ctx.scale(dpr, dpr);
        
        this.canvas.style.width = rect.width + 'px';
        this.canvas.style.height = rect.height + 'px';
    }
    
    bindEvents() {
        // Mouse events
        this.canvas.addEventListener('mousedown', this.startDrawing.bind(this));
        this.canvas.addEventListener('mousemove', this.draw.bind(this));
        this.canvas.addEventListener('mouseup', this.stopDrawing.bind(this));
        this.canvas.addEventListener('mouseout', this.stopDrawing.bind(this));
        
        // Touch events
        this.canvas.addEventListener('touchstart', this.handleTouch.bind(this));
        this.canvas.addEventListener('touchmove', this.handleTouch.bind(this));
        this.canvas.addEventListener('touchend', this.stopDrawing.bind(this));
        
        // Demo buttons
        elements.demoButtons.forEach(btn => {
            btn.addEventListener('click', this.handleDemoAction.bind(this));
        });
        
        // Color picker
        elements.colorPicker.addEventListener('change', (e) => {
            state.currentColor = e.target.value;
        });
        
        // Window resize
        window.addEventListener('resize', utils.debounce(() => {
            this.setupCanvas();
            this.drawInitialContent();
        }, 250));
    }
    
    startDrawing(e) {
        state.isDrawing = true;
        const rect = this.canvas.getBoundingClientRect();
        state.lastX = e.clientX - rect.left;
        state.lastY = e.clientY - rect.top;
    }
    
    draw(e) {
        if (!state.isDrawing) return;
        
        const rect = this.canvas.getBoundingClientRect();
        const x = e.clientX - rect.left;
        const y = e.clientY - rect.top;
        
        this.ctx.beginPath();
        this.ctx.moveTo(state.lastX, state.lastY);
        this.ctx.lineTo(x, y);
        this.ctx.strokeStyle = state.currentColor;
        this.ctx.lineWidth = 3;
        this.ctx.lineCap = 'round';
        this.ctx.stroke();
        
        state.lastX = x;
        state.lastY = y;
    }
    
    stopDrawing() {
        state.isDrawing = false;
    }
    
    handleTouch(e) {
        e.preventDefault();
        const touch = e.touches[0];
        const mouseEvent = new MouseEvent(e.type === 'touchstart' ? 'mousedown' : 
                                         e.type === 'touchmove' ? 'mousemove' : 'mouseup', {
            clientX: touch.clientX,
            clientY: touch.clientY
        });
        this.canvas.dispatchEvent(mouseEvent);
    }
    
    handleDemoAction(e) {
        const action = e.target.dataset.action;
        
        switch (action) {
            case 'clear':
                this.clearCanvas();
                break;
            case 'animate':
                this.animateShapes();
                break;
        }
    }
    
    clearCanvas() {
        const rect = this.canvas.getBoundingClientRect();
        this.ctx.clearRect(0, 0, rect.width, rect.height);
        this.drawInitialContent();
    }
    
    drawInitialContent() {
        const rect = this.canvas.getBoundingClientRect();
        const centerX = rect.width / 2;
        const centerY = rect.height / 2;
        
        // Welcome text
        this.ctx.font = '20px Inter';
        this.ctx.fillStyle = state.currentColor;
        this.ctx.textAlign = 'center';
        this.ctx.fillText('Draw here!', centerX, centerY);
    }
    
    animateShapes() {
        const rect = this.canvas.getBoundingClientRect();
        let x = 0;
        let y = rect.height / 2;
        let dx = 2;
        let dy = 1;
        let hue = 0;
        
        const animate = () => {
            // Clear trail
            this.ctx.fillStyle = 'rgba(255, 255, 255, 0.1)';
            this.ctx.fillRect(0, 0, rect.width, rect.height);
            
            // Draw circle
            this.ctx.beginPath();
            this.ctx.arc(x, y, 20, 0, Math.PI * 2);
            this.ctx.fillStyle = `hsl(${hue}, 70%, 50%)`;
            this.ctx.fill();
            
            // Update position
            x += dx;
            y += dy;
            hue += 2;
            
            // Bounce off walls
            if (x > rect.width - 20 || x < 20) dx = -dx;
            if (y > rect.height - 20 || y < 20) dy = -dy;
            
            // Continue animation
            if (hue < 360) {
                requestAnimationFrame(animate);
            }
        };
        
        animate();
    }
}

// Form Validation
class FormValidator {
    constructor(form) {
        this.form = form;
        this.init();
    }
    
    init() {
        this.form.addEventListener('submit', this.handleSubmit.bind(this));
        
        // Real-time validation
        elements.formInputs.forEach(input => {
            input.addEventListener('blur', () => this.validateField(input));
            input.addEventListener('input', () => this.clearError(input));
        });
    }
    
    handleSubmit(e) {
        e.preventDefault();
        
        if (this.validateForm()) {
            this.submitForm();
        } else {
            this.showFirstError();
        }
    }
    
    validateForm() {
        let isValid = true;
        
        elements.formInputs.forEach(input => {
            if (!this.validateField(input)) {
                isValid = false;
            }
        });
        
        return isValid;
    }
    
    validateField(field) {
        const value = field.value.trim();
        const type = field.type;
        const isRequired = field.hasAttribute('required');
        let isValid = true;
        
        // Required validation
        if (isRequired && !value) {
            this.showError(field, 'This field is required');
            isValid = false;
        }
        
        // Email validation
        if (type === 'email' && value) {
            const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
            if (!emailRegex.test(value)) {
                this.showError(field, 'Please enter a valid email address');
                isValid = false;
            }
        }
        
        // Name validation
        if (field.id === 'name' && value) {
            if (value.length < 2) {
                this.showError(field, 'Name must be at least 2 characters');
                isValid = false;
            }
        }
        
        if (isValid) {
            this.clearError(field);
        }
        
        return isValid;
    }
    
    showError(field, message) {
        field.classList.add('error');
        const errorElement = document.getElementById(`${field.id}-error`);
        if (errorElement) {
            errorElement.textContent = message;
            errorElement.style.display = 'block';
        }
    }
    
    clearError(field) {
        field.classList.remove('error');
        const errorElement = document.getElementById(`${field.id}-error`);
        if (errorElement) {
            errorElement.style.display = 'none';
        }
    }
    
    showFirstError() {
        const firstError = this.form.querySelector('.form-input.error');
        if (firstError) {
            firstError.focus();
            firstError.scrollIntoView({ behavior: 'smooth', block: 'center' });
        }
    }
    
    submitForm() {
        const formData = new FormData(this.form);
        const data = Object.fromEntries(formData);
        
        // Simulate API call
        this.showLoading();
        
        setTimeout(() => {
            this.showSuccess();
            this.form.reset();
        }, 1500);
    }
    
    showLoading() {
        const submitBtn = this.form.querySelector('button[type="submit"]');
        submitBtn.disabled = true;
        submitBtn.textContent = 'Sending...';
    }
    
    showSuccess() {
        const submitBtn = this.form.querySelector('button[type="submit"]');
        submitBtn.disabled = false;
        submitBtn.textContent = 'Sent!';
        submitBtn.classList.add('success');
        
        setTimeout(() => {
            submitBtn.textContent = 'Send';
            submitBtn.classList.remove('success');
        }, 3000);
        
        // Show success message
        this.showMessage('Message sent successfully!', 'success');
    }
    
    showMessage(text, type = 'info') {
        const message = document.createElement('div');
        message.className = `message message-${type}`;
        message.textContent = text;
        
        this.form.appendChild(message);
        
        utils.animateIn(message);
        
        setTimeout(() => {
            message.remove();
        }, 5000);
    }
}

// Intersection Observer for scroll animations
class ScrollAnimations {
    constructor() {
        this.init();
    }
    
    init() {
        const observerOptions = {
            threshold: 0.1,
            rootMargin: '0px 0px -50px 0px'
        };
        
        const observer = new IntersectionObserver((entries) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    this.animateElement(entry.target);
                    observer.unobserve(entry.target);
                }
            });
        }, observerOptions);
        
        // Observe elements
        elements.featureCards.forEach(card => {
            observer.observe(card);
        });
        
        // Hero animation
        if (elements.heroTitle) {
            utils.animateIn(elements.heroTitle);
        }
        
        if (elements.heroActions) {
            setTimeout(() => {
                utils.animateIn(elements.heroActions);
            }, 300);
        }
    }
    
    animateElement(element) {
        utils.animateIn(element);
        
        // Pulse animation for feature cards
        if (element.classList.contains('feature-card')) {
            setTimeout(() => {
                element.classList.add('pulse');
                setTimeout(() => {
                    element.classList.remove('pulse');
                }, 2000);
            }, 1000);
        }
    }
}

// App Initialization
class App {
    constructor() {
        this.modules = {};
        this.init();
    }
    
    init() {
        // DOM ready check
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', () => this.start());
        } else {
            this.start();
        }
    }
    
    start() {
        console.log('🚀 Web development demo started');
        
        // Initialize modules
        this.modules.navigation = new Navigation();
        
        if (elements.canvas) {
            this.modules.canvas = new CanvasDemo(elements.canvas);
        }
        
        if (elements.contactForm) {
            this.modules.form = new FormValidator(elements.contactForm);
        }
        
        this.modules.scrollAnimations = new ScrollAnimations();
        
        // Performance monitoring
        this.initPerformanceMonitoring();
        
        // Service Worker registration
        this.registerServiceWorker();
    }
    
    initPerformanceMonitoring() {
        // Page load performance
        window.addEventListener('load', () => {
            const perfData = performance.getEntriesByType('navigation')[0];
            const loadTime = perfData.loadEventEnd - perfData.loadEventStart;
            
            console.log(`⚡ Page loaded in ${loadTime}ms`);
            
            // Warn on slow load times
            if (loadTime > 3000) {
                console.warn('⚠️ Slow load time detected');
            }
        });
        
        // Largest Contentful Paint
        new PerformanceObserver((list) => {
            const entries = list.getEntries();
            const lastEntry = entries[entries.length - 1];
            console.log(`🎨 Largest Contentful Paint: ${lastEntry.startTime}ms`);
        }).observe({ entryTypes: ['largest-contentful-paint'] });
    }
    
    async registerServiceWorker() {
        if ('serviceWorker' in navigator) {
            try {
                const registration = await navigator.serviceWorker.register('/sw.js');
                console.log('✅ Service Worker registered:', registration.scope);
            } catch (error) {
                console.log('❌ Service Worker registration failed:', error);
            }
        }
    }
}

// Start app
const app = new App();

// Export for module system
if (typeof module !== 'undefined' && module.exports) {
    module.exports = { App, Navigation, CanvasDemo, FormValidator, ScrollAnimations, utils };
}

4. Service Worker for Offline Functionality

// sw.js - Service Worker for caching and offline functionality

const CACHE_NAME = 'webdev-demo-v1';
const urlsToCache = [
    '/',
    '/index.html',
    '/styles.css',
    '/script.js',
    '/logo.svg',
    '/favicon.svg'
];

// Service Worker Installation
self.addEventListener('install', (event) => {
    console.log('🔧 Service Worker installing...');
    
    event.waitUntil(
        caches.open(CACHE_NAME)
            .then((cache) => {
                console.log('📦 Caching app shell');
                return cache.addAll(urlsToCache);
            })
            .then(() => {
                console.log('✅ App shell cached successfully');
                return self.skipWaiting();
            })
    );
});

// Service Worker Activation
self.addEventListener('activate', (event) => {
    console.log('🔄 Service Worker activating...');
    
    event.waitUntil(
        caches.keys().then((cacheNames) => {
            return Promise.all(
                cacheNames.map((cacheName) => {
                    if (cacheName !== CACHE_NAME) {
                        console.log('🗑️ Deleting old cache:', cacheName);
                        return caches.delete(cacheName);
                    }
                })
            );
        }).then(() => {
            console.log('✅ Service Worker activated');
            return self.clients.claim();
        })
    );
});

// Fetch Events - Network first with cache fallback
self.addEventListener('fetch', (event) => {
    const { request } = event;
    const url = new URL(request.url);
    
    // Only handle HTTP/HTTPS requests
    if (url.protocol !== 'http:' && url.protocol !== 'https:') {
        return;
    }
    
    event.respondWith(
        caches.match(request)
            .then((response) => {
                // Cache hit - return cached response
                if (response) {
                    console.log('📋 Serving from cache:', request.url);
                    return response;
                }
                
                // Network request
                console.log('🌐 Fetching from network:', request.url);
                return fetch(request)
                    .then((response) => {
                        // Check if response is valid
                        if (!response || response.status !== 200 || response.type !== 'basic') {
                            return response;
                        }
                        
                        // Clone response for caching
                        const responseToCache = response.clone();
                        
                        // Cache successful responses
                        if (shouldCache(request)) {
                            caches.open(CACHE_NAME)
                                .then((cache) => {
                                    console.log('💾 Caching new resource:', request.url);
                                    cache.put(request, responseToCache);
                                });
                        }
                        
                        return response;
                    })
                    .catch(() => {
                        // Network failed - try cache
                        console.log('❌ Network failed, trying cache for:', request.url);
                        return caches.match(request);
                    });
            })
    );
});

// Helper function to determine if request should be cached
function shouldCache(request) {
    const url = new URL(request.url);
    
    // Don't cache API calls or external resources
    if (url.pathname.startsWith('/api/') || url.origin !== self.location.origin) {
        return false;
    }
    
    // Cache static assets
    const staticExtensions = ['.css', '.js', '.svg', '.png', '.jpg', '.jpeg', '.webp'];
    const hasStaticExtension = staticExtensions.some(ext => url.pathname.endsWith(ext));
    
    return hasStaticExtension || url.pathname === '/';
}

// Background sync for offline actions
self.addEventListener('sync', (event) => {
    if (event.tag === 'background-sync') {
        console.log('🔄 Background sync triggered');
        
        event.waitUntil(
            // Offline actions can be synchronized here
            new Promise((resolve) => {
                setTimeout(() => {
                    console.log('✅ Background sync completed');
                    resolve();
                }, 1000);
            })
        );
    }
});

// Push notifications
self.addEventListener('push', (event) => {
    console.log('📨 Push message received');
    
    const options = {
        body: event.data.text(),
        icon: '/logo.svg',
        badge: '/favicon.svg',
        vibrate: [100, 50, 100],
        data: {
            dateOfArrival: Date.now(),
            primaryKey: 1
        },
        actions: [
            {
                action: 'explore',
                title: 'Explore',
                icon: '/images/checkmark.png'
            },
            {
                action: 'close',
                title: 'Close',
                icon: '/images/xmark.png'
            }
        ]
    };
    
    event.waitUntil(
        self.registration.showNotification('WebDev Demo', options)
    );
});

// Notification click handling
self.addEventListener('notificationclick', (event) => {
    console.log('🔔 Notification clicked');
    
    event.notification.close();
    
    if (event.action === 'explore') {
        event.waitUntil(
            clients.openWindow('/')
        );
    }
});

HTML5 Semantic Elements Overview

ElementDescriptionUsage
headerHeader areaLogo, navigation
navNavigationMenus, links
mainMain contentPrimary content
sectionSectionThematic blocks
articleArticleSelf-contained content
asideSidebarAdditional information
footerFooterCopyright, links

CSS3 Layout Techniques

Flexbox

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

.item {
    flex: 1 1 300px;
    margin: 1rem;
}

Grid

.grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 2rem;
}

Container Queries

@container (min-width: 400px) {
    .card {
        display: grid;
        grid-template-columns: 1fr 2fr;
    }
}

JavaScript ES6+ Features

Arrow Functions

const add = (a, b) => a + b;
const users = data.map(item => item.name);

Template Literals

const message = `Hello ${name}, you have ${count} messages`;

Destructuring

const {name, email} = user;
const [first, second] = array;

Spread/Rest

const newArray = [...oldArray, newItem];
const sum = (...numbers) => numbers.reduce((a, b) => a + b);

Async/Await

async function fetchData() {
    try {
        const response = await fetch('/api/data');
        const data = await response.json();
        return data;
    } catch (error) {
        console.error('Error:', error);
    }
}

Responsive Design Breakpoints

/* Mobile First Approach */
/* Small Phones */
@media (min-width: 320px) { }

/* Large Phones */
@media (min-width: 480px) { }

/* Tablets */
@media (min-width: 768px) { }

/* Desktop */
@media (min-width: 1024px) { }

/* Large Desktop */
@media (min-width: 1200px) { }

DOM Manipulation Methods

MethodDescriptionExample
querySelectorSelect an elementdocument.querySelector('.class')
createElementCreate an elementdocument.createElement('div')
appendChildAdd an elementparent.appendChild(child)
classListManage classeselement.classList.add('active')
addEventListenerBind an eventelement.addEventListener('click', handler)
setAttributeSet an attributeelement.setAttribute('data-id', '123')

CSS3 Animations

Transitions

.button {
    transition: all 0.3s ease-in-out;
}

.button:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}

Keyframes

@keyframes fadeIn {
    from { opacity: 0; transform: translateY(20px); }
    to { opacity: 1; transform: translateY(0); }
}

.element {
    animation: fadeIn 0.6s ease-out;
}

Web Performance Optimization

Lazy Loading

// Images
const images = document.querySelectorAll('img[data-src]');
const imageObserver = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            const img = entry.target;
            img.src = img.dataset.src;
            img.removeAttribute('data-src');
            imageObserver.unobserve(img);
        }
    });
});

images.forEach(img => imageObserver.observe(img));

Code Splitting

// Dynamic Import
const loadModule = async () => {
    const module = await import('./heavy-module.js');
    module.doSomething();
};

Accessibility Best Practices

Semantic HTML

<nav aria-label="Main navigation">
    <ul>
        <li><a href="#" aria-current="page">Home</a></li>
        <li><a href="#">About</a></li>
    </ul>
</nav>

ARIA Attributes

<button aria-expanded="false" aria-controls="menu">
    Menu
</button>
<div id="menu" hidden>
    <!-- Menu content -->
</div>

Keyboard Navigation

.focusable:focus {
    outline: 2px solid #3b82f6;
    outline-offset: 2px;
}

Advantages and Disadvantages

Advantages of Modern Web Development

  • Cross-Platform: Single codebase works across all devices
  • Responsive: Optimal display on any screen size
  • Interactive: Rich user experiences
  • SEO-Friendly: Built with search engines in mind
  • Accessible: Full support for assistive technologies

Disadvantages

  • Complexity: Many technologies to master
  • Browser Compatibility: Uneven support across browsers
  • Performance: Requires careful optimization
  • Security: Demands robust protection mechanisms

Common Exam Questions

  1. What’s the difference between HTML, CSS, and JavaScript? HTML structures content, CSS styles appearance, and JavaScript enables interactivity.

  2. Explain Responsive Design. Adapting layouts to different screen sizes through media queries and flexible design patterns.

  3. What is the DOM and how do you manipulate it? The DOM is the programmable representation of an HTML document. You manipulate it using JavaScript methods like querySelector, createElement, and appendChild.

  4. When do you use Flexbox versus Grid? Use Flexbox for one-dimensional layouts (rows or columns), and Grid for two-dimensional layouts.

Key Resources

  1. https://developer.mozilla.org/en-US/docs/Web
  2. https://www.w3.org/TR/html5/
  3. https://www.w3.org/Style/CSS/

Web Development

Books about React, Vue, frontend and backend

Eloquent JavaScript von Marijn Haverbeke

Eloquent JavaScript von Marijn Haverbeke

Bei Amazon ansehen

Affiliate-Link: Bei einem Kauf erhalten wir möglicherweise eine Provision.

Back to Blog
Share:

Nächster Artikel in Web Development

Weiterlesen
Add llms.txt to Your Astro Blog

Related Posts