Build an Online Course Landing Page
Build a responsive course landing page using HTML and CSS Flexbox.
Introduction
30 Second Summary
Every website you visit is built on two foundational languages. One provides the structure of the page, and the other controls how it looks.
In this project, you will build a professional-looking landing page for a fictional online course called "Introduction to Space Science." You will write the HTML that structures the page and the CSS that makes it look polished.
What You'll Build
A responsive course landing page featuring a navigation bar, hero section, feature cards, instructor bio, and footer.
By the end of this project, you'll have:
- A polished online course landing page live in your browser.
- A working Flexbox-based layout with a navigation bar, hero section, features grid, and footer.
- A responsive design that adapts its layout for smaller screens using a media query.
- Secret Mission: Add a "Student Testimonials" section with styled quote cards and hover effects.
Are there any prerequisites?
None. This project starts from scratch and includes setup instructions for all required tools. All you need is a computer with internet access.
Set Up Your Project
Every website starts with two foundational files. An HTML file provides the structure of your page, and a CSS file controls how it looks.
In this step, you'll set up VS Code with a live preview tool, create your project folder, and write the opening lines of HTML that every webpage needs.
In this step, get ready to:
- Install the Live Server extension for auto-refreshing browser previews.
- Create the space-course-landing project folder with index.html and style.css.
- Generate the HTML boilerplate and connect your stylesheet.
Install the Live Server extension
Live Server is a VS Code extension that launches a local web server and automatically refreshes your browser every time you save a file. This means you'll see your changes instantly without manually reloading.
- Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
- Type VS Code and press Enter to open it.
- Open the Extensions panel by pressing Cmd+Shift+X (macOS) or Ctrl+Shift+X (Windows).
- Type Live Server in the search bar at the top of the Extensions panel.
- Find the result by Ritwick Dey (it should be the first result).
- Click the Install button.
You should see the Install button change to Uninstall after a few seconds. This confirms the extension is ready.
What is Live Server?
Live Server creates a local web server on your computer (at localhost:5500 by default). It watches your files for changes and refreshes the browser automatically every time you save.
Without it, you'd have to manually refresh your browser tab every single time you make a change. Live Server removes that friction so you can focus on writing code.
Don't see Live Server in search results?
Make sure you're searching in the Extensions panel (the square icon in the left sidebar), not the regular file search. The panel title should say "Extensions" at the top.
If multiple results appear, look for the one with the author name "Ritwick Dey" and a high download count (millions of installs).
Help me find and install the Live Server extension in VS Code.
Create your project folder and files
Your project needs a dedicated folder to hold all its files. You'll create this on your Desktop so it's easy to find.
- Open the integrated terminal in VS Code by pressing Ctrl+` (backtick key, usually above Tab).
- Move to your Desktop by running this command:
cd ~/Desktop
- Create your project folder by running this command:
mkdir space-course-landing
- Confirm the folder was created by running:
ls
You should see space-course-landing listed in the output.
- Click File in the top menu bar.
- Click Open Folder.
- Navigate to your Desktop and select the space-course-landing folder, then click Open (macOS) or Select Folder (Windows).
VS Code's Explorer sidebar on the left now shows your empty space-course-landing folder. Next, you'll create the two files this project needs.
- Hover over the folder name in the Explorer sidebar. A row of small icons appears.
- Click the New File icon (it looks like a page with a plus sign).
- Type index.html and press Enter.
- Click the New File icon again.
- Type style.css and press Enter.
You should now see both index.html and style.css listed in the Explorer sidebar.
Don't see the New File icon?
Make sure you opened the folder (not just a file). The Explorer sidebar should show the folder name SPACE-COURSE-LANDING in uppercase at the top. If it says "Open a Folder" instead, go back to File > Open Folder and try again.
Help me create files in my VS Code project folder.
Generate the HTML boilerplate and launch Live Server
Every HTML page needs the same foundational structure. VS Code has a built-in shortcut called Emmet that generates this entire skeleton in one keystroke.
- Click on index.html in the Explorer sidebar to open it in the editor.
- Type ! (an exclamation mark) and press Tab.
VS Code fills the file with a complete HTML5 boilerplate. You'll now make two small edits to customize it for your project.
- Find the <title> tag (it currently says "Document").
- Replace the word Document with Space Science 101 - Online Course.
- Place your cursor at the end of the </title> line and press Enter to create a new line.
- Type the following on the new line to connect your CSS file:
<link rel="stylesheet" href="style.css">
Your complete index.html should now look like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Space Science 101 - Online Course</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
</body>
</html>
What does this code do?
- <!DOCTYPE html> tells the browser this is a modern HTML5 page.
- <meta charset="UTF-8"> sets the character encoding so special characters display correctly.
- <meta name="viewport" ...> makes the page scale properly on mobile devices.
- <link rel="stylesheet" href="style.css"> connects your CSS file so any styles you write there will apply to this page.
- Save index.html by pressing Cmd+S (macOS) or Ctrl+S (Windows).
- Right-click anywhere inside the index.html editor tab.
- Select Open with Live Server from the context menu.
Your default browser opens with a blank white page. This is correct. The page is empty because your <body> tag has no content yet.
How do I know Live Server is running?
Look at the VS Code status bar at the bottom of the window. You should see a "Port: 5500" indicator. Your browser's address bar should show 127.0.0.1:5500 or localhost:5500.
Don't see Open with Live Server?
Make sure you right-clicked inside the editor area (where your code is), not in the Explorer sidebar. If the option still doesn't appear, the Live Server extension may not have finished installing. Go back to the Extensions panel and verify it shows "Uninstall" instead of "Install".
You can also click the Go Live button in the bottom status bar of VS Code as an alternative way to start the server.
Help me get Live Server running in VS Code.
✔️ Awesome, I've got everything!
Great. Double check you've saved your file, and keep that browser tab open. You'll see it come to life as you add content in the next step.
ⓧ I'd like to double check the full code
Here is the complete index.html at this point. Your style.css file should still be empty.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Space Science 101 - Online Course</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
</body>
</html>
Your project environment is ready. You have a live-reloading browser preview and the two files that will hold your entire landing page. Next up, you'll fill that blank page with a proper HTML structure.
Build the HTML Structure
Your development environment is ready with Live Server auto-refreshing your browser on every save. Now it's time to fill that blank page with content.
Every webpage starts with structure. Semantic HTML elements like <header>, <main>, and <footer> tell the browser (and screen readers) what role each part of the page plays. In this step, you'll build the complete HTML skeleton for your landing page.
In this step, get ready to:
- Build the page skeleton with semantic HTML elements.
- Add a navigation bar, hero section, and feature cards.
- Create an instructor bio section and footer.
Create the page skeleton
The skeleton is the outermost structure of your page. You'll create a header for navigation, a main area for content sections, and a footer at the bottom.
- In index.html, find the empty <body> tags.
- Add the following code between the opening <body> and closing </body> tags:
<header>
<nav>
</nav>
</header>
<main>
<!-- Hero section - the big banner at the top -->
<section class="hero" id="enroll">
</section>
<!-- Features section - what students will learn -->
<section class="features" id="curriculum">
</section>
<!-- Instructor section - who teaches the course -->
<section class="instructor" id="instructor">
<div class="instructor-img"></div>
<h3>Dr. Elena Martinez</h3>
<p>Astrophysicist with 15 years of research experience at NASA. Passionate about making space science accessible to everyone.</p>
</section>
</main>
<footer>
<p>© 2026 Space Science 101. All rights reserved.</p>
<ul class="footer-links">
<li><a href="#">Privacy Policy</a></li>
<li><a href="#">Terms of Service</a></li>
<li><a href="#">Contact</a></li>
</ul>
</footer>
What does this code do?
You've set up three major page regions using semantic HTML:
- <header> contains the site's navigation bar. The <nav> inside it is empty for now.
- <main> holds all the primary content sections. Two sections (hero and features) are empty shells you'll fill next.
- The instructor section already has content: a placeholder <div> for a profile image, a name, and a short bio.
- <footer> sits at the very bottom with copyright text and utility links.
- Save index.html.
- Check your browser. You should see plain text for Dr. Elena Martinez's bio, the copyright line, and the three footer links. Everything is unstyled, which is expected.
Don't see any text in the browser?
- Make sure you pasted the code between <body> and </body>, not inside the <head> section.
- Confirm Live Server is still running. Look for the port number (e.g. Port: 5500) in the VS Code status bar at the bottom.
- help me figure out why my HTML isn't showing in the browser
Build the navigation
The navigation bar helps visitors jump to different sections of the page. You'll place the course name on the left and three anchor links on the right.
- In index.html, find the empty <nav> element inside <header>.
- Add the following code between the opening <nav> and closing </nav> tags:
<h2 class="logo">Space Science 101</h2>
<ul class="nav-links">
<li><a href="#curriculum">Curriculum</a></li>
<li><a href="#instructor">Instructor</a></li>
<li><a href="#enroll">Enroll</a></li>
</ul>
What does this code do?
- The <h2> with class logo displays the course brand name.
- The <ul> contains three list items, each wrapping an anchor link (<a>).
- Each href points to a section id on the page (like #curriculum). Clicking a link scrolls the page to that section.
- Save index.html.
- Check your browser. You should see "Space Science 101" and three bullet-pointed links (Curriculum, Instructor, Enroll) at the top of the page.
Links not appearing?
- Make sure the code is inside <nav> and </nav>, not below the closing tag.
- Check that each <li> has a matching </li> closing tag.
- help me fix my navigation HTML
Build the hero and features sections
The hero section is the first thing visitors see. It has a bold headline, a short description, and a call-to-action button. The features section showcases what the course covers using individual cards.
- Find the empty <section class="hero" id="enroll"> element.
- Add the following code between its opening and closing tags:
<h1>Explore the Universe from Your Living Room</h1>
<p>A beginner-friendly journey through stars, planets, and galaxies. No telescope required.</p>
<a href="#enroll" class="btn">Enroll Now</a>
What does this code do?
- The <h1> is the most important heading on the page. Every page should have exactly one.
- The <a> tag with class btn is a link that you'll style to look like a button later with CSS.
- Save index.html.
- Check your browser. You should see the heading "Explore the Universe from Your Living Room", a description paragraph, and an "Enroll Now" link above the instructor text.
Now for the features section. This uses a container div with three card divs inside it, one for each topic the course covers.
- Find the empty <section class="features" id="curriculum"> element.
- Add the following code between its opening and closing tags:
<h2>What You'll Learn</h2>
<div class="features-container">
<div class="feature-card">
<h3>The Solar System</h3>
<p>Tour the planets, moons, and asteroids that make up our cosmic neighborhood.</p>
</div>
<div class="feature-card">
<h3>Stars and Galaxies</h3>
<p>Understand how stars are born, live, and die across billions of years.</p>
</div>
<div class="feature-card">
<h3>Space Exploration</h3>
<p>From the Moon landing to Mars rovers, discover humanity's greatest adventures.</p>
</div>
</div>
What does this code do?
- The features-container div groups the three cards together. In a later step, you'll use Flexbox on this container to lay the cards out side by side.
- Each feature-card div is a self-contained unit with a title (<h3>) and a description (<p>).
- The class names (features-container, feature-card) are hooks for CSS to target these elements with styles later.
- Save index.html.
- Check your browser. You should see "What You'll Learn" followed by three topic titles (The Solar System, Stars and Galaxies, Space Exploration) with their descriptions.
Seeing jumbled or missing text?
- Check that every opening tag has a matching closing tag. A missing </div> can cause content to nest incorrectly.
- Make sure the features code is inside the <section class="features"> element, not inside the hero or instructor section.
- help me debug my HTML structure
✔️ Awesome, I've got everything!
Great. Double check you've saved your file and all the text content is visible in your browser.
ⓧ I'd like to double check the full code
Here's the complete index.html file at this point. Compare yours against it:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Space Science 101 - Online Course</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<nav>
<h2 class="logo">Space Science 101</h2>
<ul class="nav-links">
<li><a href="#curriculum">Curriculum</a></li>
<li><a href="#instructor">Instructor</a></li>
<li><a href="#enroll">Enroll</a></li>
</ul>
</nav>
</header>
<main>
<section class="hero" id="enroll">
<h1>Explore the Universe from Your Living Room</h1>
<p>A beginner-friendly journey through stars, planets, and galaxies. No telescope required.</p>
<a href="#enroll" class="btn">Enroll Now</a>
</section>
<section class="features" id="curriculum">
<h2>What You'll Learn</h2>
<div class="features-container">
<div class="feature-card">
<h3>The Solar System</h3>
<p>Tour the planets, moons, and asteroids that make up our cosmic neighborhood.</p>
</div>
<div class="feature-card">
<h3>Stars and Galaxies</h3>
<p>Understand how stars are born, live, and die across billions of years.</p>
</div>
<div class="feature-card">
<h3>Space Exploration</h3>
<p>From the Moon landing to Mars rovers, discover humanity's greatest adventures.</p>
</div>
</div>
</section>
<section class="instructor" id="instructor">
<div class="instructor-img"></div>
<h3>Dr. Elena Martinez</h3>
<p>Astrophysicist with 15 years of research experience at NASA. Passionate about making space science accessible to everyone.</p>
</section>
</main>
<footer>
<p>© 2026 Space Science 101. All rights reserved.</p>
<ul class="footer-links">
<li><a href="#">Privacy Policy</a></li>
<li><a href="#">Terms of Service</a></li>
<li><a href="#">Contact</a></li>
</ul>
</footer>
</body>
</html>
Your page has all the content it needs, but it looks like a plain text document. Next up, you'll transform it into a polished design using CSS for colors, spacing, and typography.
Style the Page with CSS Basics
Your HTML structure is complete, but right now the page looks like a plain document with default browser styling. CSS is the language that transforms that raw structure into something visually polished.
In this step, you will write CSS that resets browser defaults, sets up consistent typography, styles the navigation bar with Flexbox, and creates a striking hero section with a call-to-action button.
In this step, get ready to:
- Add a universal CSS reset and base typography styles.
- Style the navigation bar using Flexbox to position the logo and links.
- Style the hero section with centered text and a bold button.
Add the CSS reset and base styles
Every browser applies its own default margins, padding, and font to HTML elements. A CSS reset removes those inconsistencies so your design looks the same everywhere.
- Open style.css in VS Code and add the universal reset and body styles:
/* Universal reset removes default browser margins and padding */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
/* Base typography for the entire page */
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 16px;
line-height: 1.6;
color: #333;
}
What does this code do?
The * selector targets every element on the page. Setting box-sizing: border-box makes padding and borders count inside an element's width instead of adding to it. This prevents layout surprises later.
The body styles set a clean sans-serif font stack starting with Segoe UI (the default Windows system font). The line-height: 1.6 adds comfortable spacing between lines of text.
- Save style.css.
- Check your browser. The page's default spacing around edges should disappear, and the font should change from the browser's serif default to a cleaner sans-serif font.
Page looks exactly the same?
Make sure you saved style.css (Ctrl+S on Windows, Cmd+S on macOS). Live Server only refreshes when files are saved.
Confirm that index.html has the line <link rel="stylesheet" href="style.css"> inside the <head> tag. Without this link, the browser does not know your stylesheet exists.
help me figure out why my CSS file is not being applied to my HTML page
Style the navigation bar
The navigation bar needs to show the course name on the left and the links on the right. Flexbox is perfect for this because it lets you distribute items along a horizontal axis with a single property.
- Below the body styles in style.css, add the header and nav layout styles:
/* Navigation */
header {
background-color: #1a1a2e;
padding: 0 2rem;
}
nav {
display: flex;
justify-content: space-between;
align-items: center;
height: 64px;
max-width: 1100px;
margin: 0 auto;
}
What does this code do?
The header gets a dark navy background that spans the full page width. The nav inside it uses display: flex to arrange its children (logo and links) in a row.
The property justify-content: space-between pushes the logo to the left and links to the right. The max-width: 1100px with margin: 0 auto centers the nav content so it does not stretch edge-to-edge on wide monitors.
- Save style.css.
- Check your browser. You should see a dark navy bar across the top of the page with "Space Science 101" and the links spread to opposite sides.
The text is hard to read because it is still dark on a dark background. The next chunk fixes that.
- Below the nav styles, add the logo and link styles:
.logo {
color: #fff;
font-size: 1.3rem;
}
.nav-links {
list-style: none;
display: flex;
gap: 1.5rem;
}
.nav-links a {
color: #ccc;
text-decoration: none;
font-size: 0.95rem;
}
.nav-links a:hover {
color: #fff;
}
What does this code do?
The .logo class makes the course name white so it stands out against the dark header. The .nav-links removes bullet points with list-style: none and uses display: flex with gap: 1.5rem to arrange the links horizontally with even spacing.
The a:hover rule brightens links to pure white when you hover over them, giving the user visual feedback.
- Save style.css.
- Check your browser. The nav bar should now show a white "Space Science 101" on the left and light gray links (Curriculum, Instructor, Enroll) on the right. Hover over a link to see it turn white.
Links still have bullet points or are stacked vertically?
Make sure your .nav-links selector targets the <ul> element with class="nav-links" in your HTML. A typo in the class name means the CSS will not apply.
Check that display: flex is on the .nav-links rule, not on .nav-links a. Flex needs to be on the parent container of the items you want side-by-side.
help me fix my navigation links layout
Style the hero section and button
The hero section is the first thing visitors see. It needs a bold background, large text, and a prominent button that invites them to take action.
- Below the navigation styles in style.css, add the hero section styles:
/* Hero Section */
.hero {
background-color: #16213e;
color: #fff;
text-align: center;
padding: 5rem 2rem;
}
.hero h1 {
font-size: 2.5rem;
margin-bottom: 1rem;
max-width: 700px;
margin-left: auto;
margin-right: auto;
}
.hero p {
font-size: 1.1rem;
margin-bottom: 2rem;
color: #ccc;
max-width: 600px;
margin-left: auto;
margin-right: auto;
}
What does this code do?
The .hero section gets a slightly lighter navy background than the nav, white text, and generous padding (5rem top/bottom) to give the headline breathing room.
Both the h1 and p use max-width with margin-left: auto and margin-right: auto to keep the text from stretching too wide on large screens. This improves readability.
- Save style.css.
- Check your browser. Below the nav, you should see a large dark section with "Explore the Universe from Your Living Room" as a big white heading and the description in lighter gray below it.
The "Enroll Now" link still looks like plain text. The next chunk turns it into a proper button.
- Below the hero paragraph styles, add the button styles:
.btn {
display: inline-block;
background-color: #e94560;
color: #fff;
padding: 0.8rem 2rem;
border-radius: 5px;
text-decoration: none;
font-size: 1rem;
font-weight: 600;
}
.btn:hover {
background-color: #c23152;
}
What does this code do?
The .btn class transforms a regular <a> link into a button. The display: inline-block allows padding to expand the element. The coral red background (#e94560) creates a strong visual contrast against the dark hero section.
The text-decoration: none removes the default underline. The :hover state darkens the button color slightly when hovered, giving users a clear signal that it is clickable.
- Save style.css.
- Check your browser. You should see a bold coral-red "Enroll Now" button centered below the hero description. Hover over it to see the color darken.
Button still looks like a plain link?
Check that the <a> tag in your HTML has class="btn". Without the class, the CSS selector .btn has nothing to target.
Make sure display: inline-block is present. Without it, the padding will not expand the link into a button shape because anchor tags are inline elements by default.
help me figure out why my button is not styled
✔️ Awesome, I've got everything!
Great. Double check you have saved style.css before moving on.
ⓧ I'd like to double check the full code
Here is the complete style.css file up to this point. Compare your code against it:
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 16px;
line-height: 1.6;
color: #333;
}
/* Navigation */
header {
background-color: #1a1a2e;
padding: 0 2rem;
}
nav {
display: flex;
justify-content: space-between;
align-items: center;
height: 64px;
max-width: 1100px;
margin: 0 auto;
}
.logo {
color: #fff;
font-size: 1.3rem;
}
.nav-links {
list-style: none;
display: flex;
gap: 1.5rem;
}
.nav-links a {
color: #ccc;
text-decoration: none;
font-size: 0.95rem;
}
.nav-links a:hover {
color: #fff;
}
/* Hero Section */
.hero {
background-color: #16213e;
color: #fff;
text-align: center;
padding: 5rem 2rem;
}
.hero h1 {
font-size: 2.5rem;
margin-bottom: 1rem;
max-width: 700px;
margin-left: auto;
margin-right: auto;
}
.hero p {
font-size: 1.1rem;
margin-bottom: 2rem;
color: #ccc;
max-width: 600px;
margin-left: auto;
margin-right: auto;
}
.btn {
display: inline-block;
background-color: #e94560;
color: #fff;
padding: 0.8rem 2rem;
border-radius: 5px;
text-decoration: none;
font-size: 1rem;
font-weight: 600;
}
.btn:hover {
background-color: #c23152;
}
Your page already looks like a real course website with a professional nav bar and eye-catching hero. Next up, you will use Flexbox again to lay out the feature cards side by side.
Layout the Features Section with Flexbox
Your navigation bar and hero section look polished. The "What You'll Learn" section and instructor bio below them still appear as unstyled text stacked against the left edge of the page.
In this step, you will use Flexbox to arrange the three feature cards side-by-side in a row. You will also style the instructor section with a circular avatar placeholder and centered text.
In this step, get ready to:
- Style the features section with a Flexbox layout that places cards in a row.
- Add padding, shadows, and rounded corners to each feature card.
- Style the instructor section with a circular image placeholder and centered bio.
Style the features section container with Flexbox
Right now the three feature cards stack vertically because that is how block-level <div> elements behave by default. Flexbox lets you place them in a horizontal row with even spacing.
- In style.css, scroll to the bottom of your file (below the .btn:hover rule).
- Add the following CSS to style the features section wrapper, its heading, and the flex container:
/* Features Section */
.features {
padding: 4rem 2rem;
text-align: center;
max-width: 1100px;
margin: 0 auto;
}
.features h2 {
font-size: 2rem;
margin-bottom: 2rem;
}
.features-container {
display: flex;
justify-content: center;
gap: 2rem;
flex-wrap: wrap;
}
What does this code do?
The .features rule centers the entire section on the page with margin: 0 auto and caps its width at 1100px so it does not stretch too wide on large monitors.
The .features-container rule turns on Flexbox with display: flex. The gap: 2rem adds even spacing between cards, and flex-wrap: wrap allows the cards to drop to a new row if the screen is too narrow to fit them all.
- Save style.css.
- Check your browser. You should see the three feature headings ("The Solar System", "Stars and Galaxies", "Space Exploration") arranged in a horizontal row instead of stacked vertically.
Cards still stacked vertically?
Make sure you added the styles to .features-container (the div that wraps the cards), not to .features (the section element). The flex container must be the direct parent of the items you want laid out in a row.
Also confirm your CSS class name matches the HTML exactly. In your index.html, the div uses class="features-container" with a hyphen.
Still stuck? Help me debug why my Flexbox cards are not sitting side-by-side.
Style each feature card
The cards are in a row now, but they have no visual separation from the page background. Adding padding, a background color, and a shadow makes each card look like a distinct, elevated element.
- Below the .features-container rule you just added, paste the following card styles:
.feature-card {
flex: 1 1 250px;
background-color: #f8f9fa;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.feature-card h3 {
margin-bottom: 0.5rem;
color: #1a1a2e;
}
What does flex: 1 1 250px mean?
This shorthand sets three Flexbox properties at once. The first 1 means each card can grow to fill available space. The second 1 means each card can also shrink if needed. The 250px sets a minimum base width before growing or shrinking kicks in.
The box-shadow property adds a subtle drop shadow below each card. The rgba(0, 0, 0, 0.1) value creates a black shadow at 10% opacity, giving a soft, lifted appearance.
- Save style.css and check your browser.
- You should see three evenly spaced cards with a light gray background, rounded corners, and a soft shadow beneath each one.
Cards look cramped or overlap?
Check that the gap: 2rem property is on .features-container (the parent), not on .feature-card. The gap property only works on the flex container itself.
Need more help? Why do my feature cards look cramped or overlap each other?
Style the instructor section
The instructor section needs a centered layout with a circular avatar. Since no actual image file is needed, a colored <div> with border-radius: 50% creates a perfect circle that acts as a placeholder.
- Below the .feature-card h3 rule, add the following instructor styles:
/* Instructor Section */
.instructor {
text-align: center;
padding: 4rem 2rem;
background-color: #f0f0f0;
}
.instructor-img {
width: 120px;
height: 120px;
border-radius: 50%;
background-color: #1a1a2e;
margin: 0 auto 1rem auto;
}
.instructor h3 {
font-size: 1.3rem;
margin-bottom: 0.5rem;
}
.instructor p {
max-width: 500px;
margin: 0 auto;
color: #555;
}
What does this code do?
The .instructor-img rule sets equal width and height (120px) and uses border-radius: 50% to turn the square <div> into a perfect circle. The margin: 0 auto 1rem auto centers it horizontally and adds spacing below.
The .instructor p rule caps the bio paragraph at 500px wide and centers it with margin: 0 auto. This keeps long text from stretching uncomfortably across the full page width.
- Save style.css and check your browser.
- Below the feature cards, you should see a dark navy circle centered above the name "Dr. Elena Martinez" and a short bio paragraph.
Don't see the circle?
The circle is a <div> with no content, so it only appears if you have both width and height set. Make sure your .instructor-img rule includes width: 120px and height: 120px. Without explicit dimensions, an empty div collapses to zero height.
Need help? My instructor avatar circle is not showing up on the page.
✔️ Awesome, I've got everything!
Great. Double check you have saved style.css before moving on.
ⓧ I'd like to double check the full code
Here is the complete style.css file up to this point. Compare it against yours:
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 16px;
line-height: 1.6;
color: #333;
}
/* Navigation */
header {
background-color: #1a1a2e;
padding: 0 2rem;
}
nav {
display: flex;
justify-content: space-between;
align-items: center;
height: 64px;
max-width: 1100px;
margin: 0 auto;
}
.logo {
color: #fff;
font-size: 1.3rem;
}
.nav-links {
list-style: none;
display: flex;
gap: 1.5rem;
}
.nav-links a {
color: #ccc;
text-decoration: none;
font-size: 0.95rem;
}
.nav-links a:hover {
color: #fff;
}
/* Hero Section */
.hero {
background-color: #16213e;
color: #fff;
text-align: center;
padding: 5rem 2rem;
}
.hero h1 {
font-size: 2.5rem;
margin-bottom: 1rem;
max-width: 700px;
margin-left: auto;
margin-right: auto;
}
.hero p {
font-size: 1.1rem;
margin-bottom: 2rem;
color: #ccc;
max-width: 600px;
margin-left: auto;
margin-right: auto;
}
.btn {
display: inline-block;
background-color: #e94560;
color: #fff;
padding: 0.8rem 2rem;
border-radius: 5px;
text-decoration: none;
font-size: 1rem;
font-weight: 600;
}
.btn:hover {
background-color: #c23152;
}
/* Features Section */
.features {
padding: 4rem 2rem;
text-align: center;
max-width: 1100px;
margin: 0 auto;
}
.features h2 {
font-size: 2rem;
margin-bottom: 2rem;
}
.features-container {
display: flex;
justify-content: center;
gap: 2rem;
flex-wrap: wrap;
}
.feature-card {
flex: 1 1 250px;
background-color: #f8f9fa;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.feature-card h3 {
margin-bottom: 0.5rem;
color: #1a1a2e;
}
/* Instructor Section */
.instructor {
text-align: center;
padding: 4rem 2rem;
background-color: #f0f0f0;
}
.instructor-img {
width: 120px;
height: 120px;
border-radius: 50%;
background-color: #1a1a2e;
margin: 0 auto 1rem auto;
}
.instructor h3 {
font-size: 1.3rem;
margin-bottom: 0.5rem;
}
.instructor p {
max-width: 500px;
margin: 0 auto;
color: #555;
}
Your features and instructor sections are looking professional. Next up, you will build the footer and add a media query so the entire page adapts gracefully to smaller screens.
Add the Footer and Make It Responsive
Your landing page has a styled nav, hero, features grid, and instructor section. The last missing piece is the footer at the bottom of the page.
Right now, the page only looks good on a wide desktop screen. Real visitors will view your page on phones and tablets too. In this step, you'll style the footer and add a media query that adapts the layout for smaller screens.
In this step, get ready to:
- Style the footer to match the nav's dark theme.
- Add a media query to make the page responsive on smaller screens.
- Test the responsive layout in Chrome DevTools.
Style the footer
The footer HTML already exists in your index.html from a previous step. You just need to add the CSS to give it the same dark look as the navigation bar.
- In style.css, scroll to the bottom of the file (below the instructor styles) and add the footer styles:
/* Footer */
footer {
background-color: #1a1a2e;
color: #ccc;
text-align: center;
padding: 2rem;
}
.footer-links {
list-style: none;
display: flex;
justify-content: center;
gap: 1.5rem;
margin-top: 0.5rem;
}
.footer-links a {
color: #ccc;
text-decoration: none;
font-size: 0.9rem;
}
.footer-links a:hover {
color: #fff;
}
What does this code do?
- background-color: #1a1a2e gives the footer the same dark navy as the header, creating visual bookends for the page.
- display: flex and justify-content: center on .footer-links places the three links side-by-side in the center.
- The :hover rule brightens links from grey to white when the learner moves their cursor over them.
- Save style.css.
- Check your browser. You should see a dark footer at the bottom of the page with a copyright line and three centered links (Privacy Policy, Terms of Service, Contact).
Footer not showing up?
- Make sure you saved style.css. Unsaved changes won't appear in the browser.
- Scroll all the way to the bottom of your page. The footer sits below the instructor section and may be off-screen.
- Check that your CSS selector says footer (no dot or hash). It targets the HTML element directly.
Help me debug why my footer styles aren't showing up.
Add a media query for smaller screens
A media query lets you write CSS rules that only activate when the screen is below a certain width. This is how you make a page responsive.
- At the very bottom of style.css (below the footer hover style), add this media query:
/* Responsive Design */
@media (max-width: 768px) {
nav {
flex-direction: column;
height: auto;
padding: 1rem 0;
gap: 0.5rem;
}
.hero {
padding: 3rem 1.5rem;
}
.hero h1 {
font-size: 1.8rem;
}
.features-container {
flex-direction: column;
align-items: center;
}
.feature-card {
max-width: 400px;
}
}
What does this code do?
Everything inside @media (max-width: 768px) only applies when the browser window is 768 pixels wide or narrower. On wider screens, these rules are completely ignored.
- flex-direction: column on the nav stacks the logo above the links instead of placing them side-by-side.
- flex-direction: column on .features-container stacks the three feature cards vertically instead of in a row.
- Reducing padding and font sizes on the hero prevents the heading from overflowing on a small screen.
- Save style.css.
- Resize your browser window to be very narrow. You should see the nav links drop below the logo, and the feature cards stack into a single column.
Layout not changing when you resize?
- Make sure the @media block is at the very bottom of your file, after all other styles. CSS reads top to bottom, so the media query must come last to override earlier rules.
- Check for missing curly braces. The media query has an outer { } pair and each rule inside also has its own { } pair.
- Confirm the viewport meta tag exists in your index.html <head>. Without it, mobile browsers ignore media queries.
Help me debug why my media query is not working.
✔️ Awesome, I've got everything!
Great. Double check you've saved your file before moving on.
ⓧ I'd like to double check the full code
Here is the complete style.css file as it should look now:
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 16px;
line-height: 1.6;
color: #333;
}
/* Navigation */
header {
background-color: #1a1a2e;
padding: 0 2rem;
}
nav {
display: flex;
justify-content: space-between;
align-items: center;
height: 64px;
max-width: 1100px;
margin: 0 auto;
}
.logo {
color: #fff;
font-size: 1.3rem;
}
.nav-links {
list-style: none;
display: flex;
gap: 1.5rem;
}
.nav-links a {
color: #ccc;
text-decoration: none;
font-size: 0.95rem;
}
.nav-links a:hover {
color: #fff;
}
/* Hero Section */
.hero {
background-color: #16213e;
color: #fff;
text-align: center;
padding: 5rem 2rem;
}
.hero h1 {
font-size: 2.5rem;
margin-bottom: 1rem;
max-width: 700px;
margin-left: auto;
margin-right: auto;
}
.hero p {
font-size: 1.1rem;
margin-bottom: 2rem;
color: #ccc;
max-width: 600px;
margin-left: auto;
margin-right: auto;
}
.btn {
display: inline-block;
background-color: #e94560;
color: #fff;
padding: 0.8rem 2rem;
border-radius: 5px;
text-decoration: none;
font-size: 1rem;
font-weight: 600;
}
.btn:hover {
background-color: #c23152;
}
/* Features Section */
.features {
padding: 4rem 2rem;
text-align: center;
max-width: 1100px;
margin: 0 auto;
}
.features h2 {
font-size: 2rem;
margin-bottom: 2rem;
}
.features-container {
display: flex;
justify-content: center;
gap: 2rem;
flex-wrap: wrap;
}
.feature-card {
flex: 1 1 250px;
background-color: #f8f9fa;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.feature-card h3 {
margin-bottom: 0.5rem;
color: #1a1a2e;
}
/* Instructor Section */
.instructor {
text-align: center;
padding: 4rem 2rem;
background-color: #f0f0f0;
}
.instructor-img {
width: 120px;
height: 120px;
border-radius: 50%;
background-color: #1a1a2e;
margin: 0 auto 1rem auto;
}
.instructor h3 {
font-size: 1.3rem;
margin-bottom: 0.5rem;
}
.instructor p {
max-width: 500px;
margin: 0 auto;
color: #555;
}
/* Footer */
footer {
background-color: #1a1a2e;
color: #ccc;
text-align: center;
padding: 2rem;
}
.footer-links {
list-style: none;
display: flex;
justify-content: center;
gap: 1.5rem;
margin-top: 0.5rem;
}
.footer-links a {
color: #ccc;
text-decoration: none;
font-size: 0.9rem;
}
.footer-links a:hover {
color: #fff;
}
/* Responsive Design */
@media (max-width: 768px) {
nav {
flex-direction: column;
height: auto;
padding: 1rem 0;
gap: 0.5rem;
}
.hero {
padding: 3rem 1.5rem;
}
.hero h1 {
font-size: 1.8rem;
}
.features-container {
flex-direction: column;
align-items: center;
}
.feature-card {
max-width: 400px;
}
}
Test the responsive layout in DevTools
Dragging your browser window to resize it works, but Chrome DevTools has a device toolbar that simulates exact phone and tablet sizes. This is the professional way to test responsive designs.
- In your browser, press F12 to open Chrome DevTools.
- Click the Toggle device toolbar button (it looks like a phone and tablet icon) in the top-left corner of the DevTools panel. You can also press Ctrl+Shift+M (Windows) or Cmd+Shift+M (macOS).
- Select a device from the dropdown at the top (try iPhone SE or iPad Air).
- Verify that the nav links stack below the logo, the feature cards appear in a single column, and the hero text is smaller.
- Switch back to Responsive in the device dropdown and drag the width handle wider than 768px. Confirm the layout snaps back to the desktop version.
Why 768px?
768px is a standard breakpoint that roughly separates tablets from desktops. Most CSS frameworks use this value as their "medium" breakpoint. It catches the majority of phone and tablet screens in one rule.
Your landing page is now fully styled and responsive. Next up, the Secret Mission challenges you to add an interactive testimonials section with hover effects.
Secret mission
Add a Student Testimonials Section
Your landing page looks professional, but real course platforms show social proof. Can you add a "What Students Say" section with styled testimonial cards that respond to hover and stack on mobile?
Clean Up Your Resources
Clean Up Your Resources
This project runs entirely locally, so there are no ongoing costs. Decide whether to keep your files for future reference, or delete them to free up space.
Resources you used:
- The space-course-landing folder on your Desktop (contains index.html and style.css).
- The Live Server extension installed in VS Code.
Keep everything running
No action needed. Choose this if you want to keep experimenting with your landing page or use it as a reference for future projects.
- Your space-course-landing folder stays on your Desktop.
- The Live Server extension remains installed in VS Code for other projects.
Pause - I'll come back to this later
Since this is a local project with no running processes, there is nothing to pause. Your files sit on disk without using any active resources.
- If Live Server is still running (you see the port number in the VS Code status bar), click it to stop the server.
- Close the browser tab showing your landing page.
- Your files remain on your Desktop whenever you are ready to come back.
Delete - I don't want to use this again
Remove all project files and optionally uninstall the Live Server extension.
- Delete the space-course-landing folder from your Desktop.
- To uninstall Live Server, open the Extensions panel in VS Code (Ctrl+Shift+X on Windows or Cmd+Shift+X on macOS), find Live Server, and click Uninstall.
Nice Work!
Nice Work!
Congratulations! You just built a professional-looking course landing page from scratch using nothing but HTML and CSS.
You've learned how to:
- Structure a complete webpage using semantic HTML elements like <header>, <nav>, <main>, <section>, and <footer>.
- Create flexible, aligned layouts with Flexbox for the navbar and feature cards, and style typography, colors, and spacing with CSS.
- Make the page responsive using a media query so it adapts to any screen size.
- Add an interactive testimonials section with hover effects.
Ready to quiz yourself?