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.

πŸ“Œ Read this first: Start from the CodePen starter template. It already contains the full HTML structure and all the text. You do not write any HTML in this tutorialβ€”your job is the CSS. Part A is a quick tour of the code you've been given. The real work starts in Part B, where you write CSS under the /* Part B */ comment in the CSS panel.

What you'll learn:

  • Reading a semantic HTML structure so you know what you're styling
  • Setting up a parent flex container (horizontal layout)
  • Making a fixed-width sidebar + flexible content column
  • Making the sidebar sticky with CSS
  • Adding smooth-scrolling anchor navigation
  • Positioning decorative elements without blocking content

Part A β€” Meet Your Starter Code

A1) Open your starter and read the code

Open the CodePen starter template. You are not writing any HTML in this tutorial. Your CodePen starter already contains the full page structure and all the text. Part A is a guided tour so you understand what you'll be styling in Parts B–F. Spend a few minutes hereβ€”it makes everything after it easier.

Open the HTML panel in your CodePen and find each of these:

  • <header> β€” the page title and description. You can leave this alone for now.
  • <main class="container"> β€” the box that wraps the sidebar and the content. This is the Flexbox parent you'll style in Part B.
  • <nav class="sidebar"> β€” five links that are already pointing at #section-1 through #section-5.
  • <div class="content"> β€” the box that holds the five <section> blocks.
  • Five <section> elements, each with a unique id (id="section-1" … id="section-5"), an <h2>, paragraphs, and an empty <div class="deco" id="deco-1"> you'll fill in Part E.
  • A <footer> placed outside (after) the <main> element.
⚠️ Do not rename anything. Every CSS hint in this tutorial targets these exact names: .container, .sidebar, .content, .deco, #section-1…#section-5, and #deco-1…#deco-5. If you rename a class or id, the hints stop working and your layout breaks. You only ever add to this codeβ€”you never rename it.
πŸ“ Why is the footer outside <main>? The <main> element represents the dominant content of the pageβ€”here, the two-column sidebar + content layout. The footer is supplementary information, so it sits outside that layout. Keeping it outside <main> also means it won't accidentally become a flex item when you style .container in Part B.
πŸ“ Now open the CSS panel. It already has a base reset (the * { box-sizing } rule and the body rule)β€”leave that alone. Below it you'll see comment markers: /* Part B */, /* Part C */, and so on. Write each step's CSS under its matching comment. The CSS panel is the only thing you edit in Parts B–F.

βœ… Checkpoint A β€” can you find these in the starter?

  • The <main class="container"> that wraps the sidebar and content
  • How many <section> elements there are, and what their ids are
  • An empty <div class="deco"> β€” what is its id?
  • Whether the <footer> is inside or outside <main>
  • In the CSS panel, the /* Part B */ comment where your first code goes

πŸ€” 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) Size the two columns

You want the sidebar to stay a fixed 300px and never get squished, and the content to take all the leftover space. That's just three lines of Flexbox:

.sidebar {
  width: 300px;
  flex-shrink: 0;
}

.content {
  flex: 1;
}

In plain English:

  • width: 300px; β€” the sidebar is 300px wide (a property you already know).
  • flex-shrink: 0; β€” never let it get squished below 300px.
  • flex: 1; on the content β€” take whatever space is left over.

That's the whole layout. Add a little styling to the sidebar so you can see itβ€”reveal the hints if you want specifics.

B3) Going deeper (optional): what flex: 1 really means

You don't need this to finish the projectβ€”your layout already works. Expand it only if you're curious why those lines do what they do.

βœ… 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):

In your own words, what does flex: 1 do? And why does the sidebar need flex-shrink: 0?

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

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) See how the anchor links work

Your starter already wires the navigation for youβ€”you don't build it. In the HTML panel, find one matching pair:

  1. A link in .sidebar with an href like href="#section-1"
  2. The <section> with the matching id="section-1"
  3. Now click that nav link in the previewβ€”does the page jump to that 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. This is exactly why Part A warned you not to rename the section idsβ€”renaming them would break this navigation.

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")
  • Click Fork in CodePen when you are done so the Pen is copied into your CodePen account
  • Test that your CodePen link opens correctly in a new browser tab
  • Confirm your reflections are pasted at the bottom of your HTML
Final reflection step: Click the button above, go to the bottom of the HTML panel in CodePen, paste the copied comment after your code, then submit your CodePen link to Canvas.

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.

CodePen Save + Submit Checklist
  1. Make sure you are signed into CodePen.
  2. Use the starter template or work in the embedded Pen below.
  3. When you are finished, click Fork in CodePen so the Pen is copied into your account.
  4. Before submitting, copy your reflections and paste them as an HTML comment at the bottom of the HTML panel.
  5. Submit your finished CodePen link to Canvas.
Use Starter Template on CodePen