top of page
logo-2-color_2x.png

Responsive Design Challenge - Conference Site

Points: 

5

Due By:

February 6, 2026 at 5:45:00 AM

Table of Contents





Learning Objectives

By completing this exercise, you will:

  • Apply fluid typography using clamp()

  • Implement CSS custom properties for maintainable design

  • Use calc() for dynamic spacing and sizing

  • Create responsive layouts with container queries

  • Practice progressive enhancement with @supports

  • Build a real-world responsive component from scratch





📋 Overview

You've been provided with a conference website that has the HTML structure complete, but the CSS is missing key responsive features. Your goal is to make this site work beautifully across all screen sizes using modern CSS techniques.


Important: This is a preview of techniques you'll master later. Don't worry if some concepts feel new—the goal is to experience how these tools work together!





🚀 Getting Started


Files Provided

  • conference-site.html - Complete HTML structure (no changes needed!)

  • conference-site.css - Partial CSS with strategic gaps for you to fill





Setup

  1. Unzip and then open both files in your code editor

  2. Open the HTML file in your browser

  3. Resize your browser window to see how the site responds (or doesn't yet!)



📝 Exercise Tasks


Task 1: Set Up CSS Custom Properties (Design Tokens)

Location: :root selector at the top of the CSS file

Your Mission: Define reusable design variables that can be used throughout the stylesheet.


What to Add:

css

:root {
    /* Colors */
    --color-primary: #2c3e50;
    --color-accent: #3498db;
    --color-background: #f4f4f4;
    
    /* Spacing - fluid values */
    --spacing-base: clamp(0.5rem, 2vw, 2rem);
    
    /* Typography - fluid values */
    --font-base: clamp(16px, 1vw + 1rem, 22px);
}


🤔 Guiding Questions (Use these if you get stuck):

  • What does clamp() do? (Hint: minimum, preferred, maximum)

  • Why would we want spacing to be fluid instead of fixed?

  • What's the difference between using 16px vs 1rem?



✅ Success Check: Open your browser's DevTools and look at the :root element. You should see your custom properties listed.






Task 2: Apply Custom Properties to Body Styles

Location: body selector


Your Mission: Uncomment the CSS properties and make sure they use your custom properties.


Current Code:

css

body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, ...;
    line-height: 1.6;
    /* background-color: var(--color-background); */
    /* color: var(--color-primary); */
    /* font-size: var(--font-base); */
}

What to Do: Simply uncomment the three lines (remove the /* */)



🤔 Guiding Questions:

  • What happens to the text size when you resize the browser?

  • Can you see the background color change?

  • What would happen if you changed --color-primary in :root?


✅ Success Check: The page should have a light gray background and dark text that scales smoothly as you resize.





Task 3: Add Dynamic Width to Page Wrapper

Location: .page-wrapper selector


Your Mission: Use calc() to create padding that prevents content from touching the edges on small screens.


What to Add:

css

.page-wrapper {
    width: calc(100% - 2rem);
    max-width: 1200px;
    margin: 0 auto;
    padding: var(--spacing-base);
}

🤔 Guiding Questions:

  • Why use calc(100% - 2rem) instead of width: 100%?

  • What does margin: 0 auto do?

  • What happens on a screen wider than 1200px?


✅ Success Check: Resize your browser. Content should never touch the edges and should center when the screen is wider than 1200px.





Task 4: Enable Container Queries for the Grid

Location: .conference-grid selector


Your Mission: Set up the conference grid to use container queries instead of media queries.


What to Add:

css

.conference-grid {
    container-type: inline-size;
    display: grid;
    gap: var(--spacing-base);
}

🤔 Guiding Questions:

  • What does container-type: inline-size tell the browser?

  • How is this different from using a media query?

  • Think: Why would container queries be useful for reusable components?


🔍 Behind the Scenes: This makes .conference-grid a "container" that its children can query. It's like the grid is saying "I'm queryable!" to its child elements.


✅ Success Check: Nothing visual changes yet—you're setting up the infrastructure for the next task!





Task 5: Create Responsive Columns with Container Query

Location: After the .conference-grid selector (new rule needed)


Your Mission: Make the grid switch from 1 column to 2 columns when the container is wide enough.


What to Add:

css

@container (min-width: 600px) {
    .conference-grid {
        grid-template-columns: 1fr 1fr;
    }
}

🤔 Guiding Questions:

  • What does 1fr 1fr mean? (Hint: fractional units!)

  • When will this rule activate?

  • Try changing 600px to 800px—what happens?


