Table of Contents
- Introduction to Exercises
- HTML Basics Exercises
- CSS Basics Exercises
- Layout Exercises
- Forms Exercises
- Responsive Design Exercises
- Components Exercises
- Animation Exercises
- Project-Based Exercises
- Challenge Exercises
- Solutions and Explanations
Introduction to Exercises
This comprehensive set of exercises is designed to help you master HTML and CSS through practical, hands-on practice. Each exercise builds upon previous concepts, gradually increasing in complexity.
How to Use These Exercises
- Read the exercise carefully - Understand the requirements
- Try it yourself - Attempt to solve before looking at solutions
- Check your work - Compare with the provided solution
- Experiment - Modify and extend beyond the requirements
- Review - Understand why the solution works
Exercise Difficulty Levels
| Level | Description | Emoji |
|---|---|---|
| Beginner | Basic concepts, simple syntax | 🌱 |
| Intermediate | Combining concepts, medium complexity | 🌿 |
| Advanced | Complex layouts, advanced techniques | 🌳 |
| Challenge | Real-world problems, creative solutions | 🏆 |
HTML Basics Exercises
Exercise 1: Create Your First Web Page 🌱
Objective: Create a basic HTML page with proper structure.
Requirements:
- Create an HTML5 document with proper doctype
- Include
html,head, andbodytags - Set the title to "My First Web Page"
- Add a main heading (
<h1>) with your name - Add a paragraph (
<p>) introducing yourself - Add a second heading (
<h2>) for "My Hobbies" - Create an unordered list (
<ul>) with 3 hobbies - Add a link to your favorite website
Expected Output:
My First Web Page ================ [Your Name] I'm learning HTML and CSS. This is my first web page! My Hobbies ---------- * Reading * Coding * Photography Visit my favorite site: [Google](https://www.google.com)
Exercise 2: Semantic HTML Structure 🌱
Objective: Build a page using semantic HTML elements.
Requirements:
- Create a page with
header,nav,main,article,aside, andfootersections - The header should contain a logo and site title
- Navigation should have at least 3 links
- Create an article with a heading, image, and 2 paragraphs
- Add an aside with related links
- Footer should contain copyright information
HTML Structure:
<header> <div class="logo">MySite</div> <nav>...</nav> </header> <main> <article>...</article> <aside>...</aside> </main> <footer>...</footer>
Exercise 3: Working with Images 🌱
Objective: Embed and format images correctly.
Requirements:
- Add 3 images from placeholder sources (https://via.placeholder.com)
- Each image must have appropriate
alttext - One image should link to an external page
- Use
figureandfigcaptionfor one image - Set proper width and height attributes
- Add a responsive image using
srcset(optional)
Example:
<figure> <img src="https://via.placeholder.com/400x300" alt="Placeholder image"> <figcaption>This is a placeholder image</figcaption> </figure> <a href="https://example.com"> <img src="image.jpg" alt="Clickable image"> </a>
Exercise 4: Tables 🌱
Objective: Create a formatted table.
Requirements:
- Create a table with 4 columns and 5 rows
- Use
thead,tbody, andtfootfor structure - Merge cells using
colspanandrowspan - Add a caption to the table
- Create a schedule table for a weekly routine
Expected Structure:
<table> <caption>Weekly Schedule</caption> <thead> <tr> <th>Time</th> <th>Monday</th> <th>Tuesday</th> <th>Wednesday</th> </tr> </thead> <tbody> <tr> <td>9:00 - 10:00</td> <td>Math</td> <td>Science</td> <td>English</td> </tr> <!-- More rows --> </tbody> </table>
Exercise 5: Lists and Navigation 🌱
Objective: Create different types of lists and navigation.
Requirements:
- Create an ordered list for top 5 favorite movies
- Create an unordered list for skills
- Create a definition list for technical terms
- Create a nested list (categories with sub-items)
- Build a horizontal navigation bar using lists
Example:
<!-- Ordered list --> <ol> <li>Inception</li> <li>The Matrix</li> <!-- ... --> </ol> <!-- Nested list --> <ul> <li>Programming <ul> <li>HTML</li> <li>CSS</li> <li>JavaScript</li> </ul> </li> </ul>
CSS Basics Exercises
Exercise 6: Styling Text 🌱
Objective: Apply text styles using CSS.
Requirements:
- Set a custom font for the page using Google Fonts
- Style headings with different colors and sizes
- Add text shadow to the main heading
- Style paragraphs with line-height and letter-spacing
- Create a class for highlighted text (background color, padding)
- Style links with different states (normal, hover, visited, active)
CSS Starter:
/* Import Google Font */ @import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;600&display=swap'); body { font-family: 'Open Sans', sans-serif; } h1 { color: #2c3e50; text-shadow: 2px 2px 4px rgba(0,0,0,0.1); } .highlight { background-color: yellow; padding: 0.2rem 0.5rem; } a:link { color: blue; } a:hover { color: red; text-decoration: underline; } Exercise 7: Box Model 🌱
Objective: Understand and apply the CSS box model.
Requirements:
- Create three cards with different padding, margin, and border
- Use
box-sizing: border-boxfor consistent sizing - Add box shadows to cards
- Create a profile card with avatar, name, and description
- Make cards equal width using percentages
CSS Starter:
* { box-sizing: border-box; } .card { width: 30%; padding: 20px; margin: 15px; border: 1px solid #ddd; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); } Exercise 8: Background and Gradients 🌱
Objective: Apply backgrounds and gradients.
Requirements:
- Set a linear gradient background for the body
- Create a card with radial gradient background
- Add a background image with proper positioning
- Create a hero section with overlay effect
- Use multiple backgrounds on an element
CSS Example:
body { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); } .card { background: radial-gradient(circle at 20% 30%, #ff6b6b, #c92a2a); } .hero { background: linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.5)), url('hero.jpg') center/cover; } Exercise 9: Display and Positioning 🌿
Objective: Master display properties and positioning.
Requirements:
- Create a header with fixed positioning
- Create a sidebar with absolute positioning
- Use relative positioning for child elements
- Create a modal using absolute positioning and z-index
- Make an element sticky when scrolling
CSS Example:
header { position: fixed; top: 0; width: 100%; z-index: 100; } .sidebar { position: absolute; left: 0; top: 60px; width: 250px; } .modal { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 1000; } .sticky { position: sticky; top: 20px; } Exercise 10: Pseudo-classes and Pseudo-elements 🌿
Objective: Use advanced selectors for dynamic styling.
Requirements:
- Style first and last child differently
- Create alternating row colors in a table
- Style a button with different states (hover, active, focus)
- Add content before and after elements using pseudo-elements
- Create a tooltip using pseudo-classes
CSS Example:
/* First child */ li:first-child { font-weight: bold; } /* Alternating rows */ tr:nth-child(even) { background: #f9f9f9; } /* Button states */ .btn:hover { background: #0056b3; } .btn:active { transform: scale(0.98); } /* Pseudo-elements */ .quote::before { content: '"'; font-size: 2rem; color: #999; } /* Tooltip */ .tooltip:hover::after { content: attr(data-tooltip); position: absolute; background: #333; color: white; padding: 5px; border-radius: 4px; } Layout Exercises
Exercise 11: Flexbox Navigation 🌿
Objective: Build a responsive navigation using Flexbox.
Requirements:
- Create a navigation bar with logo and 5 links
- Use Flexbox to align items horizontally
- Push the last item to the right (login button)
- Make the navigation responsive for mobile (vertical layout)
- Add dropdown menu for one section (optional)
HTML Structure:
<nav class="navbar"> <div class="logo">Brand</div> <ul class="nav-links"> <li><a href="#">Home</a></li> <li><a href="#">About</a></li> <li><a href="#">Services</a></li> <li><a href="#">Contact</a></li> </ul> <button class="login-btn">Login</button> </nav>
CSS Solution:
.navbar { display: flex; justify-content: space-between; align-items: center; padding: 1rem 2rem; background: #333; color: white; } .nav-links { display: flex; gap: 2rem; list-style: none; } @media (max-width: 768px) { .navbar { flex-direction: column; gap: 1rem; } .nav-links { flex-direction: column; text-align: center; gap: 0.5rem; } } Exercise 12: Flexbox Card Grid 🌿
Objective: Create a responsive card grid using Flexbox.
Requirements:
- Create a grid of cards using Flexbox
- Cards should wrap on smaller screens
- Each card should have equal width
- Cards should have consistent height
- Add hover effects to cards
CSS Solution:
.card-grid { display: flex; flex-wrap: wrap; gap: 20px; justify-content: center; } .card { flex: 1 1 300px; max-width: 350px; background: white; border-radius: 8px; overflow: hidden; transition: transform 0.3s, box-shadow 0.3s; } .card:hover { transform: translateY(-5px); box-shadow: 0 5px 15px rgba(0,0,0,0.2); } Exercise 13: CSS Grid Layout 🌿
Objective: Create a magazine layout using CSS Grid.
Requirements:
- Create a grid with 4 columns and 3 rows
- Use grid-template-areas for layout
- Create a header that spans full width
- Create a featured article that spans 2 columns
- Create a sidebar
- Create a footer spanning all columns
CSS Solution:
.grid-container { display: grid; grid-template-areas: "header header header header" "featured featured sidebar sidebar" "article1 article2 article3 sidebar" "footer footer footer footer"; grid-template-columns: repeat(4, 1fr); gap: 20px; padding: 20px; } .header { grid-area: header; } .featured { grid-area: featured; } .sidebar { grid-area: sidebar; } .article1 { grid-area: article1; } .article2 { grid-area: article2; } .article3 { grid-area: article3; } .footer { grid-area: footer; } Exercise 14: Holy Grail Layout 🌿
Objective: Implement the classic Holy Grail layout.
Requirements:
- Header at top, footer at bottom
- Left sidebar, main content, right sidebar
- All sections should fill available height
- Responsive: sidebars stack on mobile
- Use CSS Grid or Flexbox
CSS Solution (Grid):
.holy-grail { display: grid; grid-template-areas: "header header header" "nav main aside" "footer footer footer"; grid-template-columns: 200px 1fr 200px; min-height: 100vh; } @media (max-width: 768px) { .holy-grail { grid-template-areas: "header" "nav" "main" "aside" "footer"; grid-template-columns: 1fr; } } Exercise 15: Masonry Layout (Challenge) 🌳
Objective: Create a Pinterest-style masonry layout.
Requirements:
- Create a grid of varying height items
- Items should fill gaps automatically
- Use CSS Grid or Flexbox with column count
- Different item sizes (tall, wide, square)
- Smooth loading with animation
CSS Solution (CSS Columns):
.masonry { column-count: 4; column-gap: 20px; } .masonry-item { break-inside: avoid; margin-bottom: 20px; border-radius: 8px; overflow: hidden; } @media (max-width: 1024px) { .masonry { column-count: 3; } } @media (max-width: 768px) { .masonry { column-count: 2; } } @media (max-width: 480px) { .masonry { column-count: 1; } } Forms Exercises
Exercise 16: Registration Form 🌱
Objective: Create a user registration form.
Requirements:
- Fields: name, email, password, confirm password
- Use proper input types
- Add validation attributes (required, minlength)
- Include a dropdown for country selection
- Add radio buttons for gender
- Add checkboxes for interests
- Include submit and reset buttons
HTML Structure:
<form class="registration-form"> <div class="form-group"> <label for="name">Full Name *</label> <input type="text" id="name" required minlength="3"> </div> <div class="form-group"> <label for="email">Email *</label> <input type="email" id="email" required> </div> <div class="form-group"> <label for="country">Country</label> <select id="country"> <option>Select country</option> <option>USA</option> <option>Canada</option> <option>UK</option> </select> </div> <div class="form-group"> <label>Gender</label> <label><input type="radio" name="gender" value="male"> Male</label> <label><input type="radio" name="gender" value="female"> Female</label> </div> <div class="form-group"> <label>Interests</label> <label><input type="checkbox" name="interests" value="coding"> Coding</label> <label><input type="checkbox" name="interests" value="design"> Design</label> </div> <button type="submit">Register</button> <button type="reset">Reset</button> </form>
Exercise 17: Styled Form 🌿
Objective: Style the registration form with CSS.
Requirements:
- Create a centered form with max-width
- Style form groups with spacing
- Add focus states for inputs
- Style invalid/valid states
- Create custom checkbox and radio styles
- Style submit button with hover effects
CSS Solution:
.registration-form { max-width: 500px; margin: 0 auto; padding: 2rem; background: white; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); } .form-group { margin-bottom: 1.5rem; } .form-group label { display: block; margin-bottom: 0.5rem; font-weight: 600; color: #333; } .form-group input, .form-group select { width: 100%; padding: 0.75rem; border: 2px solid #e0e0e0; border-radius: 4px; transition: all 0.3s; } .form-group input:focus, .form-group select:focus { outline: none; border-color: #4CAF50; box-shadow: 0 0 0 3px rgba(76, 175, 80, 0.1); } .form-group input:invalid:not(:placeholder-shown) { border-color: #ff4444; } .form-group input:valid:not(:placeholder-shown) { border-color: #4CAF50; } /* Custom checkbox */ .checkbox-group { display: flex; align-items: center; gap: 0.5rem; } .checkbox-group input[type="checkbox"] { width: 20px; height: 20px; cursor: pointer; } /* Submit button */ button[type="submit"] { background: #4CAF50; color: white; padding: 0.75rem 1.5rem; border: none; border-radius: 4px; cursor: pointer; font-size: 1rem; transition: background 0.3s, transform 0.2s; } button[type="submit"]:hover { background: #45a049; transform: translateY(-2px); } button[type="submit"]:active { transform: translateY(0); } Exercise 18: Contact Form with Validation 🌿
Objective: Create a contact form with real-time validation.
Requirements:
- Fields: name, email, subject, message
- Real-time validation with JavaScript
- Character counter for message
- Show error messages
- Prevent submission if validation fails
- Show success message on valid submission
JavaScript Validation:
const form = document.getElementById('contact-form'); const email = document.getElementById('email'); const message = document.getElementById('message'); email.addEventListener('input', function() { if (this.value.includes('@')) { this.classList.remove('invalid'); this.classList.add('valid'); } else { this.classList.remove('valid'); this.classList.add('invalid'); } }); message.addEventListener('input', function() { const count = this.value.length; document.getElementById('char-count').textContent = `${count}/500`; if (count > 500) { this.classList.add('invalid'); } else { this.classList.remove('invalid'); } }); form.addEventListener('submit', function(e) { e.preventDefault(); if (this.checkValidity()) { // Show success message document.getElementById('success-message').style.display = 'block'; this.reset(); } else { this.reportValidity(); } }); Responsive Design Exercises
Exercise 19: Mobile-First Design 🌿
Objective: Build a responsive website using mobile-first approach.
Requirements:
- Design for mobile first (max-width: 480px)
- Add tablet breakpoint (min-width: 768px)
- Add desktop breakpoint (min-width: 1024px)
- Images should be responsive
- Typography should scale appropriately
- Navigation should transform from hamburger to horizontal
CSS Solution:
/* Mobile First (base styles) */ .container { padding: 1rem; } h1 { font-size: 1.5rem; } .card { margin-bottom: 1rem; } /* Tablet */ @media (min-width: 768px) { .container { max-width: 720px; margin: 0 auto; padding: 2rem; } h1 { font-size: 2rem; } .grid { display: flex; gap: 1rem; } .card { flex: 1; } } /* Desktop */ @media (min-width: 1024px) { .container { max-width: 960px; } h1 { font-size: 2.5rem; } } Exercise 20: Responsive Navigation with Hamburger Menu 🌿
Objective: Create a responsive navigation with hamburger menu.
Requirements:
- Horizontal navigation on desktop
- Hamburger icon on mobile
- Mobile menu should slide in/out
- Close menu when clicking link
- CSS transitions for smooth animation
HTML Structure:
<nav class="navbar"> <div class="logo">Brand</div> <button class="hamburger"> <span></span><span></span><span></span> </button> <ul class="nav-menu"> <li><a href="#">Home</a></li> <li><a href="#">About</a></li> <li><a href="#">Services</a></li> <li><a href="#">Contact</a></li> </ul> </nav>
CSS Solution:
.navbar { display: flex; justify-content: space-between; align-items: center; padding: 1rem; background: #333; color: white; } .hamburger { display: none; flex-direction: column; cursor: pointer; background: none; border: none; } .hamburger span { width: 25px; height: 3px; background: white; margin: 3px 0; transition: 0.3s; } .nav-menu { display: flex; list-style: none; gap: 2rem; } @media (max-width: 768px) { .hamburger { display: flex; } .nav-menu { position: fixed; top: 60px; left: -100%; width: 100%; flex-direction: column; background: #333; padding: 2rem; transition: 0.3s; } .nav-menu.active { left: 0; } } JavaScript:
const hamburger = document.querySelector('.hamburger'); const navMenu = document.querySelector('.nav-menu'); hamburger.addEventListener('click', () => { navMenu.classList.toggle('active'); }); document.querySelectorAll('.nav-menu a').forEach(link => { link.addEventListener('click', () => { navMenu.classList.remove('active'); }); }); Exercise 21: Responsive Pricing Table 🌿
Objective: Create a responsive pricing table.
Requirements:
- Three pricing plans (Basic, Pro, Premium)
- Show features for each plan
- Highlight the most popular plan
- Stack vertically on mobile
- Use CSS Grid for alignment
- Add call-to-action buttons
CSS Solution:
.pricing-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 2rem; max-width: 1200px; margin: 0 auto; padding: 2rem; } .pricing-card { background: white; border-radius: 12px; padding: 2rem; text-align: center; box-shadow: 0 4px 6px rgba(0,0,0,0.1); transition: transform 0.3s; } .pricing-card:hover { transform: translateY(-5px); } .pricing-card.popular { border: 2px solid #ff6b6b; position: relative; } .pricing-card.popular::before { content: 'Most Popular'; position: absolute; top: -12px; left: 50%; transform: translateX(-50%); background: #ff6b6b; color: white; padding: 0.25rem 1rem; border-radius: 20px; font-size: 0.875rem; } .price { font-size: 3rem; font-weight: bold; color: #333; margin: 1rem 0; } .price span { font-size: 1rem; color: #666; } .features { list-style: none; padding: 0; margin: 2rem 0; } .features li { padding: 0.5rem 0; border-bottom: 1px solid #eee; } .btn { background: #4CAF50; color: white; padding: 0.75rem 1.5rem; border: none; border-radius: 25px; cursor: pointer; transition: background 0.3s; } Components Exercises
Exercise 22: Modal Component 🌿
Objective: Create a reusable modal dialog.
Requirements:
- Modal opens when button clicked
- Modal closes with X button
- Close modal when clicking outside
- Close modal with ESC key
- Animate modal appearance
- Prevent body scrolling when modal open
HTML Structure:
<button id="openModal">Open Modal</button> <div id="modal" class="modal"> <div class="modal-content"> <span class="close">×</span> <h2>Modal Title</h2> <p>Modal content goes here</p> </div> </div>
CSS Solution:
.modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000; animation: fadeIn 0.3s; } .modal.show { display: flex; align-items: center; justify-content: center; } .modal-content { background: white; padding: 2rem; border-radius: 8px; max-width: 500px; width: 90%; position: relative; animation: slideIn 0.3s; } .close { position: absolute; top: 10px; right: 20px; font-size: 28px; cursor: pointer; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes slideIn { from { transform: translateY(-50px); opacity: 0; } to { transform: translateY(0); opacity: 1; } } JavaScript:
const modal = document.getElementById('modal'); const openBtn = document.getElementById('openModal'); const closeBtn = document.querySelector('.close'); function openModal() { modal.classList.add('show'); document.body.style.overflow = 'hidden'; } function closeModal() { modal.classList.remove('show'); document.body.style.overflow = ''; } openBtn.addEventListener('click', openModal); closeBtn.addEventListener('click', closeModal); window.addEventListener('click', (e) => { if (e.target === modal) closeModal(); }); document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && modal.classList.contains('show')) { closeModal(); } }); Exercise 23: Image Carousel/Slider 🌳
Objective: Build an image carousel with navigation.
Requirements:
- Display one image at a time
- Previous/Next buttons
- Auto-play with interval
- Dots indicator
- Pause on hover
- Responsive images
HTML Structure:
<div class="carousel"> <div class="carousel-container"> <div class="carousel-slide"> <img src="image1.jpg" alt="Slide 1"> </div> <!-- More slides --> </div> <button class="prev">❮</button> <button class="next">❯</button> <div class="dots"></div> </div>
CSS Solution:
.carousel { position: relative; max-width: 800px; margin: 0 auto; overflow: hidden; border-radius: 8px; } .carousel-container { display: flex; transition: transform 0.5s ease; } .carousel-slide { min-width: 100%; } .carousel-slide img { width: 100%; height: 400px; object-fit: cover; } .prev, .next { position: absolute; top: 50%; transform: translateY(-50%); background: rgba(0,0,0,0.5); color: white; border: none; padding: 1rem; cursor: pointer; } .prev { left: 0; } .next { right: 0; } .dots { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); display: flex; gap: 10px; } .dot { width: 10px; height: 10px; background: rgba(255,255,255,0.5); border-radius: 50%; cursor: pointer; } .dot.active { background: white; } JavaScript:
let currentIndex = 0; const slides = document.querySelectorAll('.carousel-slide'); const totalSlides = slides.length; let autoPlayInterval; function updateCarousel() { const container = document.querySelector('.carousel-container'); container.style.transform = `translateX(-${currentIndex * 100}%)`; // Update dots document.querySelectorAll('.dot').forEach((dot, i) => { dot.classList.toggle('active', i === currentIndex); }); } function nextSlide() { currentIndex = (currentIndex + 1) % totalSlides; updateCarousel(); } function prevSlide() { currentIndex = (currentIndex - 1 + totalSlides) % totalSlides; updateCarousel(); } function startAutoPlay() { autoPlayInterval = setInterval(nextSlide, 3000); } function stopAutoPlay() { clearInterval(autoPlayInterval); } // Event listeners document.querySelector('.next').addEventListener('click', () => { nextSlide(); stopAutoPlay(); startAutoPlay(); }); document.querySelector('.prev').addEventListener('click', () => { prevSlide(); stopAutoPlay(); startAutoPlay(); }); // Create dots const dotsContainer = document.querySelector('.dots'); for (let i = 0; i < totalSlides; i++) { const dot = document.createElement('div'); dot.classList.add('dot'); dot.addEventListener('click', () => { currentIndex = i; updateCarousel(); stopAutoPlay(); startAutoPlay(); }); dotsContainer.appendChild(dot); } updateCarousel(); startAutoPlay(); // Pause on hover const carousel = document.querySelector('.carousel'); carousel.addEventListener('mouseenter', stopAutoPlay); carousel.addEventListener('mouseleave', startAutoPlay); Exercise 24: Accordion Component 🌿
Objective: Create a FAQ accordion component.
Requirements:
- Multiple collapsible sections
- Only one section open at a time
- Animate height transition
- Icon indicates open/closed state
- Smooth animations
HTML Structure:
<div class="accordion"> <div class="accordion-item"> <button class="accordion-header"> <span>Question 1</span> <span class="icon">+</span> </button> <div class="accordion-content"> <p>Answer to question 1...</p> </div> </div> <!-- More items --> </div>
CSS Solution:
.accordion-item { border-bottom: 1px solid #eee; } .accordion-header { width: 100%; display: flex; justify-content: space-between; align-items: center; padding: 1rem; background: none; border: none; cursor: pointer; font-size: 1.1rem; font-weight: 600; text-align: left; } .accordion-header:hover { background: #f5f5f5; } .icon { transition: transform 0.3s; } .accordion-item.active .icon { transform: rotate(45deg); } .accordion-content { max-height: 0; overflow: hidden; transition: max-height 0.3s ease; padding: 0 1rem; } .accordion-item.active .accordion-content { max-height: 200px; padding: 1rem; } JavaScript:
document.querySelectorAll('.accordion-header').forEach(button => { button.addEventListener('click', () => { const item = button.parentElement; const isActive = item.classList.contains('active'); // Close all items document.querySelectorAll('.accordion-item').forEach(i => { i.classList.remove('active'); }); // Open clicked item if it wasn't active if (!isActive) { item.classList.add('active'); } }); }); Animation Exercises
Exercise 25: CSS Transitions 🌱
Objective: Create smooth transitions for interactive elements.
Requirements:
- Button that changes color and size on hover
- Card that lifts up on hover
- Link with underline animation
- Image zoom effect on hover
- Input field with border glow on focus
CSS Solution:
/* Button transitions */ .btn { background: #3498db; padding: 10px 20px; transition: all 0.3s ease; } .btn:hover { background: #2980b9; transform: translateY(-2px); box-shadow: 0 5px 15px rgba(52,152,219,0.4); } /* Card lift */ .card { transition: transform 0.3s, box-shadow 0.3s; } .card:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0,0,0,0.1); } /* Underline animation */ .link { position: relative; text-decoration: none; } .link::after { content: ''; position: absolute; bottom: 0; left: 0; width: 0; height: 2px; background: #3498db; transition: width 0.3s; } .link:hover::after { width: 100%; } /* Image zoom */ .image-zoom { overflow: hidden; } .image-zoom img { transition: transform 0.5s; } .image-zoom:hover img { transform: scale(1.1); } /* Input focus */ input { transition: border-color 0.3s, box-shadow 0.3s; } input:focus { border-color: #3498db; box-shadow: 0 0 0 3px rgba(52,152,219,0.2); } Exercise 26: CSS Keyframe Animations 🌿
Objective: Create complex animations using keyframes.
Requirements:
- Create a loading spinner
- Create a pulsing effect
- Create a fade-in animation for page load
- Create a bouncing ball animation
- Create a rotating gear
CSS Solution:
/* Loading spinner */ @keyframes spin { to { transform: rotate(360deg); } } .spinner { width: 40px; height: 40px; border: 4px solid #f3f3f3; border-top-color: #3498db; border-radius: 50%; animation: spin 1s linear infinite; } /* Pulsing effect */ @keyframes pulse { 0% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.05); opacity: 0.7; } 100% { transform: scale(1); opacity: 1; } } .pulse { animation: pulse 2s ease infinite; } /* Fade-in */ @keyframes fadeIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .fade-in { animation: fadeIn 1s ease; } /* Bouncing ball */ @keyframes bounce { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-100px); } } .ball { width: 50px; height: 50px; background: #3498db; border-radius: 50%; animation: bounce 2s ease infinite; } /* Rotating gear */ @keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } .gear { font-size: 4rem; display: inline-block; animation: rotate 3s linear infinite; } Exercise 27: Scroll Animations 🌳
Objective: Create elements that animate when scrolling into view.
Requirements:
- Elements fade in when scrolled into view
- Elements slide in from sides
- Progress bar that fills as you scroll
- Parallax effect on background
- Sticky header that changes style on scroll
CSS Solution:
/* Scroll reveal */ .scroll-reveal { opacity: 0; transform: translateY(30px); transition: all 0.6s ease; } .scroll-reveal.revealed { opacity: 1; transform: translateY(0); } /* Progress bar */ .progress-bar { position: fixed; top: 0; left: 0; width: 0%; height: 3px; background: #3498db; z-index: 1000; transition: width 0.2s; } /* Parallax background */ .parallax { background-image: url('background.jpg'); background-attachment: fixed; background-position: center; background-repeat: no-repeat; background-size: cover; } /* Sticky header */ .header { transition: all 0.3s; } .header.scrolled { background: white; box-shadow: 0 2px 10px rgba(0,0,0,0.1); padding: 0.5rem; } JavaScript:
// Scroll reveal const revealElements = document.querySelectorAll('.scroll-reveal'); function checkReveal() { const windowHeight = window.innerHeight; revealElements.forEach(element => { const elementTop = element.getBoundingClientRect().top; if (elementTop < windowHeight - 100) { element.classList.add('revealed'); } }); } window.addEventListener('scroll', checkReveal); checkReveal(); // Progress bar function updateProgressBar() { const scrollTop = window.pageYOffset; const docHeight = document.documentElement.scrollHeight - window.innerHeight; const scrollPercent = (scrollTop / docHeight) * 100; document.querySelector('.progress-bar').style.width = scrollPercent + '%'; } window.addEventListener('scroll', updateProgressBar); // Sticky header window.addEventListener('scroll', () => { const header = document.querySelector('.header'); if (window.scrollY > 100) { header.classList.add('scrolled'); } else { header.classList.remove('scrolled'); } }); Project-Based Exercises
Exercise 28: Personal Portfolio Website 🏆
Objective: Build a complete personal portfolio website.
Requirements:
- Hero section with intro and call-to-action
- About section with bio and skills
- Projects section with cards
- Contact form
- Footer with social links
- Responsive design
- Smooth scrolling
- Dark mode toggle
Project Structure:
portfolio/ ├── index.html ├── css/ │ ├── style.css │ └── responsive.css ├── js/ │ └── main.js └── images/ ├── hero.jpg └── projects/
HTML Template:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>My Portfolio</title> <link rel="stylesheet" href="css/style.css"> <link rel="stylesheet" href="css/responsive.css"> </head> <body> <header class="header"> <nav class="navbar"> <div class="logo">Portfolio</div> <ul class="nav-links"> <li><a href="#home">Home</a></li> <li><a href="#about">About</a></li> <li><a href="#projects">Projects</a></li> <li><a href="#contact">Contact</a></li> </ul> <button class="theme-toggle">🌙</button> </nav> </header> <section id="home" class="hero"> <div class="hero-content"> <h1>John Doe</h1> <p>Web Developer & Designer</p> <a href="#contact" class="btn">Get in Touch</a> </div> </section> <section id="about" class="about"> <div class="container"> <h2>About Me</h2> <div class="about-content"> <div class="bio"> <p>I'm a passionate web developer...</p> </div> <div class="skills"> <h3>Skills</h3> <div class="skill-item">HTML/CSS</div> <div class="skill-item">JavaScript</div> <div class="skill-item">React</div> </div> </div> </div> </section> <section id="projects" class="projects"> <div class="container"> <h2>My Projects</h2> <div class="projects-grid"> <div class="project-card"> <img src="images/project1.jpg" alt="Project 1"> <h3>Project Title</h3> <p>Project description...</p> <a href="#" class="btn btn-sm">View Project</a> </div> <!-- More project cards --> </div> </div> </section> <section id="contact" class="contact"> <div class="container"> <h2>Contact Me</h2> <form id="contact-form"> <div class="form-group"> <input type="text" placeholder="Name" required> </div> <div class="form-group"> <input type="email" placeholder="Email" required> </div> <div class="form-group"> <textarea placeholder="Message" rows="5" required></textarea> </div> <button type="submit">Send Message</button> </form> </div> </section> <footer class="footer"> <div class="container"> <div class="social-links"> <a href="#">GitHub</a> <a href="#">LinkedIn</a> <a href="#">Twitter</a> </div> <p>© 2024 John Doe. All rights reserved.</p> </div> </footer> <script src="js/main.js"></script> </body> </html>
Exercise 29: E-commerce Product Page 🏆
Objective: Build a product page for an online store.
Requirements:
- Product image gallery with thumbnails
- Product details (price, description, variations)
- Quantity selector
- Add to cart button
- Related products section
- Responsive layout
- Image zoom on hover
- Color/size options
Key Features:
/* Product gallery */ .product-gallery { display: flex; gap: 1rem; } .main-image { flex: 1; } .main-image img { width: 100%; border-radius: 8px; } .thumbnails { display: flex; flex-direction: column; gap: 0.5rem; width: 80px; } .thumbnail { width: 100%; cursor: pointer; border-radius: 4px; opacity: 0.6; transition: opacity 0.3s; } .thumbnail.active { opacity: 1; border: 2px solid #3498db; } /* Quantity selector */ .quantity-selector { display: flex; align-items: center; gap: 0.5rem; } .quantity-btn { width: 30px; height: 30px; background: #f0f0f0; border: none; cursor: pointer; } .quantity { width: 50px; text-align: center; } JavaScript:
// Image gallery const mainImage = document.getElementById('main-image'); const thumbnails = document.querySelectorAll('.thumbnail'); thumbnails.forEach(thumb => { thumb.addEventListener('click', () => { mainImage.src = thumb.dataset.large; thumbnails.forEach(t => t.classList.remove('active')); thumb.classList.add('active'); }); }); // Quantity selector const quantity = document.getElementById('quantity'); document.querySelectorAll('.quantity-btn').forEach(btn => { btn.addEventListener('click', () => { let value = parseInt(quantity.value); if (btn.classList.contains('plus')) { value++; } else if (value > 1) { value--; } quantity.value = value; }); }); // Add to cart document.getElementById('add-to-cart').addEventListener('click', () => { const selectedOptions = { color: document.querySelector('.color.active')?.dataset.color, size: document.querySelector('.size.active')?.dataset.size, quantity: quantity.value }; // Add to cart logic alert(`Added ${quantity.value} item(s) to cart!`); }); Exercise 30: Dashboard Interface 🏆
Objective: Create a modern admin dashboard.
Requirements:
- Sidebar navigation
- Header with user profile and notifications
- Stats cards
- Charts (use Chart.js)
- Data tables
- Activity feed
- Responsive design (collapsible sidebar on mobile)
- Dark mode toggle
HTML Structure:
<div class="dashboard"> <aside class="sidebar"> <div class="logo">Dashboard</div> <nav> <a href="#" class="active">📊 Dashboard</a> <a href="#">👥 Users</a> <a href="#">📦 Products</a> <a href="#">💰 Sales</a> <a href="#">⚙️ Settings</a> </nav> </aside> <main class="main-content"> <header class="header"> <div class="search"> <input type="search" placeholder="Search..."> </div> <div class="user-menu"> <span>John Doe</span> <div class="avatar">JD</div> </div> </header> <div class="stats-grid"> <div class="stat-card"> <h3>Revenue</h3> <div class="stat-value">$45,231</div> <div class="stat-change">+20.1%</div> </div> <!-- More stats --> </div> <div class="chart-container"> <canvas id="revenue-chart"></canvas> </div> <div class="recent-orders"> <h2>Recent Orders</h2> <table> <!-- Table content --> </table> </div> </main> </div>
Challenge Exercises
Challenge 1: CSS-Only Tooltip 🏆
Objective: Create tooltips using only CSS (no JavaScript).
Requirements:
- Tooltip appears on hover
- Position tooltips (top, bottom, left, right)
- Different styles for different contexts
- Fade-in animation
- Arrow pointer
Solution:
[data-tooltip] { position: relative; cursor: help; } [data-tooltip]::before { content: attr(data-tooltip); position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%); padding: 0.5rem 0.75rem; background: #333; color: white; font-size: 0.875rem; white-space: nowrap; border-radius: 4px; opacity: 0; visibility: hidden; transition: opacity 0.2s, visibility 0.2s; z-index: 10; } [data-tooltip]::after { content: ''; position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%); border-width: 5px; border-style: solid; border-color: #333 transparent transparent transparent; opacity: 0; visibility: hidden; transition: opacity 0.2s, visibility 0.2s; } [data-tooltip]:hover::before, [data-tooltip]:hover::after { opacity: 1; visibility: visible; } /* Different positions */ [data-tooltip][data-position="top"]::before { bottom: 100%; } [data-tooltip][data-position="bottom"]::before { top: 100%; bottom: auto; } /* More positions */ Challenge 2: Pure CSS Dropdown Menu 🏆
Objective: Create a dropdown menu using only CSS.
Requirements:
- Dropdown appears on hover
- Nested dropdowns
- Smooth animation
- Keyboard accessible
- Responsive design
Solution:
.dropdown { position: relative; } .dropdown-menu { position: absolute; top: 100%; left: 0; background: white; min-width: 200px; border-radius: 4px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); opacity: 0; visibility: hidden; transition: opacity 0.2s, visibility 0.2s; z-index: 100; } .dropdown:hover .dropdown-menu { opacity: 1; visibility: visible; } /* Nested dropdowns */ .dropdown-submenu { position: relative; } .dropdown-submenu .dropdown-menu { top: 0; left: 100%; } .dropdown-submenu:hover .dropdown-menu { opacity: 1; visibility: visible; } Challenge 3: CSS Grid Master 🏆
Objective: Recreate complex layouts using only CSS Grid.
Requirements:
- Magazine layout with irregular grid
- Overlapping elements
- Responsive grid reconfiguration
- Card grid with featured items
- Holy grail layout with sidebar
Solution:
.complex-grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 20px; } .featured { grid-column: span 6; grid-row: span 2; } .card { grid-column: span 3; } .sidebar { grid-column: span 3; grid-row: span 4; } /* Responsive */ @media (max-width: 1024px) { .featured { grid-column: span 12; } .card { grid-column: span 6; } .sidebar { grid-column: span 12; grid-row: auto; } } @media (max-width: 768px) { .card { grid-column: span 12; } } Solutions and Explanations
How to Check Your Solutions
- HTML Validation: Use W3C Validator (https://validator.w3.org/)
- CSS Validation: Use W3C CSS Validator (https://jigsaw.w3.org/css-validator/)
- Browser DevTools: Inspect elements and check styles
- Responsive Testing: Use Chrome DevTools device emulation
- Cross-browser Testing: Test in Chrome, Firefox, Safari, Edge
Common Mistakes to Avoid
- Missing alt attributes on images
- Not closing tags properly
- Inline styles instead of CSS
- Overusing !important
- Not making layouts responsive
- Hardcoding pixel values instead of relative units
- Not considering accessibility
Performance Tips
- Minify CSS for production
- Use CSS variables for maintainability
- Optimize images (compression, WebP format)
- Lazy load images below the fold
- Reduce specificity to avoid conflicts
- Use flexbox/grid instead of floats
- Group media queries for better performance
Conclusion
Progress Tracker
| Exercise | Completed | Notes |
|---|---|---|
| 1-10: Basics | ☐ | |
| 11-15: Layout | ☐ | |
| 16-18: Forms | ☐ | |
| 19-21: Responsive | ☐ | |
| 22-24: Components | ☐ | |
| 25-27: Animation | ☐ | |
| 28-30: Projects | ☐ | |
| Challenges | ☐ |
Next Steps After Exercises
- Build a complete project combining all concepts
- Learn JavaScript for interactivity
- Explore frameworks (React, Vue, Angular)
- Learn CSS preprocessors (Sass, Less)
- Study CSS architecture (BEM, ITCSS, SMACSS)
- Learn about web performance optimization
- Understand accessibility best practices
- Build your portfolio with your projects
Resources
- MDN Web Docs: https://developer.mozilla.org/
- CSS-Tricks: https://css-tricks.com/
- CodePen: https://codepen.io/
- Frontend Mentor: https://www.frontendmentor.io/
- freeCodeCamp: https://www.freecodecamp.org/
Remember: The best way to learn is by doing. Don't just copy solutions - understand why they work and experiment with modifications. Happy coding! 🚀