Advanced Responsive Design: Container Queries & Modern Layout Techniques
Learning Objectives: By the end of this lesson, you will be able to:
- Use container queries to create responsive, modular components
- Apply modern CSS layout features (Flexbox, Grid, subgrid) for advanced layouts
- Combine container queries with Grid and Flexbox for robust, scalable designs
1. Welcome and Introduction (5 minutes)
Icebreaker Activity
“What is the most challenging layout you’ve tried to build? How did you approach it?”
Lesson Overview
- Duration: 90 minutes
- Prerequisites: Basic HTML & CSS, familiarity with Flexbox and Grid
- Materials Needed: Code editor, modern browser (Chrome, Firefox, or Safari), sample project files
2. Learning Objectives and Session Outline (5 minutes)
What We’ll Cover Today:
- Container queries – what they are and why they matter
- Modern layout techniques: Flexbox, Grid, and subgrid
- Combining container queries with modern layouts
- Hands-on practice and exercises
- Common pitfalls and how to avoid them
Success Criteria:
By the end of this session, you should be able to build a layout where components adapt to their container size, not just the viewport, using container queries and modern CSS layout features.
3. Foundation Knowledge (15-20 minutes)
Core Concepts
Container Queries
Container queries allow elements to adapt their styles based on the size of their parent container, not just the viewport. This is a major step forward for modular, reusable components.
Real-World Analogy: Think of a chameleon that changes color based on the branch it sits on, not the weather. Similarly, a card component can change its appearance based on the space available in its parent, regardless of the overall screen size.
Why This Matters:
- Enables true component reusability
- Reduces reliance on global media queries
- Makes components more predictable in different layouts
Modern Layout Techniques
- Flexbox: Best for arranging items in a row or column (one-dimensional layouts).
- CSS Grid: Ideal for two-dimensional layouts, like dashboards or complex page structures.
- Subgrid: Lets nested grids inherit grid definitions from their parent, making deeply nested layouts more consistent.
Why Use These?
- Build layouts that are both flexible and maintainable
- Reduce CSS complexity
- Make responsive design easier and more robust
Key Terminology
- Container Query: A CSS feature that applies styles based on a container’s size
- container-type: CSS property that enables container queries on an element (e.g.,
container-type: inline-size;) - @container: CSS at-rule for writing container query conditions
- Subgrid: A CSS Grid feature allowing child grids to use the parent’s grid tracks
4. Detailed Explanation and Examples (25-30 minutes)
Understanding Container Queries & Modern Layouts
Traditionally, responsive design relied on media queries, which only respond to the viewport size. This is limiting for components that need to adapt based on their parent’s size. Container queries solve this by letting you write styles that respond to the container’s dimensions.
Practical Applications
- Cards that look good in both sidebars and main content
- Widgets that adapt to dashboard panels
- Reusable UI components for design systems
Common Misconceptions
- Misconception: Container queries replace media queries entirely. Reality: They complement each other. Use container queries for component-level responsiveness and media queries for global layout changes.
- Misconception: You can use container queries anywhere by default.
Reality: You must set
container-typeon the parent element to enable them.
5. Live Coding Demonstration (20-25 minutes)
Example 1: Basic Implementation
<style>
.page-layout {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 2rem;
padding: 2rem;
}
.sidebar {
background: #ececec;
padding: 1rem;
}
.main-content {
container-type: inline-size;
background: #f9f9f9;
padding: 1rem;
}
.card-list {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.card {
container-type: inline-size;
width: 100%;
max-width: 300px;
padding: 1rem;
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
transition: background 0.3s;
}
@container (min-width: 250px) {
.card {
font-size: 1.2em;
background: #e0f7fa;
}
}
@container (min-width: 400px) {
.card {
font-size: 1.5em;
background: #b2ebf2;
}
}
</style>
<div class="page-layout">
<aside class="sidebar">Sidebar content</aside>
<main class="main-content">
<div class="card-list">
<div class="card">Card 1 adapts to its container!</div>
<div class="card">Card 2 adapts to its container!</div>
</div>
</main>
</div>
Explanation:
.page-layoutuses Grid for the overall page structure..main-contentenables container queries withcontainer-type: inline-size..card-listuses Flexbox to arrange cards in a row..cardenables container queries for each card.@containerrules change card styles based on their container’s width.
Example 2: Practical Application
<style>
.card.special {
transition: all 0.3s;
}
@container (min-width: 400px) {
.card.special {
display: flex;
align-items: center;
gap: 1rem;
}
.card.special img {
display: block;
width: 80px;
height: 80px;
border-radius: 50%;
}
}
</style>
<div class="card-list">
<div class="card special">
<img src="https://placekitten.com/80/80" alt="Kitten" style="display:none;">
<span>Special card with image at wide container!</span>
</div>
</div>
<script>
// Show image only when container is wide enough
const specialCard = document.querySelector('.card.special');
const img = specialCard.querySelector('img');
const resizeObserver = new ResizeObserver(entries => {
for (let entry of entries) {
if (entry.contentRect.width >= 400) {
img.style.display = 'block';
} else {
img.style.display = 'none';
}
}
});
resizeObserver.observe(specialCard);
</script>
Key Points:
- Demonstrates how a card can reveal extra content (an image) when its container is wide enough
- Uses both CSS and JavaScript for dynamic behavior
- Shows how container queries enable more interactive, adaptive components
Example 3: Advanced Technique (Subgrid)
<style>
.grid-parent {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 1rem;
}
.grid-child {
display: grid;
grid-template-columns: subgrid;
grid-column: 1 / -1;
gap: 0.5rem;
}
</style>
<div class="grid-parent">
<div>Sidebar</div>
<div>Main Content</div>
<div class="grid-child">
<div>Nested 1</div>
<div>Nested 2</div>
</div>
</div>
Explanation:
.grid-parentdefines the main grid.grid-childusessubgridto inherit columns from the parent- Useful for deeply nested, consistent layouts
Debugging Demonstration
Show common errors and how to fix them:
/* Common mistake: forgetting container-type */
.main-content {
/* missing container-type: inline-size; */
}
/* Corrected version */
.main-content {
container-type: inline-size;
}
6. Hands-On Practice (30-40 minutes)
Exercise 1: Basic Practice (10 minutes)
Objective: Build a sidebar/main layout with responsive cards using container queries.
Instructions:
- Create a layout with a sidebar and main content using CSS Grid.
- In the main content, add a row of cards using Flexbox.
- Use container queries so each card changes style (font size, background) based on its container width.
- Experiment by resizing the main content area to see the cards adapt.
Starter Code:
<div class="page-layout">
<aside class="sidebar">Sidebar</aside>
<main class="main-content">
<div class="card-list">
<div class="card">Card 1</div>
<div class="card">Card 2</div>
</div>
</main>
</div>
Solution:
.page-layout {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 2rem;
}
.main-content {
container-type: inline-size;
}
.card-list {
display: flex;
gap: 1rem;
}
.card {
container-type: inline-size;
max-width: 300px;
background: #fff;
transition: background 0.3s;
}
@container (min-width: 250px) {
.card {
background: #e0f7fa;
}
}
@container (min-width: 400px) {
.card {
background: #b2ebf2;
}
}
Exercise 2: Intermediate Challenge (15 minutes)
Objective: Make a card display extra content when its container is wide enough.
Requirements:
- Add an image to one card
- Use container queries to show the image only at
min-width: 400px - The card should remain visually balanced at all sizes
Hints:
- Use
display: nonefor the image by default - Use
@containerto setdisplay: blockat the right width
Exercise 3: Creative Application (15 minutes)
Objective: Build a dashboard widget that adapts to its container using subgrid and container queries.
Challenge:
- Create a parent grid with two columns
- Add a nested grid (using subgrid) for a widget
- Use container queries to change the widget’s style based on its container
Extension Ideas:
- Add more widgets with different breakpoints
- Combine with media queries for even more control
7. Common Pitfalls and Troubleshooting (10 minutes)
Frequent Mistakes
- Problem: Container queries not working
Cause: Missing
container-typeon the parent Solution: Always setcontainer-type: inline-size;orcontainer-type: size;on the container - Problem: Styles not updating as expected Cause: Overlapping media and container queries, or specificity issues Solution: Check selector specificity and query order
Debugging Tips
- Use browser DevTools to inspect container sizes and applied styles
- Test components in different parent containers
- Use feature queries (
@supports) to provide fallbacks for older browsers
8. Best Practices and Professional Tips (5 minutes)
Industry Standards
- Use container queries for reusable, modular components
- Combine Grid and Flexbox for robust layouts
- Use subgrid for consistent nested layouts
- Keep CSS organized and use comments for clarity
Next Steps in Your Learning Journey
- Explore advanced CSS features (e.g.,
:has(), custom properties) - Build a component library using container queries
- Read the MDN Container Queries Guide
9. Summary and Review (5 minutes)
Key Takeaways
- Container queries enable component-level responsiveness
- Modern layout techniques (Grid, Flexbox, subgrid) make complex layouts easier
- Combining these tools leads to scalable, maintainable designs
Quick Review Questions
- What is the main difference between media queries and container queries?
- How do you enable container queries on an element?
- When would you use subgrid in a layout?
For Instructors
Teaching Tips
- Encourage students to experiment with resizing containers, not just the viewport
- Highlight the difference between media and container queries with live demos
- Use real-world layout challenges as discussion points
Assessment Ideas
- Quiz: Identify when to use container vs. media queries
- Project: Build a responsive card component that adapts to its container
- Peer review: Share and critique each other’s layouts
Adaptation Notes
- For beginners: Focus on Flexbox and basic container queries
- For advanced: Dive into subgrid and complex breakpoints
- Online: Use live coding tools and screen sharing
- In-person: Walk around and help debug student code