What this chapter is really for
Split again: Part 1 (slides 1–60) is selectors, the cascade, the box model and text/table/form styling; Part 2 (slides 61–84) is flexbox, grid and responsive design.
Be warned about this deck specifically. A large share of its most important slides — the flexbox container properties (65–66), the flex item properties (67), the grid structure slides (69–71) — are images with almost no text on them. If you revise from the slide text alone you will have a chapter with a hole in the middle exactly where the layout marks are. That gap is what the code sections below are for.
The two ideas everything hangs off
The cascade decides which rule wins when several apply: inheritance, then specificity, then location. The box model decides how big things are: content, padding, border, margin. Almost every "why does my page look wrong" question is one of these two.
Engineering framing worth quoting
Slide 3 gives the reason CSS exists in engineering terms: separation of concerns and reuse. The listed benefits — control over formatting, maintainability, accessibility, download speed, output flexibility — all follow from those two.
All 85 slides, weighted
| Slides | Topic | Weight | What to do with it |
|---|---|---|---|
| 1–3 | What CSS is; benefits | Memorize | Separation of concerns + reuse, then five benefits. A likely short-answer question. |
| 4–5 | Rule, selector, declaration, declaration block, values | Memorize | Get the vocabulary exactly right — questions are worded using these terms. |
| 6 | The five ways to write a colour | Memorize | Name, RGB, hexadecimal, RGBa, HSL/HSLA. Know which are CSS3-only. |
| 7 | Units: relative vs absolute | Memorize | px, em, vw are the ones asked about; in and cm are absolute. |
| 8–11 | Inline, embedded and external styles | Write it | Know the syntax of all three and why external wins: one change updates every page, and the browser can cache it. |
| 12–15 | Element, class and ID selectors | Write it | The id is unique to one element; a class targets many. An element can carry several classes. |
| 16–18 | Attribute selectors — all six operators | Write it | [] [=] [~=] [^=] [*=] [$=]. Very examinable, and easy marks once memorised. |
| 19–22 | Pseudo-classes and pseudo-elements | Write it | Link states in order, :hover, :active, :first-child, :first-letter, :first-line, :is(). |
| 23 | Task: last child red; links whose href contains "example" | Write it | Do it. It is two lines and it tests both halves of the selector material. |
| 25–26 | Contextual selectors / combinators | Write it | Space, >, +, ~. Learn what each one actually matches, not just its name. |
| 27 | Nested CSS rules | Skim | New, and shown side by side with the flat equivalent. Understand the translation both ways. |
| 28–32 | The cascade: inheritance, specificity, location | Memorize | The highest-value block in Part 1. Slide 31 gives the a-b-c-d specificity algorithm — learn to compute it. |
| 33–36 | Block vs inline elements | Memorize | Two block elements cannot share a line without styling. Inline elements flow within lines and wrap. |
| 37–42 | Margins, padding, the box model, dimensions, overflow | Write it | Learn the four-value / two-value / one-value shorthand rules and how total element size is calculated. |
| 43–50 | Text and font properties, web font stacks, @import, rem | Write it | A font stack exists because your font may not be on the user’s machine. rem is relative to the root element. |
| 51–53 | CSS variables / custom properties | Write it | Declared in :root, named with --, read with var(). Almost certain to appear in a lab. |
| 54–57 | Styling tables: borders, border-collapse, zebra striping | Write it | Borders can go on table, th and td only — not on tr, thead, tbody, tfoot. That exact fact is examinable. |
| 58–60 | Styling forms, placeholders, labels, form design | Write it | Ties chapter 2 forms to CSS. ::placeholder is the pseudo-element to remember. |
| 61–62 | Part 2 title and objectives | Skim | Transition slides. |
| 63–67 | Flexbox: containers and items | Write it | Screenshot slides. The property tables are images. Use the reconstruction below. |
| 68–77 | Grid: structure, column widths, placement, cells, nesting, named areas | Write it | Mostly screenshots too, except the named-areas listing on slide 76. Highest-value practical block in the chapter. |
| 78 | Grid and flexbox together | Memorize | One sentence that answers the "which do I use" question: grid for the page structure, flexbox for the contents of a cell. |
| 79–84 | Responsive design, viewports, media queries, <picture> | Write it | Memorize the viewport meta tag verbatim. Know why max-width:100% is not enough on its own. |
| 85 | Supporting material and links | Skim | The code repository for every chapter: github.com/skanderturki/se371. |
Syntax and every selector type
The vocabulary, precisely
/* ── one RULE ──────────────────────────────── */ h1, h2 { ← SELECTOR (comma groups several) color: #431c5d; ← DECLARATION: property : value font-size: 24pt; ← another declaration } ← the { } is the DECLARATION BLOCK /* A stylesheet is one or more rules. The unit of a value depends on the property: keywords, percentages, lengths, unitless numbers, colour values and URLs are all possible. */
Colour: five ways to say red
| Method | Description | Example |
|---|---|---|
| Name | 17 standard names; CSS3 has 140. | color: red; · color: hotpink; (CSS3) |
| RGB | Three numbers 0–255 for red, green and blue. | color: rgb(255,0,0); |
| Hexadecimal | A six-digit hex number for the same three values. | color: #FF0000; |
| RGBa | Adds alpha — transparency. | color: rgba(255,0,0,0.5); |
| HSL / HSLA | Hue, saturation, lightness. CSS3 only. | color: hsl(0,100%,100%); |
Units
Units are either relative (based on the value of something else) or absolute (a real-world size).
| Unit | Kind | Meaning |
|---|---|---|
px | Relative in CSS2, absolute in CSS3 | 1/96 of an inch, so roughly 1.06 mm. |
em | Relative | The computed font-size of the element it is used on. 2em = twice the current font size. |
rem | Relative | Always relative to the root <html> element — introduced because nested ems become impossible to calculate. |
vw | Relative | 1% of the viewport width. If the viewport is 30 cm wide, 1vw = 0.3 cm. |
in, cm | Absolute | Real-world inches and centimetres. |
Where styles live — three locations, not mutually exclusive
<!-- 1. INLINE — style attribute. Affects only this element. Overrides other definitions for the properties it sets. --> <h2 style="font-size: 24pt; font-weight: bold;">Reviews</h2> <!-- 2. EMBEDDED (internal) — a <style> element in the <head>. Better than inline, but still discouraged. --> <head> <style> h1 { font-size: 24pt; } h2 { font-size: 18pt; font-weight: bold; } </style> </head> <!-- 3. EXTERNAL — a .css file. THE ONE TO USE. • change it once, every page that links it updates • the browser can CACHE it, which improves performance --> <head> <link rel="stylesheet" href="styles.css"> </head>
Basic selectors
/* ELEMENT — every instance of the element */ p { margin: 0; } /* UNIVERSAL — every element */ * { box-sizing: border-box; } /* GROUPED — commas. These two are exactly equivalent: */ p, div, aside { margin: 0; padding: 0; } /* ≡ p{margin:0;padding:0} div{...} aside{...} */ /* CLASS — a period. Targets MANY elements. */ .orange { background-color: orange; } .circle { border-radius: 50%; } /* ID — a hash. UNIQUE: one element per document. */ #first { border: 2px solid black; }
An element may carry several classes — <div class="orange circle"> —
and where two of its classes set the same property, priority goes to whichever rule appears
last in the document. That is the location principle, arriving early.
Attribute selectors — all six operators
[title] /* has the attribute at all */ a[title="posts from this country"] /* exact value */ [title~="Countries City"] /* value contains this WORD in a space-separated list */ a[href^="mailto"] /* value BEGINS with (^ = start, like regex) */ img[src*="flag"] /* value CONTAINS the substring anywhere */ a[href$=".pdf"] /* value ENDS with ($ = end, like regex) */ /* The slide's own example: mark PDF links with an icon */ a[href$=".pdf"] { background: url(pdf.jpg) no-repeat left center; padding-left: 20px; }
^ is “starts with” and $ is “ends with” in regular expressions too (chapter 5), and * is the greedy one — anywhere at all. Only ~= is CSS-specific: a whole word in a space-separated list.Pseudo-classes and pseudo-elements
A pseudo-element selects something that does not exist as an element in the document tree — the first line or first letter of a block. A pseudo-class targets a state or a family relationship.
/* LINK STATES — write them in this order or later ones stop working */ a:link { color: #0000EE; } /* not yet visited */ a:visited { color: #551A8B; } /* already visited */ a:hover { color: #b829ea; } /* pointer is currently above */ a:active { color: red; } /* being activated / clicked */ /* FAMILY + TEXT */ li:first-child { font-weight: bold; } /* first child of its parent */ li:last-child { color: red; } /* ← the slide 23 task */ p::first-letter { font-size: 3em; } /* pseudo-ELEMENT: :: */ p::first-line { font-variant: small-caps; } /* :is() takes a selector LIST — far shorter than repeating :hover */ :is(input, label, button, select):hover { outline: 2px solid #b829ea; } /* instead of input:hover, label:hover, button:hover, select:hover */ /* The other half of the slide 23 task */ a[href*="example"] { color: red; }
Contextual selectors (combinators)
/* Given this markup: <section> <h2>Title</h2> <p>One</p> <div><p>Nested</p></div> <p>Two</p> </section> */ section p { } /* DESCENDANT, a SPACE. Matches One, Nested AND Two — every p contained anywhere inside section. */ section > p { } /* CHILD, a >. Matches One and Two only — Nested is a child of div, not of section. */ h2 + p { } /* ADJACENT, a +. Matches One only — the NEXT SIBLING immediately after h2. */ h2 ~ p { } /* GENERAL SIBLING, a ~. Matches One and Two — ALL following siblings sharing the same parent. */
> = directly inside? · + = immediately after? · ~ = anywhere after, same parent?Nested rules (new)
/* NESTED — implemented by all major browsers, still a W3C draft */ .card { padding: 1rem; & h2 { margin: 0; } & p { color: gray; } &:hover { border-color: #b829ea; } } /* ── is exactly equivalent to ── */ .card { padding: 1rem; } .card h2 { margin: 0; } .card p { color: gray; } .card:hover { border-color: #b829ea; }
The cascade — the most examinable idea in CSS
The cascade is how conflicting rules are resolved, and it applies three principles in this order: inheritance, specificity, location.
1. Inheritance
Many CSS properties affect descendants as well as the element itself. The division is not arbitrary and is worth learning as two lists:
| Inherited | Not inherited |
|---|---|
Font properties — font-family, font-size, font-weight | Layout properties — display, position, float |
Color — color | Sizing — width, height |
List properties — list-style-type | Border properties |
Text properties — text-align, line-height | Background and spacing — margin, padding |
/* You can FORCE inheritance of a property that normally does not inherit */ button { color: inherit; font-family: inherit; } /* ↑ the classic use: form controls do not inherit page fonts by default */
2. Specificity — and how to actually compute it
The more specific selector wins: id beats class, class beats element. Slide 31 gives the simplified
algorithm as four counters, written as abcd:
a = is it an INLINE style? (1 or 0) b = count the IDs (#) c = count the CLASSES + ATTRIBUTES + pseudo-classes (. [ ] :) d = count the ELEMENTS (tag names + pseudo-elements) Read a-b-c-d as one number, LEFT TO RIGHT. Higher wins. A single id beats any number of classes: 0-1-0-0 > 0-0-9-9. ─── worked examples ─────────────────────────────────────────── p a=0 b=0 c=0 d=1 → 0001 .orange a=0 b=0 c=1 d=0 → 0010 div p a=0 b=0 c=0 d=2 → 0002 div p.intro a=0 b=0 c=1 d=2 → 0012 #first a=0 b=1 c=0 d=0 → 0100 ← beats all of the above #first p.intro:hover a=0 b=1 c=2 d=1 → 0121 style="color:red" a=1 b=0 c=0 d=0 → 1000 ← beats everything Question style: "which colour is applied?" — compute abcd for each rule that could match, take the largest. If TWO tie, go to location.
3. Location
When inheritance and specificity cannot decide, location does: with equal specificity, the later rule wins. Which is why an inline style overrides an embedded or external stylesheet, and why the last of two competing classes on an element is the one that applies.
Box model, text, variables, tables and forms
Block vs inline
| Block-level | Inline |
|---|---|
<p> <div> <h2> <ul> <table> | normal text, <em> <a> <img> <span> |
| Each sits on its own line. Without styling, two block elements cannot share a line. | Displayed within lines; does not form its own block. |
Uses the normal CSS box model, with width and height. | When there is not enough room on the line, content moves to a new line. |
The box model
┌─────────────────── MARGIN ──────────────────────┐ ← space AROUND the element │ ┌──────────────── BORDER ────────────────────┐ │ (divides margin from padding) │ │ ┌───────────── PADDING ─────────────────┐ │ │ ← space INSIDE the element │ │ │ │ │ │ │ │ │ CONTENT │ │ │ ← width and height apply HERE ONLY │ │ │ (width × height) │ │ │ │ │ └───────────────────────────────────────┘ │ │ │ └────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────┘ TOTAL WIDTH = width + padding-left/right + border-left/right + margin-left/right ← this is why a 100%-wide box with padding overflows its parent. /* Shorthand: 4 values, 2 values, or 1 */ .a { border-color: red green orange blue; } /* top right bottom left — clockwise */ .b { border-color: red yellow; } /* top+bottom = red, right+left = yellow */ .c { border-color: red; } /* all four sides */ /* Or set one side at a time */ .d { border-top-color: red; border-right-color: green; border-bottom-color: yellow; border-left-color: blue; } /* The fix everybody uses: make width MEAN total width */ * { box-sizing: border-box; }
Block-level elements also have min-width, min-height,
max-width and max-height, which matter when a width is expressed as a
percentage of the parent. And overflow controls what happens when the box is not large
enough for its content: visible (default), hidden, scroll,
auto.
Text and fonts
/* A WEB FONT STACK: fallbacks, because your font may not be installed on the user's computer. Always end with a generic family. */ body { font-family: 'Roboto Slab', Georgia, 'Times New Roman', serif; font-size: 1rem; /* rem = relative to the ROOT html element */ font-weight: 400; /* 100–900, or normal / bold */ font-style: normal; /* normal | italic | oblique */ line-height: 1.7; text-align: left; text-decoration: none; text-transform: uppercase; letter-spacing: 0.05em; } /* Using a font that is NOT installed anywhere — two ways */ /* 1. a link in <head>: <link href="https://fonts.googleapis.com/css?family=Droid+Sans" rel="stylesheet"> */ /* 2. an @import at the TOP of a CSS file: */ @import url('https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@400&display=swap');
CSS variables (custom properties)
Slide 52 shows a stylesheet where #431c5d, 4px, 5px,
18px and one long box-shadow are each repeated several times. Slide 53
rewrites it. This is the pattern to reproduce in labs.
/* Declare in :root — names MUST begin with a double hyphen */ :root { --bg-color-main: #431c5d; --bg-color-secondary: #e05915; --fg-color-main: #e6e9f0; --radius-boxes: 5px; --padding-boxes: 4px; --fontsize-default: 18px; --shadow-color: rgba(0,0,0,0.22); --dropshadow: 6px 5px 20px 1px var(--shadow-color); /* variables can use variables */ } /* Read with the var() function */ header { background-color: var(--bg-color-main); color: var(--bg-color-secondary); padding: var(--padding-boxes); box-shadow: var(--dropshadow); margin: 0; } header button { background-color: var(--bg-color-secondary); border-radius: var(--radius-boxes); border-color: var(--fg-color-main); font-size: var(--fontsize-default); margin-top: calc(var(--fontsize-default) / 2); /* note: var() INSIDE calc() */ }
Styling tables
/* WHERE BORDERS CAN GO — an examinable fact: ✓ table, th, td ✗ tr, thead, tbody, tfoot ← borders CANNOT be assigned to these */ table { border-collapse: collapse; /* adjacent cells SHARE one border */ /* border-collapse: separate; ← the DEFAULT: each cell has its own */ width: 100%; } th, td { border: 1px solid #ccc; padding: 0.6rem; text-align: left; } /* ZEBRA STRIPING with the nth-child pseudo-class */ tbody tr:nth-child(even) { background-color: #f4f0fa; } /* ROW HIGHLIGHT on hover */ tbody tr:hover { background-color: #e6d8f5; }
Styling forms
/* The common change described on slide 58: drop the border, round the corners, add padding. */ input[type="text"], input[type="email"], textarea { border: none; border-bottom: 2px solid #ccc; border-radius: 8px; padding: 0.6rem 0.8rem; font: inherit; /* controls do NOT inherit fonts by default */ } input:focus { outline: 2px solid #b829ea; } /* ::placeholder — the pseudo-element for the placeholder text */ input::placeholder { color: #948da3; font-style: italic; } /* Labels on their own line, with a click target */ label { display: block; margin-bottom: 0.3rem; font-weight: 600; }
Layout — the screenshot slides, reconstructed
Slide 63 opens with a rule: tables were once used for page layout and this should never be done — it pollutes the HTML, makes SEO harder and is not maintainable.
Everything below this point is what the slide images contained. Nothing here is in the slide text, which is why this section is the one to work through with a browser open.
Flexbox — for one-dimensional layouts
Properties go in two places: on the flex container and on the flex items inside it. Any direct child of a flex container automatically becomes a flex item.
<style> .flex-container { display: flex; /* this ONE line creates the flex context */ background-color: DodgerBlue; flex-direction: row; /* row | row-reverse | column | column-reverse */ flex-wrap: wrap; /* wrap | nowrap (default) | wrap-reverse */ } .flex-container > div { /* direct children ARE the flex items */ background-color: #f1f1f1; margin: 10px; font-size: 30px; } </style> <div class="flex-container"> <div>1</div><div>2</div><div>3</div> </div>
Container properties — the table from slides 65–66
| Property | Values | What it does |
|---|---|---|
display | flex · inline-flex | Makes the element a flex container. Nothing else works without it. |
flex-direction | row · row-reverse · column · column-reverse | Sets the main axis. Everything else is described relative to it. |
flex-wrap | nowrap (default) · wrap · wrap-reverse | Whether items may overflow onto more lines. |
flex-flow | row wrap | Shorthand for direction + wrap. |
justify-content | flex-start · flex-end · center · space-between · space-around · space-evenly | Aligns items along the main axis. |
align-items | stretch (default) · flex-start · flex-end · center · baseline | Aligns items across the cross axis. |
align-content | Same values as justify-content | Aligns the lines when content has wrapped. No effect on a single line. |
gap | A length | Space between items, without margin arithmetic. |
Item properties — slide 67
| Property | Default | What it does |
|---|---|---|
order | 0 | Reorders items visually without touching the HTML. Lower first. |
flex-grow | 0 | Share of the leftover space this item takes. This is the fraction the slide mentions: grow 2 takes twice as much extra space as grow 1. |
flex-shrink | 1 | How readily the item shrinks when there is not enough room. 0 = never shrink. |
flex-basis | auto | The item’s size before growing or shrinking — its starting width on a row. |
flex | 0 1 auto | Shorthand for grow / shrink / basis. flex: 1 is the everyday one. |
align-self | auto | Overrides the container’s align-items for this item alone. |
.flex-container { display: flex; } /* Give each child a FRACTION of the container — the slide 67 note */ .item-a { flex: 1; } /* 1 share → 1/6 of the free space */ .item-b { flex: 2; } /* 2 shares → 2/6 */ .item-c { flex: 3; } /* 3 shares → 3/6 */ /* Longhand equivalent of flex: 2 */ .item-b { flex-grow: 2; flex-shrink: 1; flex-basis: 0%; } /* The centring everyone memorises: dead centre, both axes */ .centre { display: flex; justify-content: center; align-items: center; }
justify-content works along the main axis, align-items across the cross axis. With flex-direction: row that means justify = horizontal, align = vertical — but switch to column and they swap. Learn them as main/cross, never as horizontal/vertical.Grid — for two-dimensional layouts
Every block-level child of a container with display: grid is automatically placed into
a grid cell.
.container { display: grid; /* COLUMNS — the fr unit is a FRACTION of the free space */ grid-template-columns: 1fr 1fr 1fr; /* three equal columns */ grid-template-columns: 200px 1fr 1fr; /* fixed + two flexible */ grid-template-columns: repeat(3, 1fr); /* repeat() — same thing */ grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); /* ↑ responsive with NO media query: as many 240px-min columns as fit */ /* ROWS work identically */ grid-template-rows: 100px 150px 100px; gap: 10px; /* or row-gap / column-gap / grid-gap */ }
/* EXPLICIT PLACEMENT — count grid LINES, not cells. 3 columns means 4 vertical lines: 1 2 3 4 */ .header { grid-column: 1 / 4; } /* from line 1 to line 4 = all 3 columns */ .header { grid-column: 1 / span 3; } /* identical, written as a span */ .header { grid-column: 1 / -1; } /* identical: -1 is the LAST line */ .sidebar { grid-row: 2 / 4; } /* two rows tall */ /* CELL ALIGNMENT — slide 74. *-items on the CONTAINER sets the default for every cell; *-self on an ITEM overrides it for that one cell. */ .container { justify-items: center; align-items: center; } .blue { justify-self: start; align-self: end; } /* justify = horizontal (along the row), align = vertical (down the column) */
Named areas — the full listing from slide 76
<style> .container { display: grid; grid-gap: 10px; grid-template-rows: 100px 150px 100px; grid-template-columns: 75px 1fr 1fr 1fr 1fr; /* Each STRING is a row; each WORD is a column. A name repeated across adjacent cells makes one merged area. A dot ( . ) leaves that cell empty. */ grid-template-areas: ". a1 a2 a3 a4" "b1 b2 b2 b2 b3" /* b2 spans 3 columns */ "b1 c1 c2 c2 c2"; /* b1 spans 2 rows */ } .a1 { grid-area: a1; } .b1 { grid-area: b1; } .c1 { grid-area: c1; } .a2 { grid-area: a2; } .b2 { grid-area: b2; } .c2 { grid-area: c2; } .a3 { grid-area: a3; } .b3 { grid-area: b3; } .a4 { grid-area: a4; } </style> <section class="container"> <div class="yellow a1">A1</div> <div class="yellow a2">A2</div> <div class="yellow a3">A3</div> <div class="yellow a4">A4</div> <div class="orange b1">B1</div> <div class="orange b2">B2</div> <div class="orange b3">B3</div> <div class="cyan c1">C1</div> <div class="cyan c2">C2</div> </section>
Grid and flexbox together — the decision rule
Grid builds the layout structure of the page. Flexbox lays out the contents of a grid cell. That single sentence from slide 78 answers the "which should I use" question in an exam, and it is also just good practice: grid is two-dimensional, flexbox is one-dimensional.
/* GRID for the page skeleton */ .page { display: grid; grid-template-columns: 240px 1fr; grid-template-rows: 64px 1fr auto; grid-template-areas: "head head" "side main" "foot foot"; min-height: 100vh; } /* FLEXBOX inside one of those cells */ .page > header { grid-area: head; display: flex; align-items: center; /* vertical centring within the bar */ justify-content: space-between; /* logo left, actions right */ gap: 1rem; }
Responsive design
In a responsive design the page responds to changes in browser size beyond simple percentage scaling: smaller images are served, and navigation elements are replaced as the window shrinks.
The viewport — memorize this tag
<meta name="viewport" content="width=device-width, initial-scale=1"> ↑ size of the viewport ↑ zoom level WHY: the viewport is the part of the browser window that shows web content. Mobile browsers DEFAULT to scaling a whole desktop-width page down to fit the screen. The result works, but is very difficult to read and use. This tag tells the browser to use the device's real width instead — after which your media queries actually fire.
Media queries
A media query applies style rules based on the medium displaying the file. Contemporary responsive sites give rules for phones first, then tablets, then desktops — an approach the slide names progressive enhancement.
/* MOBILE FIRST: the base rules are the phone layout. No media query needed — this is the default. */ .page { display: grid; grid-template-columns: 1fr; } nav ul { display: none; } /* nav replaced by a menu button */ /* TABLET and up */ @media (min-width: 600px) { .page { grid-template-columns: 200px 1fr; } nav ul { display: flex; gap: 1.5rem; } } /* DESKTOP and up */ @media (min-width: 1024px) { .page { grid-template-columns: 240px 1fr 300px; } } /* Other media types and features you can query */ @media print { nav, footer { display: none; } } @media (orientation: landscape) { /* … */ } @media (prefers-color-scheme: dark) { /* … */ }
Images: scaling is not the same as downloading less
/* Making an image SCALE is one line — but the browser still downloads the full-size file. On a phone that is wasted bandwidth. */ img { max-width: 100%; } <!-- <picture> (HTML5.1) lets you offer SEVERAL images and lets the browser choose which one to download, based on viewport size. --> <picture> <source media="(min-width: 1024px)" srcset="banner-large.jpg"> <source media="(min-width: 600px)" srcset="banner-medium.jpg"> <img src="banner-small.jpg" alt="Campus banner"> <!-- fallback, always last --> </picture>
max-width: 100% changes how big the image looks. <picture> changes which file gets downloaded. Only the second one saves the user's data.The eight things people get wrong
You assume the last rule wins, but a rule further up with an id in it is beating it. Location only applies after specificity ties.
Fix: Compute a-b-c-d for every competing rule and compare left to right. One id (0-1-0-0) beats nine classes (0-0-9-0).
width: 100% plus padding: 1rem plus a border is wider than the parent, because width sizes the content area only.
Fix: Either subtract the padding yourself, or set box-sizing: border-box so width means the full outside width. This is why almost every stylesheet starts with * { box-sizing: border-box; }.
justify-content as "horizontal"It is horizontal only while flex-direction is row. Switch the container to column and justify-content becomes vertical, so a layout that centred correctly suddenly does not.
Fix: Learn them as main axis (justify) and cross axis (align). The direction sets which is which.
grid-column: 1 / 3 spans two columns, not three, because those numbers are line numbers. Three columns are bounded by four lines.
Fix: Sketch the lines and number them, or avoid the arithmetic entirely with span: grid-column: 1 / span 3. And -1 always means the last line.
Your breakpoints work perfectly when you resize the desktop browser but do nothing on an actual phone. The viewport meta tag is missing, so the mobile browser is rendering at a fake desktop width and scaling the result down.
Fix: Put <meta name="viewport" content="width=device-width, initial-scale=1"> in the <head> of every page. Nothing responsive works reliably without it.
<tr>Nothing happens, and it looks like a CSS bug. Slide 54 states it directly: borders can be assigned to <table>, <th> and <td>, and cannot be assigned to <tr>, <thead>, <tfoot> or <tbody>.
Fix: Style the cells instead: tr:hover td { ... } or a border-bottom on every td in the row.
Writing a:hover before a:visited means a visited link never shows its hover colour — both selectors have the same specificity, so the later one wins.
Fix: Keep the order :link, :visited, :hover, :active. It is a location problem wearing a costume.
You set font-family on body and every input still renders in the browser’s default. Font properties inherit, but form controls are a documented exception.
Fix: Add input, select, textarea, button { font: inherit; } — this is exactly the use case for the inherit keyword on slide 29.
Chapter 3 on a single screen
Selector types
pelement ·*universal.classmany ·#idonep, divgroup[attr][a="v"][a~="w"][a^=]starts ·[a*=]contains ·[a$=]ends
Combinators
a b— descendant, anywhere insidea > b— direct childa + b— next siblinga ~ b— all following siblings
Cascade order
- 1. Inheritance — font/color/list/text yes; layout/size/border/background/spacing no
- 2. Specificity —
a=inlineb=idc=class/attrd=element - 3. Location — later wins on a tie
Box model
- content → padding → border → margin
widthsizes the content only- 4 values = top right bottom left
- 2 values = top/bottom, right/left
box-sizing: border-boxfixes the maths
Flex container
display: flexflex-directionrow | column (+reverse)flex-wrapnowrap | wrapjustify-content— main axisalign-items— cross axisgap
Flex item
flex: grow shrink basis(0 1 auto)flex: 1— equal share of free spaceorder— visual reorderingalign-self— override for one item
Grid
display: gridgrid-template-columns: 1fr 1frrepeat(3, 1fr)·minmax(240px, 1fr)grid-column: 1 / 4— LINE numbers1 / span 3·1 / -1grid-template-areas+grid-area
Responsive
<meta name="viewport" content="width=device-width, initial-scale=1">@media (min-width: 600px) { }- Phone first, then tablet, then desktop
img { max-width: 100% }scales<picture>downloads less
Variables
- Declare in
:root, names start-- - Read with
var(--name) - Variables may reference variables
calc(var(--x) / 2)
Build these, do not read about them
Layout is not learnable by reading, and this is the chapter where that bites hardest, because the layout slides are pictures. Open a file, open the browser, and build.
- Write the same rule three ways: inline, embedded and external. Then explain in one sentence why external wins.
- Write one selector for each of the six attribute operators, and say in words what each matches.
- Style a link’s four states in the correct order, then deliberately reorder them and observe what breaks.
- Complete the slide 23 task: colour the last child of a
ulred, and style every<a>whosehrefcontains “example”. - Given four rules that all match one element, compute
abcdfor each and predict the winner. Then check in DevTools — the Styles panel strikes through the losers. - Build a box with an explicit width, padding and border. Measure the real rendered width in DevTools, then add
box-sizing: border-boxand measure again. - Convert a stylesheet with five repeated values into CSS variables declared in
:root. - Style a table: collapsed borders, zebra striping with
nth-child, and a hover highlight on rows. - Build a flex row of five items, then use
flex: 1 / 2 / 3to give three of them different shares of the free space. - Centre a box perfectly in the viewport using three lines of flexbox.
- Take that same flex container, switch it to
column, and predict what happens tojustify-contentbefore you reload. - Build a three-column grid with
repeat(auto-fit, minmax(240px, 1fr))and resize the window — a responsive layout with no media query. - Reproduce the slide 76 named-areas layout exactly, then move one area by editing only the
grid-template-areasstrings. - Build a page skeleton with grid and lay out its header with flexbox, following the slide 78 rule.
- Write a mobile-first stylesheet with breakpoints at 600px and 1024px, then delete the viewport meta tag and test it on a phone to see what happens.
Worked examples for almost all of this already sit in your study material: the
CSS example folder,
the CSS layout handout with exercises,
and the two solved CSS labs
(lab 03a,
lab 03b).
Slide 85 also gives the repository for every chapter’s code:
github.com/skanderturki/se371.