Today's X-ray
Every element you have ever written is a box. Today you get X-ray vision.
Class 10 loaded the paint — colours, fonts, one style.css dressing the whole site. But two mysteries were left standing, on purpose: why did margin: 0 auto need a width to centre that form? And what exactly were the padding and margin lines doing inside .dish? The answer to both is the CSS Box Model — the four nested layers every element is made of — plus position and display: the properties that decide where things sit and why.
Walk out of this room able to…
Every box we X-ray today already exists — the .dish cards, the header, the nav — all styled by the style.css you typed in Class 10. Today's only new tool is Chrome DevTools, and it has been sitting inside your browser all along: press F12 and it opens. Nothing to install, nothing to fetch.
Grab the Class 9 asset pack (from the Class 9 opener) for the caught-up poshtik-campus\ folder, then open Class 10, Part 5 and type its 19-line style.css into existence — twenty minutes, and it's the exact file today inspects. Every padding, border and margin value we read in DevTools today comes from those 19 lines, so don't skip the typing.
The picture that explains everything
Content, padding, border, margin — four layers, inside out.
Take any element — a heading, a paragraph, a .dish card — and the browser wraps it in the same four rectangles, every single time. Content is the text or image itself. Padding is breathing room inside the border. Border is the visible edge. Margin is the push outside — the gap to the neighbours. Learn to see these four and every layout question for the rest of your career becomes "which layer am I changing?"
This is your own card, to scale: the values in the diagram are not invented — they are the exact lines you typed into style.css in Class 10: .dish { width: 300px; padding: 12px; border: 2px solid seagreen; margin: 12px 0; }. You have been using all four layers since last class. Today you can finally name what you were doing.
Now the arithmetic that catches everyone. One press per line — watch the running total on the right.
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Box width demo</title></head><body> <article class="dish">Jonna Rotte Wrap</article> <!-- the box being measured --></body></html>/* HTML is complete & plain above. Now add a <style> — one rule per press ↓ */<style> .dish { /* exactly what you wrote in Class 10 */ width: 300px; /* content only! */ padding: 12px; /* +12 left, +12 right */ border: 2px solid seagreen; /* +2, +2 */ margin: 12px 0; /* outside — not part of the box's own width */ background-color: mintcream;} </style>/* true on-screen width: *//* 300 + 12 + 12 + 2 + 2 = 328px — not 300 */Plain box on screen — no width, padding, or border yet. (the HTML above is complete & unstyled)
300px — the content rectangle. what width: sets
+ 24px — padding, both sides. running total: 324
+ 4px — border, both sides. running total: 328
margin: excluded — it positions the box; it is not part of it.
TRUE WIDTH = 328px. The width property lied to you — politely.
Now watch the four layers arrive one at a time. The right side starts as a bare box — just text, no padding, no border, no margin. Press once per rule and each box-model layer lands on the live box: first the content padding pushes the text off the edges, then the seagreen border draws itself, then the margin pushes the whole box inward. Plain HTML first — then CSS, in sync, never all at once.
/* the <article class="dish"> box is already on screen (bare) */.dish { width: 220px; background: mintcream; }.dish { padding: 14px; } /* content layer gets breathing room */.dish { border: 3px solid seagreen; } /* border layer */.dish { margin: 18px; } /* margin layer — outside the box */Before any press: a bare box, text touching every edge. Each press adds exactly one layer — you can press Back to peel them off again.
Two .dish cards each carry margin: 12px 0 — so the gap between two stacked cards should be 12 + 12 = 24px, right? Measure it in DevTools: it's 12px. Vertical margins between stacked blocks collapse: the browser keeps only the larger of the two, not the sum. This is deliberate (it keeps repeated paragraphs evenly spaced) but it startles everyone once. Horizontal margins never collapse — only vertical ones do.
Don't take my 328 on faith. Go read the browser's own ruler.
Chrome keeps a live X-ray of every element's box — the Computed panel. Your job: open your own menu.html, inspect one dish card, and read off its four layers from the browser itself. No guessing, no trusting slides — the browser tells you what it actually drew.
menu.html (your poshtik-campus\ copy, styled by Class 10's style.css) in Chrome. Press F12, or right-click any dish card and choose Inspect.- In the Elements tab, click the
<article class="dish">for Ragi Idli Bowl. - In the right-hand pane, open the Computed tab and scroll to the coloured box-model drawing.
- Write down the four numbers it shows: content width, padding, border, margin.
- Add them up left-to-right and check the total against Part 2's arithmetic.
Inspect honestly first. Reading the Computed panel is the single most-used professional habit this course teaches.
Why 96.5 and not a round number? You never set a height — so the browser computed one from the text inside. Width was pinned by width: 300px; height flows from content. That asymmetry (fixed width, flowing height) is how almost every real card on the web behaves.
Solved PYQ · straight from the papers
Four marks, two ideas: the box model + a colour that changes when printed.
You just measured all four layers with your own eyes — this question is now a victory lap. The second half adds one new trick: @media print, a rule block that applies only when the page is printed. Watch it work for real below, then take the model answer one point per press.
asked verbatim!Explain the CSS Box Model. Write CSS so that a heading appears blue on screen but prints in red. [4M]
Model answer — box model first, then the two-colour trick :
300 + 12+12 + 2+2 = 328px.✓ 1mh1 { color: blue; } — this is what every monitor shows.✓ 1m@media print { h1 { color: red; } } — the block applies only while printing; on paper the same heading comes out red. Never write two separate pages — one page, two media rules.✓ 1m@media print is the tiny cousin of @media (max-width: …) — the responsive queries Class 12 is built on. Nail this 4-marker and you have already met next class's core syntax.Now prove the answer is real. The panel types the exact CSS; the preview beside it is a working simulation — press the two buttons and watch the same heading change ink.
<!DOCTYPE html><html lang="en"><head> <title>Screen vs print</title></head><body> <h1>Poshtik Campus Menu</h1> <p>Same file, two inks.</p></body></html>/* HTML is complete & plain above (default black text). Now add a <style> ↓ */<style> h1 { color: blue; } /* every screen */ @media print { h1 { color: red; } /* paper only */ }</style>Poshtik Campus Menu
Same file, two inks.
↑ PLAIN HTML — NO CSS YET, SO BOTH LINES ARE DEFAULT BLACKCtrl+P — Chrome's print preview shows the heading in red while the tab behind it stays blue. One file, two media, zero duplication.C:\Users\student\Desktop\fswd-practice\class-11\print-demo.html — the 23 lines above, exactlyposhtik-campus\ alone carries commits.Marks anatomy: 2 marks for the four layers named in order with the width arithmetic, 2 marks for the two colour rules — and the @media print block is the half most students drop. Write both rules; label them "screen" and "print" in comments exactly as the panel does.
Error first — watch it break, then fix it
Two half-width columns that refuse to sit side by side.
Here is the layout everyone writes in week one: two columns, each width: 50%, expecting them to share the row. They don't — the second one wraps below. You now know exactly why: 50% + padding + border is more than 50%. Press the buttons in the output and watch box-sizing: border-box repair it live.
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Two columns</title></head><body> <div class="col">Jonna Rotte Wrap — Rs. 60</div> <!-- column one --> <div class="col">Ragi Idli Bowl — Rs. 50</div> <!-- column two — the one that wraps --></body></html>/* two plain divs on screen (full-width, stacked). Now add a <style> ↓ */<style> .col { /* THE PLAN: two columns, half the row each */ float: left; /* sit on one row — Class 12 tells float's full story */ width: 50%; padding: 12px; /* + on top of the 50%! */ border: 2px solid seagreen; /* + again */ background-color: mintcream; } </style>/* each col = 50% + 24 + 4 > half the row *//* 2 cols > 100% — the second one WRAPS */ box-sizing: border-box; /* THE FIX — add inside .col, after line 13 *//* now width:50% means the WHOLE box is 50% — *//* padding + border squeeze INSIDE, content shrinks */The professional opener: real stylesheets start with * { box-sizing: border-box; } — every element, honest widths, forever. From the next time you touch style.css, that line goes at the very top. (We keep today's practice files in the sandbox; the real repo gets it in Class 12's responsive pass, as one deliberate commit.)
History. CSS shipped in 1996 with content-box behaviour, and the web never breaks old pages on purpose — billions of existing sites rely on the old maths. So the sensible behaviour is opt-in: one line, top of the sheet. Old Internet Explorer actually used border-box maths incorrectly on purpose in "quirks mode" — the industry later admitted IE's instinct was the better default, and standardised it as an opt-in property instead.
Where things sit — and who they sit relative to
position — four values, one question: "measured from where?"
Every element starts life in the normal flow — stacked in source order, exactly as your pages have behaved since Class 2. The position property lets one element step out of that queue. The whole topic is a single question asked four ways: when I write top: 10px, 10px from what?
The default. The element sits in the normal flow queue. top/right/bottom/left are ignored completely.
Measured from: nothing — it queues.
Nudged from its own normal spot — and, crucially, its original gap in the queue is kept reserved (the ghost you'll see below).
Measured from: where it would have been.
Pulled out of the queue entirely — its gap closes. It measures from the nearest ancestor that has a position set; if none exists, from the whole page.
Measured from: the nearest positioned ancestor.
Pinned to the browser window itself. Scrolling never moves it — chat bubbles, cookie bars, "back to top" buttons.
Measured from: the window. Always.
Now watch all four, live. One dish card, one NEW badge. Press each mode button and watch where the badge lands — and read the dashed ghost that marks where it would have been.
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Position play</title></head><body> <article class="dish"> <!-- MODE 4 anchors THIS card --> <h4>Ragi Idli Bowl — Rs. 50</h4> <p>Soft steamed finger-millet idlis.</p> <span class="badge">NEW</span> <!-- the element every mode moves --> </article></body></html>/* card + NEW badge on screen, plain (badge queues = static). Now a <style> ↓ */<style> .badge { /* MODE 1 · static — default: rule left EMPTY */ /* MODE 2 · relative — nudged from its own spot */ position: relative; top: -58px; left: 160px; /* ghost stays! */ /* MODE 3 · absolute, NO anchored parent — flies to the PAGE corner */ position: absolute; top: 10px; right: 10px; /* MODE 5 · fixed — pinned to the window, scroll-proof */ position: fixed; right: 12px; bottom: 12px; } /* MODE 4 · keep MODE 3's absolute + ONE new rule on the CARD: */ .dish { position: relative; } </style> /* the anchor */Today's Healthy Ten
Ragi Idli Bowl — Rs. 50
Soft steamed finger-millet idlis.
ghost — its spot in the queue NEWThe pair worth memorising: parent { position: relative; } + child { position: absolute; }. The parent volunteers as the measuring frame; the child pins to its corners. Every price tag, every notification dot, every "NEW" ribbon on every shopping site is this exact two-line pattern.
position: sticky is the hybrid: it scrolls normally like relative, then sticks like fixed once it reaches a threshold (top: 0). Section headers in long lists (your phone's contacts app) use it. It's beyond this paper's syllabus — but now the four you DO need each answer the same question: measured from where?
Read the CSS. Say where the price tag lands — before any browser shows you.
This is the exact skill Part 6 built: answer "measured from where?" from code alone. Read both rules, then commit your prediction in writing. The render is deliberately hidden until you unlock — prediction first is the pedagogy.
<article class="dish"> … <span class="price">Rs. 60</span> </article>. The card sits in the middle of a page with other cards above and below it..dish { position: relative; width: 300px; } and .price { position: absolute; top: 8px; right: 8px; }- Where exactly does
Rs. 60render — measured from which box's corner? - Does the card keep a gap where the price tag used to sit in the flow?
- One-line why: which rule made the card the measuring frame?
A prediction you commit to teaches double: right = confidence, wrong = the exact gap in your model, found cheap.
Jonna Rotte Wrap
Sorghum flatbread wrap with sprouts.
The other half of "why things stack"
display — does this element claim the whole row, or share it?
You have felt this since Class 2 without naming it: a <p> always starts a new line; an <a> sits inside a sentence. That difference IS the display property. block claims the full row and accepts width/height. inline flows within text but ignores width, height and vertical margins. inline-block is the useful hybrid — flows in a row, yet obeys the box properties.
Same three chips, three display modes. Press each button and watch the stacking change — the CSS shown is the only line that differs.
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Display play</title></head><body> <span class="chip">Wraps</span> <span class="chip">Bowls</span> <span class="chip">Drinks</span> <!-- the three chips being switched --></body></html>/* three plain chips on screen (inline spans, side by side). Now a <style> ↓ */<style> .chip { display: block; /* full row each — stack */ display: inline; /* swap in: share the line — width IGNORED */ display: inline-block; /* swap in: share the line AND obey width */ width: 130px; /* honoured only by block + inline-block */ background-color: mintcream; border: 2px solid seagreen; } </style>block: each chip claims a full row — they stack, and the 130px width is honoured.
width: 130px is silently ignored, and so would height and vertical margins be. When a "why is my width doing nothing?!" afternoon strikes, check display first.| block | inline | inline-block | |
|---|---|---|---|
| Row behaviour | claims the whole row | shares the line | shares the line |
| width / height | obeyed | ignored | obeyed |
| Default for | p h1 div article | a strong span img* | (opt-in only) |
| Classic use | sections, cards | words inside sentences | nav pills, badge rows |
<img> is technically inline but behaves like inline-block (it obeys width/height) — browsers special-case replaced elements. And the two display values this class deliberately defers: flex and grid, the modern layout engines. They arrive with the MERN project's real layouts later; block/inline/inline-block is the exam syllabus and the foundation both of them stand on.
The badge escaped its card. Nobody typed an error. Find the silent failure.
A classmate styled a NEW badge exactly like Part 6 taught — position: absolute; top: 8px; right: 8px; — and the badge flew to the top-right of the whole page, nowhere near its card. The CSS below is everything they wrote. No typos, no invalid lines: the browser executed it all happily. This is the classic silent CSS failure — the code is legal, the intent is broken.
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Badge bug</title></head><body> <article class="dish"> <h4>Ragi Idli Bowl — Rs. 50</h4> <span class="badge">NEW</span> <!-- the escapee --> </article></body></html>/* card + NEW badge on screen, plain. Now the classmate's <style> ↓ */<style> .dish { /* the card — but is it an ANCHOR? */ width: 300px; padding: 12px; background-color: mintcream; border: 2px solid seagreen; } .badge { position: absolute; /* ...but there is NO positioned ancestor! */ top: 8px; right: 8px; background-color: seagreen; color: white; } </style>Ragi Idli Bowl — Rs. 50
NEW- The badge measured its
top: 8px; right: 8pxfrom what — and why that box? - Which single line is missing, and from which rule?
- Why did the browser show no error anywhere — DevTools console included?
This exact bug will find you in Lab 3. Diagnose it here, where it's cheap.
The three verdicts: ① with no positioned ancestor anywhere, the badge climbed all the way up and measured from the page itself — absolute always walks up the family tree looking for a positioned parent and settles for the document if none volunteers. ② The missing line is position: relative on .dish — note the fix goes on the parent, not the element that looks wrong. ③ No error because nothing IS an error: every line is valid CSS doing exactly what it says. CSS never errors on legal-but-unintended — which is why the Part 3 DevTools habit, not the console, is how layout bugs get found.
Everything at once, on the real project
Poshtik's header — boxed, spaced and pinned, with today's whole toolkit.
One worked example, every idea from today: honest border-box sizing, deliberate padding instead of accidental gaps, inline-block nav pills that obey their width, and the header fixed to the top so the menu stays reachable while you scroll the ten dishes. Type it in the sandbox and watch each line land in the preview.
- Header:
background-color: darkslategray,padding: 12px 16px,position: fixed; top: 0; left: 0; right: 0;. - Nav links:
display: inline-block,padding: 6px 14px, white text, no underline. - Body:
padding-top: 70px— the fixed header floats OVER content; the body must duck under it. - Everything sized with
box-sizing: border-box.
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Header play</title></head><body> <header><nav><a href="#">Menu</a><a href="#">About</a></nav></header> <h1>Today's Healthy Ten</h1></body></html>/* HTML is complete & PLAIN above (a stacked nav, a heading). Now the <style> in <head> ↓ */ <style> * { box-sizing: border-box; } /* honest widths, line one */ header { background-color: darkslategray; padding: 12px 16px; } header { position: fixed; top: 0; left: 0; right: 0; } /* pinned */ nav a { display: inline-block; padding: 6px 14px; } /* share the row */ nav a { color: white; text-decoration: none; } body { background-color: floralwhite; } /* h1 is HIDDEN under the bar! */ body { padding-top: 70px; } /* THE FIX — duck under the fixed bar */ </style>Today's Healthy Ten
⚠ the heading is now UNDER the fixed bar — line 13 rescues itSorghum flatbread wrap with sprouts.
Soft steamed finger-millet idlis.
Green-gram dosa, ginger chutney.
Horse-gram protein bowl.
…scroll me — the dark bar never moves.
↑ PLAIN HTML — DEFAULT BLUE UNDERLINED LINKS, NO BAR, NO CARDSC:\Users\student\Desktop\fswd-practice\class-11\header-play.html — one file: today's skeleton + the style block aboveTake it home
Your layout kit — the whole class on one card.
| PROPERTY | DECIDES | THE ONE THING TO REMEMBER | TODAY'S EXAMPLE |
|---|---|---|---|
| padding | Space INSIDE the border — same colour as the box | pushes content in; grows the visible box | padding: 12px; |
| border | The visible edge between inside and outside | it has thickness — it counts in the width sum | border: 2px solid seagreen; |
| margin | Space OUTSIDE — pushes the neighbours away | transparent; vertical margins can collapse | margin: 0 auto; centres a box with a width |
| box-sizing | What width means | border-box = the honest total; line one of every pro stylesheet | * { box-sizing: border-box; } |
| position | WHICH frame offsets measure from | absolute hunts for a positioned parent — or takes the page | .dish { position: relative; } |
| top / right / bottom / left | The offsets themselves | dead lines on static — position must be set first | top: 8px; right: 8px; |
| display | How the box shares the row | inline IGNORES width/height; inline-block obeys | nav a { display: inline-block; } |
Class 11 · closed
You can see the boxes now. Next: making them fit every screen.
Today you earned X-ray vision — four layers on every element, the 328-pixel arithmetic, border-box honesty, the position playground and the display switcher — and you caught an escaped badge with a one-line fix on its parent. Class 12 asks the question every phone in this room is already asking: your 300px cards look right on the projector — what happens on a 360px screen? Media queries, the viewport, and responsive design close out CSS.
- Five-minute drill: without notes, draw the four-layer diagram, label it, and compute the total width of a width: 200px; padding: 10px; border: 5px solid; margin: 20px box — both dialects: content-box and border-box.
- PYQ rehearsal: write the P1·Q16a answer cold — the four layers half AND the screen-blue / paper-red media-type half with both magic phrases.
- Ten-minute experiment: in header-play.html, delete the padding-top: 70px line, watch the title hide behind the bar, put it back. Then inspect the header in DevTools and read its real box.