💡 Key Insight: This responds to the container's width, not the viewport width. That's the power of container queries!

✅ Success Check: Resize your browser slowly. The two conference days should stack vertically on narrow screens and sit side-by-side on wider screens.





Task 6: Uncomment Existing Styles

Location: .conference-day and .page-wrapper selectors


Your Mission: Find and uncomment the lines that use your custom properties.


Look For:

  • padding: var(--spacing-base);

  • Any other commented-out lines using var(--...)


🤔 Guiding Questions:

  • How many places use --spacing-base?

  • What happens if you change --spacing-base in :root to a larger value?

  • Can you see how custom properties make global changes easier?


✅ Success Check: Your spacing should now be fluid and consistent throughout the design.





Task 7: Add a Media Query (Progressive Enhancement)

Location: Near the bottom of the CSS file (the commented section)


Your Mission: Add a traditional media query as a fallback for very small screens.


What to Add:

css

/* Media Query as a Progressive Enhancement */
@media (max-width: 480px) {
    .session-details {
        flex-direction: column;
        gap: 0.25rem;
    }
    
    .conference-day h2 {
        font-size: 1.5rem;
    }
}

🤔 Guiding Questions:

  • How is this different from the container query you wrote earlier?

  • When would you use media queries vs. container queries?

  • What happens to the time/room details on very small screens?


💡 Key Point: Media queries and container queries can work together! Media queries are still useful for viewport-level changes.

✅ Success Check: On screens narrower than 480px, the time and room should stack vertically.





Task 8: Add Feature Detection (Advanced)

Location: Very end of CSS file


Your Mission: Use @supports to ensure graceful degradation for older browsers.


What to Add:

css

/* Feature Query for Modern Browsers */
@supports (container-type: inline-size) {
    .conference-grid {
        container-type: inline-size;
    }
}

@supports not (container-type: inline-size) {
    /* Fallback for browsers without container query support */
    @media (min-width: 600px) {
        .conference-grid {
            grid-template-columns: 1fr 1fr;
        }
    }
}

🤔 Guiding Questions:

  • What does @supports check for?

  • Why provide a fallback with @media?

  • How does this relate to "progressive enhancement"?


🔍 Real-World Context: Not all browsers support container queries yet. This ensures your site works everywhere!


✅ Success Check: Visit caniuse.com/css-container-queries to see browser support. Your code now handles both modern and older browsers!







🐛 Troubleshooting Guide


Problem: "My custom properties aren't working!"


Symptoms: Colors or spacing look wrong, or you see var(--color-primary) as literal text.


Diagnostic Questions:

  1. Did you define the properties in :root?

  2. Are you using the exact same variable name (including the -- prefix)?

  3. Did you uncomment the lines that use them?


Common Mistakes:

  • Forgetting the -- prefix: color: var(color-primary) ❌ vs. var(--color-primary) ✅

  • Typos in variable names: --color-primery vs. --color-primary

  • Defining inside wrong selector (not :root)


Fix: Check DevTools → Inspect Element → Computed styles to see what values are actually being used.



Problem: "The grid won't switch to two columns!"


Symptoms: Columns stay stacked even on wide screens.


Diagnostic Questions:

  1. Did you add container-type: inline-size to .conference-grid?

  2. Is your @container rule outside of any other selector?

  3. Did you specify grid-template-columns: 1fr 1fr inside the container query?


Common Mistakes:

css

/* WRONG - container query nested inside grid */
.conference-grid {
    container-type: inline-size;
    @container (min-width: 600px) { ... }  ❌
}

/* RIGHT - container query as separate rule */
.conference-grid {
    container-type: inline-size;
}
@container (min-width: 600px) {
    .conference-grid { ... }  ✅
}

Fix: Use DevTools to check if container-type is applied. Look in the "Elements" panel under "Styles."





Problem: "My clamp() values aren't scaling!"


Symptoms: Font sizes or spacing don't change when resizing browser.


Diagnostic Questions:

  1. Did you use all three values in clamp(min, preferred, max)?

  2. Is your middle value using a relative unit like vw or %?

  3. Are you actually using the custom property somewhere?


Common Mistakes:

css

/* Not fluid - no viewport unit */
--font-base: clamp(16px, 18px, 22px);  ❌

/* Fluid - uses viewport width */
--font-base: clamp(16px, 1vw + 1rem, 22px);  ✅

