AI Computer Institute
Expert-curated CS & AI curriculum aligned to CBSE standards. A bharath.ai initiative. About Us

CSS3 and Responsive Design: Beautiful on Every Screen

📚 Web Development Foundations⏱️ 23 min read🎓 Grade 9
✍️ AI Computer Institute Editorial Team Updated: August 2026 CBSE-aligned · Peer-reviewed · 23 min read
Content curated by subject matter experts with IIT/NIT backgrounds. All chapters are fact-checked against official CBSE/NCERT syllabi.

The Portfolio That Broke on a Phone

Suppose you build a personal portfolio page for a school science-fair website. You design it on your laptop, at a comfortable browser width of about 1366 pixels. Every heading sits where you want it, your project photos line up in neat rows, and the navigation menu spreads across the top in one tidy line. You are proud of it. Then you open the same page on your mother's phone, at a screen width of roughly 360 pixels, and it falls apart: the text is so small you have to pinch and zoom to read a single sentence, your project photo hangs off the right edge of the screen forcing a horizontal scrollbar to appear, and the navigation menu — which had five links laid out in a row — is now squeezed into an unreadable strip of overlapping text.

Nothing about your HTML changed between the laptop and the phone. What changed was the width of the space your page had to fit into — 1366 pixels shrank to 360 pixels, less than a third. Your CSS had fixed pixel widths everywhere (width: 1200px for the main container, width: 400px for each photo), and fixed sizes do not know how to shrink. This chapter is about writing CSS3 that responds to the space it is given, so the same HTML file produces a good layout whether it is opened on a 360px phone, a 768px tablet, or a 1920px desktop monitor. This is called responsive design, and it is not a separate technology from CSS — it is a disciplined way of writing ordinary CSS3 rules.

What "Responsive" Actually Means

A responsive page is one where the layout reflows to fit the available width, rather than staying a fixed size and forcing the user to scroll sideways or zoom. There are three ingredients that make this possible, and this chapter covers all three in order: (1) telling the browser to report the phone's real width instead of pretending to be a tiny desktop, (2) using sizing units that scale instead of units that stay rigid, and (3) writing rules that change the layout itself — how many columns there are, whether the menu wraps — at specific width thresholds called breakpoints. Skipping any one of the three gives you a page that looks "almost" responsive but breaks in an obvious way, which is exactly the mistake most beginners make and exactly the mistake this chapter corrects.

The Viewport: Telling the Phone Not to Lie

Here is a fact that surprises most students: by default, most mobile browsers do not report their true screen width to your CSS. A phone that is physically 360 pixels wide will tell your page it is 980 pixels wide, then shrink the whole rendered page down to fit the real screen. This was a historical trick browser makers used so that old desktop-only websites, built assuming a wide screen, would at least appear in full (tiny, but complete) rather than broken. The side effect is that your media queries — which check the reported width — never fire correctly, because the browser always reports 980px regardless of the real device.

You fix this with one line placed in the <head> of your HTML document, not in your CSS file at all:

<meta name="viewport" content="width=device-width, initial-scale=1.0">

width=device-width tells the browser: "stop pretending to be 980px wide — report your actual physical width." initial-scale=1.0 tells it to start at normal zoom, one CSS pixel equal to one device pixel, instead of already zoomed out. Without this tag, every media query and every percentage-based layout you write will behave incorrectly on real phones, even though it may look fine in a desktop browser's simulated "mobile view." This is the single most common reason a student's "responsive" CSS works in their code editor's preview but fails on an actual phone.

Units That Scale: px, %, em, and rem

A pixel (px) is an absolute unit — 20px means the same physical size no matter what else is on the page. That rigidity is exactly the problem you saw with the portfolio site. CSS3 gives you three relative units that adapt: %, em, and rem.

% is a percentage of the parent element's corresponding size. A <div> with width: 50% inside a parent that is 600px wide will render at 300px; if the parent later shrinks to 360px, the same div automatically becomes 180px, with zero extra CSS.

em is a font-size unit relative to the font-size of that element's own parent. rem ("root em") is a font-size unit relative to the font-size of the root element — the <html> tag — no matter how deeply nested the element is. This distinction trips up almost every beginner, so trace it numerically. Suppose your stylesheet sets:

html { font-size: 16px; }
.card { font-size: 1.2rem; }
.card p { font-size: 0.9em; }
.card p .note { font-size: 0.9em; }

