Interactive Flexbox Tutorial

Two-Column Flexbox with Sticky Sidebar + Anchor Nav

0% Complete

What You'll Build

Goal: Create a two-column page with Flexbox: a 300px sticky sidebar on the left and a scrollable content column on the right. Nav links jump to section IDs.

What you'll learn:

  • Setting up a parent flex container (horizontal layout)
  • Making a fixed-width sidebar + flexible content column
  • Using anchor links to jump within the page
  • Making the sidebar sticky with CSS
  • Positioning decorative elements without blocking content

Part A — Scaffold the HTML

A1) Start file + semantic structure

Create your HTML with a semantic skeleton. Do not change class names; add your content where noted.

Your HTML should include:

  • A <header> with an <h1> for your page title and a <p> for a description
  • A <main class="container"> element
  • A <nav class="sidebar"> with 5 anchor links. Use <a href="#"></a> as placeholders for now—we'll connect them to sections next.
  • A <div class="content"> with 3-5 sections. Give each section an id attribute labeled id="section-1", id="section-2", etc.
  • Each section needs a <div class="deco" id="deco-1"> for decoration. Give each deco div a unique id: id="deco-1", id="deco-2", etc.
  • A <footer> with basic info (note: place this outside the <main> element)
📝 Note: The <footer> should be placed outside (after) the <main> element. The <main> element represents the dominant content of your page—in this case, the two-column layout with sidebar and content. The footer contains supplementary information and isn't part of that flex layout.

A2) Add Content

Now that you have your structure, you need content to fill it! We've provided sample flexbox-themed content for you to use.

What you'll get:

  • 5 navigation link titles (e.g., "What is Flexbox?", "Flex Containers", etc.)
  • 5 sections of varied-length content about flexbox concepts
  • Mix of educational and engaging text to test your layout

✅ Checkpoint A

  • Do you have five nav items with anchor links?
  • Do your sections have unique ids like id="section-1", id="section-2", etc.?
  • Did you update your anchor hrefs to match section ids (e.g., href="#section-1")?
  • Did you add content to your navigation links and sections from the sample content?
  • Did you include a <div class="deco"> with a unique id inside each section (e.g., id="deco-1")?
  • Is your <footer> placed outside the <main> element?

🤔 Reflect (2–3 sentences):

What advantages do you see in giving each section a unique id? Where could id vs. class trip you up?

Part B — Flexbox Two-Column Layout

B1) Identify the Flexbox parent

Question: What element do you think the flexbox parent is? Why?

💡 Hint: The flexbox parent is the container for the flex items. In this case, our flex items are the sidebar and the content.

Once you've identified the flexbox parent, add CSS to make it a flex container. This sets up your two-column layout.

B2) Sidebar vs. content sizing

Give the sidebar a fixed 300px width that won't grow or shrink. Let the content area flex to fill the remaining space.

For the sidebar (.sidebar):

  • Set width: 300px;
  • Set flex-grow: 0; (don't grow)
  • Set flex-shrink: 0; (don't shrink)
  • Set flex-basis: 300px; (start at 300px)
  • Add some styling: padding, background, and border-radius

For the content (.content):

  • Set flex-grow: 1; (grow to fill space)
  • Set flex-shrink: 1; (can shrink if needed)
  • Set flex-basis: auto; (start with content size)

B3) Understanding what you just did

Let's break down what you accomplished with those flex properties:

🎯 The sidebar stays fixed:
  • flex-grow: 0; — The sidebar won't expand when there's extra space
  • flex-shrink: 0; — The sidebar won't shrink when space gets tight
  • flex-basis: 300px; — The sidebar starts at 300px and stays there
  • Result: Your sidebar remains exactly 300px wide, no matter the screen size
🎯 The content area is flexible:
  • flex-grow: 1; — The content expands to fill all available space
  • flex-shrink: 1; — The content can shrink if the viewport gets smaller
  • flex-basis: auto; — The content starts with its natural size, then adjusts
  • Result: Your content area fills the remaining space after the sidebar takes its 300px
💡 Why this works: In a flex container, items compete for space. By setting the sidebar to not grow or shrink (0, 0), it claims its 300px and refuses to budge. The content area, with grow: 1, says "I'll take whatever's left!" This is how you create fixed-width sidebars with flexible content areas—a common pattern in web design.

✅ Checkpoint B

  • Does the layout show two columns?
  • Is the sidebar exactly 300px?
  • Does the content area expand when you widen the window?

🤔 Reflect (2–3 sentences):

What's the difference between width and flex-basis in your mental model? When might you prefer one over the other?

Part C — Sticky Sidebar (No JavaScript)

C1) Make the sidebar sticky

