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! 🚀