Work it out step by step. The root font-size is 16px, so 1rem always equals 16px anywhere on the page. .card is set in rem, so its computed font-size is 16 × 1.2 = 19.2px. Now .card p is set in em, which looks at its parent — .card, whose computed size is 19.2px — so the paragraph becomes 19.2 × 0.9 = 17.28px. Finally .card p .note is also in em, and its parent is the paragraph at 17.28px, so it becomes 17.28 × 0.9 = 15.552px. Notice how each em value multiplies onto the previous computed value — this is called compounding, and three or four nested em rules can produce sizes far from what you intended. rem never compounds, because it always measures from the same fixed root, which is why most developers use rem for font-sizes and spacing throughout a page, and reserve em for sizes that should genuinely scale with their immediate local context, such as icon sizing next to text.

rem has a second, accessibility-related benefit worth knowing for CBSE-level conceptual questions: if a visually impaired user increases their browser's default font-size from 16px to, say, 20px, every rem-based measurement on your page scales up proportionally along with it, while px-based measurements stay frozen and can start to look cramped or misaligned next to the now-larger text.

The Box Model Trap: Why width:100% Overflows

Even after switching to relative units, students hit a second classic bug. Consider this CSS, using the default box-sizing behavior:

.box {
  width: 300px;
  padding: 20px;
  border: 2px solid #333;
}

You might expect this box to occupy exactly 300px on the page. It does not. By default, CSS uses box-sizing: content-box, which means the width property sets only the width of the content area — padding and border are added on top. The actual rendered width is: content (300px) + left padding (20px) + right padding (20px) + left border (2px) + right border (2px) = 300 + 40 + 4 = 344px. If that box sits inside a mobile screen that is only 360px wide and you have two such boxes side by side, or even one box plus a small margin, it overflows and forces the dreaded horizontal scrollbar — the exact symptom from the opening story.

The fix is one declaration, almost always placed once at the very top of a stylesheet so it applies everywhere:

* {
  box-sizing: border-box;
}

border-box flips the meaning of width: now the 300px includes padding and border, and the browser shrinks the visible content area to make room for them instead of adding to the total. Redo the arithmetic: total rendered width stays exactly 300px; the content area shrinks to 300 − 40 − 4 = 256px to absorb the padding and border. This single rule is why almost every modern CSS3 stylesheet, and every framework you will encounter later, starts with a universal box-sizing: border-box reset — it makes percentage and pixel widths behave the way your intuition expects.

Media Queries: CSS That Asks "How Wide Am I?"

Relative units and correct box-sizing solve scaling, but not restructuring. A photo gallery with three columns on a desktop should usually not become three impossibly narrow slivers on a phone — it should become one column, stacked. That structural change needs a rule that behaves differently depending on the available width. That rule is a media query:

@media (max-width: 599px) {
  .gallery {
    flex-direction: column;
  }
}

Read this as: "apply the CSS inside these braces only when the viewport is 599px wide or narrower." The width at which behavior changes — 599px/600px in this example — is called a breakpoint. You choose breakpoints based on your content, not any fixed device catalogue, but common ones follow the natural boundaries between phones (roughly up to 599px), tablets (600–899px), and laptops/desktops (900px and above), since most content designed to fit those bands looks reasonable across the huge variety of actual device sizes within each band.

Media queries can also use min-width to target wider screens and above, and you can combine several breakpoints to progressively change a layout:

.gallery { display: flex; flex-wrap: wrap; gap: 16px; }
.card { flex: 1 1 100%; }              /* base: 1 column */

@media (min-width: 600px) {
  .card { flex: 1 1 calc(50% - 8px); } /* 2 columns */
}

@media (min-width: 900px) {
  .card { flex: 1 1 calc(33.333% - 10.67px); } /* 3 columns */
}

The calc() values are not arbitrary — they come directly from the gap: 16px you already set. When two cards share a row, there is exactly one 16px gap between them, so each card must give up half of that gap: 16 ÷ 2 = 8px, giving 50% − 8px. When three cards share a row, there are two 16px gaps between them, totaling 32px, split three ways: 32 ÷ 3 ≈ 10.67px, giving 33.333% − 10.67px. Working out the exact subtraction like this — rather than guessing a round number — is what keeps rows from wrapping unpredictably when the gap and card widths do not divide evenly.

Mobile-First: Building Up, Not Shrinking Down