Now let's make the sidebar stay pinned while you scroll the page. This is pure CSS—no JavaScript needed!

📚 First, do some research:

  1. Read the MDN docs on position: sticky
  2. Pay attention to:
    • What value you need for the position property
    • What the top property does with sticky positioning
    • How to handle overflow with max-height and overflow

Your task: Add CSS to .sidebar to make it stick to the top of the viewport when scrolling.

⚠️ Common gotcha: Sticky positioning only works when the element's ancestor allows it (no overflow: hidden on parent elements). Keep .container simple!

✅ Checkpoint C

  • When you scroll, does the sidebar stay pinned?
  • If you add a tall header later, would you need to adjust top?

🤔 Reflect (2–3 sentences):

In your words, why is position: sticky different from position: fixed here?

Part D — Anchor Links + Scroll Polish

D1) Test your anchor links

Verify your HTML setup:

  1. Check that each navigation link has an href pointing to a section id (e.g., href="#section-1")
  2. Confirm each section has a matching id attribute (e.g., id="section-1")
  3. Click each navigation link to test—does it jump to the correct section?
💡 How anchor links work: When you click a link with href="#section-1", the browser looks for an element with id="section-1" and scrolls to it. The # symbol tells the browser to look for an id on the current page rather than navigating to a new page.

D2) Smooth scroll + heading alignment

Right now, clicking anchor links causes an instant jump. Let's add smooth scrolling and prevent headings from being cut off at the top.

📚 Research these CSS properties:

  1. Smooth scrolling: Read about scroll-behavior on MDN
    • What element does this property go on? (html or your sections?)
    • What value creates smooth scrolling?
  2. Scroll margin: Read about scroll-margin-top on MDN
    • Why would you need space at the top when jumping to a section?
    • What's a good value to prevent headings from being glued to the edge?

Your task: Add CSS for smooth scrolling and proper spacing when jumping to sections. Also, add some visual styling to your sections (padding, background, borders, etc.).

✅ Checkpoint D

  • Clicking each nav item jumps to the right section smoothly
  • The heading is comfortably visible after the jump

🤔 Reflect (2–3 sentences):

What problems might appear if you later add a fixed header? How would scroll-margin-top help?

Part E — Decorative Icons (Per Section)

E1) Download icons from The Noun Project

Let's add visual interest to each section with thematic icons related to flexbox and web design.

📥 Download icons:

  1. Go to The Noun Project
  2. Search for flexbox-related terms like:
    • "layout" or "grid"
    • "container" or "box"
    • "align" or "arrange"
    • "responsive" or "adapt"
    • "web design" or "code"
  3. Download 5 icons (one for each section) as PNG or SVG files
  4. Choose icons that complement your content themes
  5. Note: Free icons are available! Look for the "Free" filter or create a free account
💡 Icon tips:
  • Download in a consistent style (all line art, all filled, etc.)
  • Choose a reasonable size (128px or 256px works well)
  • SVG files are preferred—they scale perfectly and have smaller file sizes
  • Save them with descriptive names like icon-flexbox.svg, icon-container.svg, etc.

E2) Add icons to your HTML

Now let's add the icons to each section's deco div.

For CodePen users (using Snipboard):

  1. Go to Snipboard.io
  2. Click "Upload Files" and select your 5 icons
  3. Once uploaded, click each image and copy its direct URL
  4. In your HTML, update each deco div to include an <img> tag:
    <div class="deco" id="deco-1">
      <img src="SNIPBOARD_URL_HERE" alt="">
    </div>
  5. Repeat for all 5 sections with their respective icon URLs
⚠️ Important for Final Project: When you create your final project submission (not in CodePen), you'll need to:
  • Create an images folder in your project directory
  • Save all your icon files in that folder
  • Update your image paths to images/icon-name.svg
  • This ensures your images work when you submit your files or host your site