Fix: The middle value must include a relative unit to scale!





Problem: "calc() isn't calculating!"

Symptoms: Width looks wrong or CSS doesn't apply.


Diagnostic Questions:

  1. Did you include spaces around the operator? calc(100% - 2rem) not calc(100%-2rem)

  2. Are you mixing compatible units?

  3. Did you close all parentheses?


Common Mistakes:

css

/* WRONG - no spaces */
width: calc(100%-2rem);  ❌

/* RIGHT - spaces around operator */
width: calc(100% - 2rem);  ✅

Fix: Always put spaces around +, -, *, and / operators in calc()!





Problem: "I don't see any changes when I edit CSS!"

Symptoms: Saving changes doesn't update the browser.


Diagnostic Questions:

  1. Did you save the CSS file?

  2. Did you hard refresh the browser? (Ctrl+Shift+R or Cmd+Shift+R)

  3. Are you editing the right file?

  4. Is your HTML linked to the correct CSS file?


Fix:

  1. Save the file (Ctrl+S / Cmd+S)

  2. Hard refresh (Ctrl+Shift+R / Cmd+Shift+R)

  3. Check the HTML <link> tag points to your CSS file








💡 Productive Learning Prompts

These are questions to ask yourself (or your instructor) when you're stuck. They guide your thinking without giving away the answer.


When Stuck on Custom Properties:

  • "Where should CSS variables be defined if I want them available everywhere?"

  • "What's the syntax for using a variable vs. defining one?"

  • "How can I test if my variable is defined? (Hint: DevTools)"


When Stuck on Container Queries:

  • "What makes an element a 'queryable container'?"

  • "Am I querying the container's size or the viewport's size?"

  • "What selector goes inside the @container rule?"


When Stuck on Responsive Behavior:

  • "At what size should this change? How do I test that breakpoint?"

  • "Am I using the right unit? Should this be px, %, vw, fr, or rem?"

  • "What happens if I slowly resize my browser? At what point does it break?"


When Stuck on Syntax:

  • "Did I close all my brackets and parentheses?"

  • "Are there any typos in my property or variable names?"

  • "What does DevTools say about this rule? Is it crossed out?"


When Code Isn't Working:

  • "What's the smallest change I can make to test if this works?"

  • "If I comment this out, does anything change?"

  • "What does the browser think the computed value is? (Check DevTools → Computed)"






🎓 Extension Challenges (Optional)

Ready for more? Try these enhancements:



Challenge 1: Add a Dark Mode

Use custom properties to create a dark color scheme:

css

:root {
    --color-background: #f4f4f4;
    --color-primary: #2c3e50;
}

@media (prefers-color-scheme: dark) {
    :root {
        --color-background: #2c3e50;
        --color-primary: #ecf0f1;
    }
}


Challenge 2: Make Typography Even More Fluid

Add more fluid typography using clamp() for the session titles and details.




Challenge 3: Add More Breakpoints

Create a three-column layout for very wide screens (1200px+).




Challenge 4: Experiment with Container Query Units

Try using cqi (container inline size) units inside your container query.





🔗 Resources for Further Learning

  • Can I Use: caniuse.com - Check browser support for any CSS feature

  • MDN Web Docs: developer.mozilla.org - Comprehensive CSS reference

  • CSS Tricks: Great articles on Grid, Flexbox, and Container Queries

  • Your Course CodePens: Review the examples provided in the lecture materials





✅ Final Success Checklist

Before you consider this exercise complete, verify:

  •  Custom properties are defined in :root

  •  Colors and spacing use var(--...) throughout

  •  clamp() creates fluid typography that scales smoothly

  •  calc() creates dynamic spacing

  •  Container query makes grid responsive to container size

  •  Grid switches from 1 to 2 columns at the right breakpoint

  •  Media query handles very small screens (optional but recommended)

  •  @supports provides progressive enhancement

  •  Page looks good at 320px, 768px, 1024px, and 1920px widths

  •  No horizontal scrolling at any width

  •  DevTools shows no CSS errors





🎯 Key Takeaways

After completing this exercise, you should understand:

  1. Custom Properties create a single source of truth for design values

  2. clamp() enables fluid, self-scaling values without media queries

  3. calc() lets you mix units and create dynamic calculations

  4. Container Queries respond to component size, not viewport size

  5. Progressive Enhancement ensures your site works everywhere

  6. Modern CSS can create responsive designs with less code than old methods

Locked Message

bottom of page