Web Development Fundamentals: HTML, CSS, JavaScript, DOM Manipulation & Responsive Design
This article is a comprehensive introduction to web development fundamentals – including HTML5, CSS3, JavaScript ES6+, DOM manipulation and responsive design with practical examples.
In a Nutshell
Web development is based on three core technologies: HTML for structure, CSS for styling and JavaScript for interactivity. Responsive design ensures optimal display on all devices.
Compact Technical Description
Web development is the creation of web applications through the combination of 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, fonts, 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 elements, manipulate, events
- Asynchronous: Promises, async/await, Fetch API
Exam-Relevant Key Points
- 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
- IHK-relevant: Foundation for all web development professions
Core Components
- HTML5: Semantic structure and content
- CSS3: Visual design and layout
- JavaScript: Dynamic functionality
- DOM: Programmable interface
- Responsive Design: Cross-device compatibility
- Accessibility: Accessible web development
- Performance: Loading times and optimization
- Best Practices: Modern development standards
Practical Examples
1. HTML5 Basic Structure
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Moderne Webanwendung mit HTML5, CSS3 und JavaScript">
<title>Webentwicklung Demo</title>
<!-- CSS einbinden -->
<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="Webentwicklung Demo">
<meta property="og:description" content="Moderne Webanwendung">
<meta property="og:type" content="website">
</head>
<body>
<!-- Skip Navigation für Accessibility -->
<a href="#main-content" class="skip-link">Zum Hauptinhalt springen</a>
<!-- Header mit Navigation -->
<header class="header">
<nav class="nav" aria-label="Hauptnavigation">
<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">Menü</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">Kontakt</a></li>
</ul>
</div>
</nav>
</header>
<!-- Hauptinhalt -->
<main id="main-content" class="main">
<!-- Hero Section -->
<section class="hero" id="home">
<div class="container">
<h1 class="hero-title">Moderne Webentwicklung</h1>
<p class="hero-subtitle">HTML5, CSS3 und JavaScript in Aktion</p>
<div class="hero-actions">
<button class="btn btn-primary" data-action="start">Starten</button>
<a href="#features" class="btn btn-secondary">Mehr erfahren</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">Löschen</button>
<button class="demo-btn" data-action="animate">Animieren</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">Sicherheit</h3>
<p class="feature-description">Moderne Sicherheitsstandards und 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">Optimale Darstellung auf allen Geräten</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">Schnelle Ladezeiten und reibungslose Interaktion</p>
</article>
</div>
</div>
</section>
<!-- Kontakt Formular -->
<section class="contact" id="contact">
<div class="container">
<h2 class="section-title">Kontakt</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">Bitte geben Sie Ihren Namen ein</span>
</div>
<div class="form-group">
<label for="email" class="form-label">E-Mail *</label>
<input type="email" id="email" name="email" class="form-input" required>
<span class="form-error" id="email-error">Bitte geben Sie eine gültige E-Mail ein</span>
</div>
<div class="form-group">
<label for="message" class="form-label">Nachricht</label>
<textarea id="message" name="message" class="form-textarea" rows="4"></textarea>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">Senden</button>
<button type="reset" class="btn btn-secondary">Zurücksetzen</button>
</div>
</form>
</div>
</section>
</main>
<!-- Footer -->
<footer class="footer">
<div class="container">
<p>© 2024 Webentwicklung Demo. Alle Rechte vorbehalten.</p>
<div class="footer-links">
<a href="#impressum">Impressum</a>
<a href="#datenschutz">Datenschutz</a>
</div>
</div>
</footer>
<!-- JavaScript einbinden -->
<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
// DOM Elements select
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
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 not available:', 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
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);
// Body scroll lock
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 long');
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 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 about 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 für Caching und Offline-Funktionalität
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 Fallback to Cache
self.addEventListener('fetch', (event) => {
const { request } = event;
const url = new URL(request.url);
// Only for 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 could 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
| Element | Description | Usage |
|---|---|---|
| header | Header area | Logo, Navigation |
| nav | Navigation | Menu, Links |
| main | Main content | Primary content |
| section | Section | Thematic blocks |
| article | Article | Self-contained content |
| aside | Sidebar | Additional information |
| footer | Footer area | Copyright, 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
| Method | Description | Example |
|---|---|---|
| querySelector | Select element | document.querySelector('.class') |
| createElement | Create element | document.createElement('div') |
| appendChild | Add element | parent.appendChild(child) |
| classList | Manage classes | element.classList.add('active') |
| addEventListener | Bind event | element.addEventListener('click', handler) |
| setAttribute | Set attribute | element.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: One code for all devices
- Responsive: Optimal display everywhere
- Interactive: Rich user experiences
- SEO-friendly: Search engine optimized
- Accessible: Barrier-free support
Disadvantages
- Complexity: Many technologies to learn
- Browser compatibility: Different support levels
- Performance: Optimization required
- Security: Protection mechanisms needed
Common Exam Questions
-
What is the difference between HTML, CSS and JavaScript? HTML structures content, CSS styles appearance, JavaScript enables interactivity.
-
Explain Responsive Design! Adapting the display to different screen sizes through media queries and flexible layouts.
-
What is the DOM and how is it manipulated? The DOM is the programmable representation of the HTML document. Manipulation through JavaScript methods such as querySelector, createElement, appendChild.
-
When do you use Flexbox vs Grid? Flexbox for one-dimensional layouts (rows/columns), Grid for two-dimensional layouts.
Most Important Sources
- https://developer.mozilla.org/de/docs/Web
- https://www.w3.org/TR/html5/
- https://www.w3.org/Style/CSS/
Recommended Reading: Web Development
Keine Bücher für Kategorie "web-development" gefunden.