Responsive Design Challenge - Conference Site
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
Unzip and then open both files in your code editor
Open the HTML file in your browser
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:
Did you define the properties in :root?
Are you using the exact same variable name (including the -- prefix)?
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:
Did you add container-type: inline-size to .conference-grid?
Is your @container rule outside of any other selector?
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:
Did you use all three values in clamp(min, preferred, max)?
Is your middle value using a relative unit like vw or %?
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:
Did you include spaces around the operator? calc(100% - 2rem) not calc(100%-2rem)
Are you mixing compatible units?
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:
Did you save the CSS file?
Did you hard refresh the browser? (Ctrl+Shift+R or Cmd+Shift+R)
Are you editing the right file?
Is your HTML linked to the correct CSS file?
Fix:
Save the file (Ctrl+S / Cmd+S)
Hard refresh (Ctrl+Shift+R / Cmd+Shift+R)
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:
Custom Properties create a single source of truth for design values
clamp() enables fluid, self-scaling values without media queries
calc() lets you mix units and create dynamic calculations
Container Queries respond to component size, not viewport size
Progressive Enhancement ensures your site works everywhere
Modern CSS can create responsive designs with less code than old methods
Locked Message