Look again at the previous code block: the base rule (no media query at all) is the single-column mobile layout, and each successive min-width query adds complexity for larger screens. This ordering is deliberate and is called mobile-first design. The alternative — writing the full desktop layout as the base rule, then using max-width queries to strip things away for smaller screens — is called desktop-first, and it tends to produce messier CSS, because you spend your media queries un-doing desktop assumptions (undoing a fixed width, undoing a horizontal flex row, hiding elements) instead of simply adding new ones. Mobile-first also matches a genuine real-world priority: the majority of first-time visits to most Indian websites now happen on a phone rather than a laptop, so designing the simplest, single-column version first, as your unconditional default, means every visitor gets a working layout even if every media query in your stylesheet somehow failed to apply — the enhancements for bigger screens layer safely on top rather than being required for basic usability.

Flexbox: Layout That Reflows Itself

The gallery examples above used display: flex, which deserves its own explanation because it does part of the responsive work automatically, without any media query at all. Setting display: flex on a container turns its direct children into flex items that can be arranged in a row (the default) or a column (flex-direction: column), and — critically for responsiveness — flex-wrap: wrap allows items to drop onto a new line once they no longer fit on the current one, instead of being squeezed or overflowing. Take a navigation bar with five links:

nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  list-style: none;
  padding: 0;
  margin: 0;
}

On a wide screen, all five links fit on one row. As the viewport narrows, once the fifth link no longer has room, it automatically drops to a second line — no @media rule required, because flex-wrap is reacting live to available space, not to a fixed breakpoint number. This is the piece that was missing from the broken portfolio site in the opening story: its navigation menu used display: inline-block without wrapping, so the links had nowhere to go but to overlap. Flexbox and media queries are complementary, not competing, tools: use flex-wrap for small, self-adjusting reflows like a nav bar or a row of tags, and use explicit media queries when the layout needs a deliberate, larger restructuring, such as swapping a sidebar-plus-content layout for a fully stacked one.

Responsive Images

An <img> tag has an intrinsic size — the pixel dimensions of the actual image file — and without any CSS, the browser renders it at exactly that size, regardless of how narrow its container is. This is why images are usually the first thing to overflow a small screen. The standard fix is:

img {
  max-width: 100%;
  height: auto;
  display: block;
}

max-width: 100% tells the browser the image may never render wider than its container, so it shrinks along with the container instead of pushing past it. height: auto is essential alongside it: it tells the browser to recalculate the height automatically so the image's original aspect ratio is preserved rather than being stretched or squashed. Trace the numbers: an image file that is 1200 × 800 pixels has an aspect ratio of 1200:800, which simplifies to 3:2. If its container shrinks to 320px wide, max-width: 100% makes the displayed width 320px, and height: auto computes the matching height as 320 × (800 ÷ 1200) = 320 × 0.667 ≈ 213px — the same 3:2 shape, just smaller. Omit height: auto and leave an explicit fixed height in the CSS, and the image would be forced into the wrong proportions as its width changes, visibly stretching or squishing.

Common Misconceptions, Corrected

Misconception: media queries detect what kind of device you are using — "if it's a phone, use layout A." Correction: a media query only ever checks the current viewport width in pixels, at that instant. It has no idea whether it is running on a phone, a tablet, or a desktop. Proof of this: open any responsive site in a desktop browser and slowly drag the browser window narrower with your mouse — the layout will restack into its "mobile" version even though you are still on a laptop, because the viewport width crossed the breakpoint. This is precisely why testing responsive CSS by resizing your desktop browser window is a completely valid and common technique — you do not need a separate physical phone to check most of your breakpoints.

Misconception: adding the viewport meta tag makes a page responsive. Correction: the viewport tag only fixes what width the browser reports to your CSS — it does not add any layout adaptation by itself. A page with the viewport tag but no media queries and no relative units will report its true 360px width accurately, and then proceed to render the exact same fixed 1200px layout anyway, overflowing just as before. The viewport tag is a necessary first step, not a complete solution — it is step one of the three-part recipe from the start of this chapter, not the whole recipe.

Worked Example: One Layout, Three Screens

Put every piece together on a single card component and trace what happens at three specific viewport widths.

* { box-sizing: border-box; }
html { font-size: 16px; }

.gallery { display: flex; flex-wrap: wrap; gap: 16px; padding: 16px; }
.card {
  flex: 1 1 100%;
  padding: 1rem;
  border: 1px solid #ccc;
}
.card img { max-width: 100%; height: auto; display: block; }
.card h3 { font-size: 1.1rem; }

