CSCI 4513 - Advanced Web Programming
Week 9, Lecture 17
"Skíðblaðnir could expand to carry all the gods or fold to fit in Freyr's pocket, just as responsive sites adapt from mobile to desktop while maintaining all capabilities."
Among the legendary treasures created by the sons of Ivaldi was Skíðblaðnir, a magnificent ship crafted for the god Freyr. This vessel was large enough to carry all the Aesir gods with their weapons, yet when not needed, it could fold itself small enough to fit in Freyr's pocket. The transformation was seamless—nothing was lost in the folding, and nothing was compromised in the expansion.
/* Skíðblaðnir folded (mobile) */
.container {
width: 100%;
flex-direction: column;
}
/* Skíðblaðnir expanded (desktop) */
@media (min-width: 768px) {
.container {
max-width: 1200px;
flex-direction: row;
}
}
Reflection: Skíðblaðnir maintained all capabilities whether folded or expanded. What functionality do websites often sacrifice on mobile that shouldn't be?
Two reasons:
Accessibility isn't a one-time lesson—it's a continuous commitment to inclusive design.
Creating websites that respond to changes in browser size to work on any device
📱
Mobile
320px - 500px
💻
Tablet
500px - 1000px
🖥️
Desktop
1000px+
📅 2007: First iPhone released
📊 Today: Mobile traffic exceeds desktop
✅ Requirement: Sites must work on all screen sizes
Reality Check: Your simple HTML-only recipe project probably worked fine on phones, but complex layouts require responsive techniques
320px
Smallest phones in common use
If it works at 320px, it works on any small device
???
Ultra-wide monitors exist!
Solution: Set max-width and center content
Mind-blowing fact: Plain HTML with no CSS is completely responsive!
Most elements are responsive until you change that with CSS
Approach: Start with natural responsiveness and maintain it as you add styles
Essential for every project:
<meta name="viewport" content="width=device-width, initial-scale=1">
What it does:
Good news: Emmet includes this automatically! (! + Enter)
.container {
width: 600px;
}
Can never shrink below 600px!
.container {
max-width: 600px;
}
Won't exceed 600px but will shrink!
Rule: Use max-width instead of width for containers
.box {
height: 300px;
}
Content overflow on small screens!
.box {
min-height: 300px;
}
Grows if content needs space!
Even better: Avoid height altogether! Use padding and margin to control spacing
✅ Small elements: 32px icon doesn't need to shrink
✅ Sidebars: A 250px sidebar might need to stay 250px
✅ Rule of thumb: Smaller widths = more acceptable to fix
Consider your options: Think about whether each element truly needs a fixed size
These were designed for responsive layouts!
/* Responsive with flex-wrap */
.container {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.item {
flex: 1 1 300px; /* Grow, shrink, basis */
}
/* Responsive with grid auto-fill */
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 20px;
}
Problem: Shrinking width without adjusting height = distorted images!
img {
width: 200px;
height: 400px;
}
img {
max-width: 100%;
height: auto;
}
For background images (not <img> tags)
.hero {
background-image: url('hero.jpg');
background-size: cover; /* Fill container */
background-position: center; /* Keep centered */
height: 400px;
}
/* Other options */
background-size: contain; /* Fit inside, might not fill */
background-size: 100% 100%; /* Stretch (usually bad) */
cover: Fills entire container, may crop edges
contain: Entire image visible, may have empty space
For <img> tags (works like background-size)
img {
width: 300px;
height: 200px;
object-fit: cover; /* Fill dimensions, maintain aspect */
object-position: center; /* Center the image */
}
/* Other object-fit values */
object-fit: fill; /* Default - stretches */
object-fit: contain; /* Fit inside, letterbox */
object-fit: cover; /* Fill, crop if needed */
object-fit: none; /* Use original size */
object-fit: scale-down; /* Smaller of none or contain */
Serve different images for different screen sizes
<picture>
<source media="(min-width: 1200px)" srcset="large.jpg">
<source media="(min-width: 768px)" srcset="medium.jpg">
<img src="small.jpg" alt="Description">
</picture>
Why? Send smaller files to mobile devices, cropped versions for better composition, or high-res images for retina displays
Let the browser choose the best image
<img
src="small.jpg"
srcset="small.jpg 500w,
medium.jpg 1000w,
large.jpg 2000w"
sizes="(max-width: 600px) 500px,
(max-width: 1200px) 1000px,
2000px"
alt="Responsive image"
>
Browser: "I'm 800px wide, screen is 2x density, I'll grab medium.jpg"
body {
margin: 24px;
}
@media (max-width: 600px) {
body {
margin: 8px;
}
}
How it works:
/* Max-width: applies UP TO this size */
@media (max-width: 768px) {
/* Mobile styles */
}
/* Min-width: applies FROM this size and up */
@media (min-width: 768px) {
/* Desktop styles */
}
/* Combining conditions */
@media (min-width: 600px) and (max-width: 1200px) {
/* Tablet styles */
}
/* Multiple queries */
.nav {
display: flex;
}
@media (max-width: 768px) {
.nav {
flex-direction: column;
}
}
@media (max-width: 600px) {
/* Applies when
screen is
600px or less */
}
Think: "up to this size"
@media (min-width: 600px) {
/* Applies when
screen is
600px or more */
}
Think: "from this size up"
📱 Mobile: 320px - 500px
📲 Large Mobile / Small Tablet: 500px - 768px
💻 Tablet: 768px - 1024px
🖥️ Desktop: 1024px - 1200px
🖥️ Large Desktop: 1200px+
Important: These are guidelines, not rules! Choose breakpoints based on YOUR design, not arbitrary device sizes
Best Practice: Use as few breakpoints as possible
✅ Simple layouts: One breakpoint around 600px
✅ Complex layouts: Maybe 2-3 breakpoints
❌ Avoid: Breakpoints for every device size
Why? Rely on natural flexibility of flexbox/grid first, then add media queries only where needed
/* Base styles for mobile */
.container {
width: 100%;
padding: 10px;
}
.sidebar {
display: none; /* Hidden on mobile */
}
/* Progressive enhancement for larger screens */
@media (min-width: 768px) {
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.sidebar {
display: block; /* Show on desktop */
}
}
Strategy: Start with mobile, enhance for desktop with min-width queries
/* Navigation: column on mobile, row on desktop */
.nav {
display: flex;
flex-direction: column;
gap: 10px;
}
@media (min-width: 768px) {
.nav {
flex-direction: row;
gap: 30px;
}
}
/* Grid: 1 column mobile, 2 tablet, 3 desktop */
.grid {
display: grid;
grid-template-columns: 1fr;
gap: 20px;
}
@media (min-width: 600px) {
.grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
.grid { grid-template-columns: repeat(3, 1fr); }
}
Important! Browser zoom affects effective resolution
🔍 Zoom in: 1000px window acts like smaller screen
🔍 Zoom out: Useful for testing large screens
⚠️ Watch out: Forgetting you're zoomed causes confusion!
DevTools tip: Use responsive design mode to test different sizes
Media queries aren't just for screen sizes!
/* Screen styles (default) */
@media screen {
.nav { display: flex; }
}
/* Print styles */
@media print {
/* Hide non-essential elements */
.nav,
.sidebar,
button {
display: none;
}
/* Optimize for print */
body {
color: black;
background: white;
}
a::after {
content: " (" attr(href) ")"; /* Show URLs */
}
}
Style based on container size, not viewport size
.card-container {
container-type: inline-size;
container-name: card;
}
.card h2 {
font-size: 1.2em;
}
/* When container is 400px+, not viewport! */
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 1fr 2fr;
}
.card h2 {
font-size: 2em;
}
}
Use case: Reusable components that adapt to their container, not the whole page
Based on viewport/device
Good for:
Based on container size
Good for:
✅ Include viewport meta tag
✅ Use max-width instead of width
✅ Avoid fixed heights
✅ Make images responsive (max-width: 100%, height: auto)
✅ Use flexbox and grid with flexible properties
✅ Add media queries only where needed
✅ Test on actual devices or DevTools
✅ Support 320px minimum width
Goal: Create a responsive portfolio homepage
Requirements:
1. Setup:
2. Gather Assets:
3. Build:
📖 MDN - Using the viewport meta tag
📖 MDN - Responsive Images
📖 CSS Tricks - Responsive Images Syntax
📖 MDN - Using media queries
🔗 Read about background-size, background-position, object-fit
❓ What is responsive design and why is it important?
❓ What does natural responsiveness mean?
❓ Why should you avoid fixed width and height?
❓ What's the difference between object-fit and background-size?
❓ How do you define a media query for mobile layouts?
❓ What's the difference between max-width and min-width?
❓ When would you use a <picture> element vs srcset?
✅ Responsive design makes sites work on any screen size
✅ Natural responsiveness: HTML is responsive by default
✅ Avoid fixed sizes: Use max-width and min-height
✅ Responsive images: max-width: 100%, height: auto
✅ Media queries: Conditional styles based on screen size
✅ Mobile-first: Start small, enhance for larger screens
⚛️ What is React and why use it?
🛠️ Setting up your development environment
📦 Creating your first React app
🧩 Understanding components
See you next week!
Spring Break is coming up!