For local files (working outside CodePen):

  1. Create an images folder in your project directory
  2. Move your downloaded icons into that folder
  3. Reference them in your HTML:
    <div class="deco" id="deco-1">
      <img src="images/icon-flexbox.svg" alt="">
    </div>
📝 Accessibility Note: We use alt="" (empty alt text) because these icons are purely decorative and don't convey essential information. Screen readers will skip them.

E3) Style the decorative icons

Style the icons so they add visual interest without interfering with content.

📚 Research CSS positioning:

Your task: Style the .deco class and the img inside it:

  • Position decorations absolutely so they don't affect layout
  • Make them semi-transparent with opacity
  • Prevent them from blocking clicks with pointer-events: none
  • Size the images appropriately (try 150-200px)

E4) Position each icon uniquely

Style each decoration differently using their unique ids. Place icons in different positions to create visual variety.

Your task: Use id selectors to position each icon differently:

  • #deco-1 — Try top: -10%; left: -5%;
  • #deco-2 — Try top: 50%; right: -5%;
  • #deco-3 — Try bottom: -10%; left: 50%;
  • Continue for remaining sections with your own creative positions!

✅ Checkpoint E

  • Downloaded 5 icons from The Noun Project (or similar icon source)
  • Added <img> tags inside each .deco div
  • Icons are positioned absolutely and don't block content
  • Icons are semi-transparent and subtle
  • Each icon has a unique position using id selectors
  • Text remains readable and links are clickable

🤔 Reflect (2–3 sentences):

How did you ensure decoration didn't harm readability or usability? What would you change for dark vs. light themes?

Part F — Finishing Touches (Optional)

Optional Enhancements

Polish your project with these accessibility and usability improvements. Note: While optional, completing Part F demonstrates attention to accessibility and can earn you extra consideration in grading.

  • Add a focus style for sidebar links (:focus-visible)
  • Style the active link based on scroll (stretch goal with IntersectionObserver)
  • Add a "Back to top" link at the end of each section

✅ Checkpoint F

  • Focus styles are visible and clear
  • Navigation has good accessibility

🤔 Reflect (2–3 sentences):

What one improvement most increases usability? Why?

Part G — Save Your Reflections

G1) Copy reflections to your HTML

Save your reflections directly in your CodePen HTML file so they're preserved with your work.

📋 Steps:

  1. Click the "Copy All Reflections" button below
  2. Go to your CodePen HTML editor
  3. Scroll to the very bottom of your HTML (after the closing </footer> tag)
  4. Paste your reflections
  5. Your reflections are now saved as an HTML comment in your code!
💡 Why save reflections in HTML? By pasting them as an HTML comment at the bottom of your code, they're permanently saved with your project. When you submit your CodePen link, your instructor can view both your code and reflections in one place.

✅ Checkpoint G

  • Clicked "Copy All Reflections" button
  • Pasted reflections at the bottom of HTML in CodePen
  • Verified reflections are visible in HTML (as a comment)

📤 Submission

What to submit to Canvas

  1. Your CodePen link — Make sure your pen is saved and public
  2. That's it! Your reflections are already in your HTML at the bottom
⚠️ Before submitting:
  • Verify your CodePen is saved (not showing "unsaved changes")
  • Test that your CodePen link opens correctly in a new browser tab
  • Confirm your reflections are pasted at the bottom of your HTML

Add to your homepage

Link to this tutorial from your workspace homepage (index.html):

<a href="YOUR_CODEPEN_LINK">Flexbox Tutorial</a>

This way, your instructor can easily find all your work from your main workspace page.

Final Checklist

  • Sidebar is 300px and sticky
  • Five nav items link to matching ids
  • Right column flexes to fill space (Flexbox only—no grid)
  • Smooth scrolling works; headings aren't jammed at the top
  • Each section includes a decorative icon that doesn't block content
  • Basic accessibility: reasonable contrast, visible focus on nav links

Grading Rubric (10 pts)

  • 4 pts — Layout correctness (Flexbox, 300px sidebar, sticky behavior)
  • 3 pts — Anchors & scroll polish (IDs matched, smooth scroll, scroll-margin)
  • 2 pts — Decorative icons (positioned safely with absolute positioning, varied locations)
  • 1 pt — Reflection quality (clear, specific, shows understanding)

Your Workspace

Code along as you follow the tutorial →