@media (min-width: 600px) {
  .card { flex: 1 1 calc(50% - 8px); }
}
@media (min-width: 900px) {
  .card { flex: 1 1 calc(33.333% - 10.67px); }
}

At a viewport width of 360px (a typical phone), neither media query's condition is met, since 360 is less than both 600 and 900, so only the base rule applies: .card uses flex: 1 1 100%, meaning each card claims the full row width and the gallery stacks into a single column — exactly the safe mobile-first default. At 768px (a typical tablet), the min-width: 600px query's condition (768 ≥ 600) is now true, so it overrides the base rule: cards switch to calc(50% − 8px), producing two columns. At 1280px (a laptop), both queries are true, but since the 900px rule appears later in the stylesheet and applies to the same property, it wins by the normal CSS cascade rule of "later rule of equal specificity overrides an earlier one" — cards become calc(33.333% − 10.67px), three columns. Meanwhile, throughout all three widths, box-sizing: border-box keeps each card's declared width exact regardless of its padding, and max-width: 100%; height: auto keeps every photo inside its card correctly proportioned no matter how narrow the column becomes. This is the complete mechanism: one HTML file, zero JavaScript, three genuinely different layouts, each chosen automatically by the browser reading the same stylesheet.

How the Layout Reflows at Each Breakpoint

Same 4 cards, same HTML — layout reflows at each breakpoint MOBILE (<600px) flex: 1 1 100% TABLET (600–899px) flex: 1 1 calc(50% - 8px) DESKTOP (≥900px) flex: 1 1 calc(33.333% - 10.67px) @media (min-width:600px) @media (min-width:900px) Colours mark the same 4 cards; only their arrangement changes as viewport width crosses each breakpoint.

Summary

  • Responsive CSS needs three ingredients together: the viewport meta tag (<meta name="viewport" content="width=device-width, initial-scale=1.0">), relative sizing units, and media queries that restructure the layout at chosen breakpoints. Any one alone is not enough.
  • % scales against the parent's size; em scales against the parent's font-size and compounds through nested elements; rem always scales against the root <html> font-size and never compounds, which is why it is the safer default for most sizing.
  • Default box-sizing: content-box adds padding and border on top of a declared width; box-sizing: border-box makes the declared width the final total, which is why almost every stylesheet sets * { box-sizing: border-box; } at the top.
  • A media query such as @media (min-width: 600px) { ... } applies its rules only once the viewport reaches that width; it reacts to the current window width, never to the device's identity.
  • Mobile-first design writes the simplest single-column layout as the unconditional base rule, then uses min-width queries to add columns and complexity as the screen grows — the reverse of writing a full desktop layout and stripping it down.
  • display: flex with flex-wrap: wrap lets items reflow onto new rows automatically as space runs out, without needing a media query for every small adjustment.
  • img { max-width: 100%; height: auto; } keeps images from overflowing their container while preserving their original aspect ratio.

Practice: Test Yourself

  1. A stylesheet has html { font-size: 20px; } and .title { font-size: 1.5rem; }. Compute the rendered font-size of .title in pixels.
  2. A <div> has width: 200px; padding: 15px; border: 5px solid black; with the default box-sizing. Calculate its total rendered width. Then state what the total width becomes if box-sizing: border-box is added.
  3. A student writes CSS with correct media queries but forgets the viewport meta tag entirely. Explain, using the "reported width" idea, exactly what will go wrong on a real phone even though the CSS file itself has no errors.
  4. Write a single media query rule that changes a container's flex-direction from row to column whenever the viewport is 700px or narrower.
  5. A flex container has gap: 20px and needs to fit exactly 4 equal cards per row. Using the same reasoning as the worked 2-column and 3-column examples in this chapter, derive the correct calc() expression for each card's width.
  6. A classmate says, "I tested my site by resizing my laptop's browser window and it looked fine at every width, so I don't need to test it on an actual phone." Explain what this test does and does not prove, referring to the misconception about media queries corrected in this chapter.

Think About It

Think about this: How would you explain css3 and responsive design: beautiful on every screen to a friend who has never seen a computer? What real-world analogy would you use? Imagine you had to build a system using these concepts — what would be your first step? Try this: before moving on, write down three things you learned and one question you still have.

← Full Stack Capstone: Building a Complete Indian Weather AppJavaScript Fundamentals: Making Web Pages Interactive →

Found this useful? Share it!

📱 WhatsApp 🐦 Twitter 💼 LinkedIn