INF-250: Web Design and Development — Presentations & Responsive Design
Announcements
Assignment #3 due this Sunday.
What Is Responsive Design?
Responsive design means building a website so that it looks and works well on any screen size — from a small phone to a large desktop monitor.
When the web was invented, almost everyone used a desktop computer. Pages were built with fixed widths (like width: 960px) because that is what most monitors showed. Then smartphones arrived — and suddenly, those same pages had to fit on a screen that was only 320 to 375 pixels wide.
Responsive design solves this problem through three core ideas:
- Fluid layouts — using percentages or flexible units (
%,fr,em,rem) instead of fixed pixel widths. - Flexible images and media — making images scale down rather than overflow their container.
- Media queries — CSS rules that only apply at certain screen widths, so you can change the layout entirely depending on the device.
Today we will focus on media queries, which are the most direct tool for adapting a layout to different screen sizes.
Problems Without Responsive Design
Example of a non-responsive website
What actually goes wrong when a site is not responsive? Let's look at the most common problems.
Horizontal scrolling
If your layout is designed for a 1200px screen and a visitor opens it on a phone, the page is still 1200px wide — it just doesn't fit. The browser adds a horizontal scrollbar and users have to scroll left and right to read content. This is one of the worst user experiences on the web.
Text becomes unreadable
Without responsive design, the browser shrinks everything down to fit the page on screen. A heading that was 48px on desktop might become a few millimeters tall on a phone. Users either squint at tiny text or pinch-to-zoom — both are frustrating.
Buttons and links become impossible to tap
Touch targets need to be large enough to tap accurately with a finger. Apple's Human Interface Guidelines recommend at least 44×44 pixels. A navigation link that works fine with a mouse click can be nearly impossible to tap on a small screen if it hasn't been designed for touch.
Layouts break or overlap
A multi-column layout that looks great on a widescreen will squeeze columns down to unusably narrow widths on a phone. Images can overflow their containers, text can stack on top of other elements, and sidebars can become wider than the content they sit next to.
Search engines penalize non-responsive sites
Google uses mobile-first indexing, meaning it primarily evaluates the mobile version of a site when deciding how to rank it. A site that is not mobile-friendly will rank lower in search results — even for desktop users.
The Viewport Meta Tag
Before media queries can work correctly, you need one line of HTML in your <head>:
<meta name="viewport" content="width=device-width, initial-scale=1.0">Without this tag, mobile browsers will render the page at a fake desktop width (usually 980px) and then scale it down to fit — which makes your responsive CSS rules useless. The viewport meta tag tells the browser:
width=device-width— set the viewport width to the actual screen widthinitial-scale=1.0— do not zoom in or out by default
Most modern HTML boilerplates include this already. If you created your file from a template in VS Code, it is probably already there. If you are ever confused about why your media queries seem to not be working on a real device, this tag is the first thing to check.
Media Queries
A media query is a block of CSS that only applies when a certain condition is met. The most common condition is screen width.
@media (condition) {
/* CSS rules that only apply when the condition is true */
} Think of it like an if statement in JavaScript — the CSS inside only runs when the condition is true.
Here is a real example:
/* These styles apply to ALL screen sizes */
body {
font-size: 16px;
background-color: white;
}
/* These styles ONLY apply when the screen is 600px wide or narrower */
@media (max-width: 600px) {
body {
font-size: 14px;
background-color: lightyellow;
}
} The styles outside the media query apply at all screen sizes. The styles inside the @media block apply only when the screen is 600px wide or narrower — which covers most phones.
max-width vs min-width
These are the two most common conditions you will use in media queries:
/* max-width: applies styles when screen is NARROWER than the value */
@media (max-width: 768px) {
/* phone / small tablet styles */
}
/* min-width: applies styles when screen is WIDER than the value */
@media (min-width: 768px) {
/* tablet / desktop styles */
}max-width— "apply these styles when the screen is this wide or narrower" — used in desktop-first workflows to progressively adapt down to smaller screens.min-width— "apply these styles when the screen is this wide or wider" — used in mobile-first workflows to progressively enhance up to larger screens.
Common Breakpoints
A breakpoint is a screen width at which your layout changes. There are no official breakpoints — they should match the content of your site. That said, these values are widely used as starting points:
/* Small phones */
@media (max-width: 480px) { }
/* Phones and large phones */
@media (max-width: 600px) { }
/* Tablets */
@media (max-width: 768px) { }
/* Small laptops */
@media (max-width: 1024px) { }
/* Desktops */
@media (max-width: 1200px) { } You do not need to use all of these. Most sites only need two or three breakpoints. Start with one (usually around 768px for the phone/tablet divide) and only add more if the layout breaks at a specific width.
Mobile-First vs Desktop-First
There are two common ways to organize responsive CSS:
Desktop-first (using max-width)
You write styles for the desktop layout first, then use max-width media queries to adjust for smaller screens.
/* Desktop styles come first */
.container {
display: flex;
flex-direction: row;
}
/* Then we "scale down" for smaller screens */
@media (max-width: 768px) {
.container {
flex-direction: column;
}
}Mobile-first (using min-width)
You write styles for the smallest screen first, then use min-width media queries to enhance the layout for larger screens.
/* Mobile styles come first — no media query needed */
.container {
display: flex;
flex-direction: column; /* stacked vertically on small screens */
gap: 1rem;
}
/* Then we "upgrade" the layout for larger screens */
@media (min-width: 768px) {
.container {
flex-direction: row; /* side by side on tablets and up */
}
}Mobile-first is generally the recommended approach. It forces you to decide what is most important on the smallest screen, and it tends to produce leaner CSS. It also aligns with how browsers load and render pages on low-powered mobile devices.
That said, if you are starting from an existing desktop layout, adapting it desktop-first is perfectly practical.
Practical Examples
Responsive navigation
One of the most common things you will adapt is a navigation bar. On desktop, links sit side by side. On mobile, they stack vertically.
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Projects</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>/* Full navigation on desktop */
nav ul {
display: flex;
gap: 1.5rem;
list-style: none;
padding: 0;
}
/* Stack the nav links vertically on small screens */
@media (max-width: 600px) {
nav ul {
flex-direction: column;
gap: 0.5rem;
}
}Scaling font sizes
Large headings that look good on a wide screen can feel overwhelming on a small phone. Scale them down at smaller breakpoints.
<h1>Welcome to My Site</h1>
<p>Resize the window to see the heading scale down on smaller screens.</p>h1 {
font-size: 3rem; /* large on desktop */
}
p {
font-size: 1rem;
}
@media (max-width: 600px) {
h1 {
font-size: 1.75rem; /* smaller on phones */
}
}Hiding elements on small screens
Sometimes the right answer is to hide a secondary piece of content entirely rather than trying to squeeze it in.
<div class="layout">
<aside class="sidebar">
<h3>Sidebar</h3>
<p>Secondary content that is not critical on mobile.</p>
</aside>
<main>
<h2>Main Content</h2>
<p>This is the primary content of the page.</p>
</main>
</div>.layout {
display: flex;
gap: 1rem;
}
/* This sidebar is visible by default */
.sidebar {
width: 250px;
flex-shrink: 0;
}
/* Hide it entirely on small screens */
@media (max-width: 600px) {
.sidebar {
display: none;
}
}Responsive card layout
Flexbox's flex-wrap lets cards automatically reflow into fewer columns as the screen narrows — no breakpoints needed for most cases. The flex: 1 1 250px shorthand means each card can grow and shrink but will never start smaller than 250px, so the browser figures out how many fit per row on its own.
<div class="card-grid">
<div class="card">Card 1</div>
<div class="card">Card 2</div>
<div class="card">Card 3</div>
<div class="card">Card 4</div>
<div class="card">Card 5</div>
<div class="card">Card 6</div>
</div>/* Cards sit side by side and wrap to the next line when there's no room */
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.card {
flex: 1 1 250px; /* grow, shrink, and use 250px as the base width */
}
/* Force a single column on small phones */
@media (max-width: 480px) {
.card {
flex: 1 1 100%;
}
}flex shorthand takes three values: flex-grow, flex-shrink, and flex-basis. Flex-basis sets the starting size of an item before any growing or shrinking happens — think of it as the item's "ideal" width. In
flex: 1 1 250px, the 250px is the flex-basis: each card starts at 250px, then the browser fits as many as it can across the row. When there is not enough room for another 250px card, it wraps to the next line. This means on a wide screen you get three or four cards per row, on a tablet maybe two, and on a phone one — all without a single media query.