CSS — Cascading Style Sheets
Think of HTML as the skeleton of a house — walls, rooms, doors. CSS is the interior design — paint colors, furniture arrangement, spacing between objects. Without CSS, every webpage would look like a plain text document from 1995.
CSS controls how HTML elements look — colors, spacing, layout, fonts, animations. There are three ways to add CSS to your page:
| Method | Syntax | Priority |
|---|---|---|
| Inline | <p style="color:red"> | Highest (1000) |
| Internal | <style> in <head> | Normal |
| External | <link rel="stylesheet" href="style.css"> | Normal |
CSS Selectors
Why do selectors exist? Imagine you are a teacher in a classroom of 30 students. You need a way to say "Hey, YOU specifically" or "everyone in the back row" or "all students wearing blue shirts." CSS selectors are exactly that — they are how you point at specific HTML elements and say "I want to style YOU."
Without selectors, you would have to put inline styles on every single element. Selectors let you write one rule that applies to many elements at once, or target one very specific element.
| Selector | Syntax | Selects |
|---|---|---|
| Universal | * | All elements (like yelling "EVERYONE!") |
| Element | p | All <p> tags (like saying "all paragraphs") |
| Class | .intro | Elements with class="intro" (like a team jersey — many can wear it) |
| ID | #main | Element with id="main" (like a roll number — unique to one person) |
| Descendant | div p | All <p> inside <div> (children, grandchildren, great-grandchildren...) |
| Child | div > p | Direct <p> children of <div> (only immediate children, not grandkids) |
| Adjacent sibling | h2 + p | First <p> right after <h2> (the next-door neighbor) |
| General sibling | h2 ~ p | All <p> siblings after <h2> (all neighbors on the same street) |
| Attribute | input[type="text"] | Inputs with type text (selecting by a specific trait) |
| Group | h1, h2, h3 | All h1, h2, and h3 elements (applying one rule to multiple selectors) |
div p (descendant) selects ALL <p> elements anywhere inside <div> — children, grandchildren, great-grandchildren. div > p (child) only selects direct children — just the first generation, not nested ones.If a
<p> is inside a <span> inside a <div>, then div p will select it, but div > p will NOT — because that <p> is a grandchild, not a direct child.
/* Element selector — targets ALL paragraphs */ p { color: blue; } /* Class selector — targets anything with class="highlight" */ .highlight { background: yellow; } /* ID selector — targets the ONE element with id="header" */ #header { font-size: 24px; } /* Descendant vs Child — EXAM FAVORITE */ div p { color: red; } /* ALL p inside div (any depth) */ div > p { color: blue; } /* only DIRECT p children of div */ /* Attribute selector */ a[target="_blank"] { color: red; }
div > p select?" — It selects only direct child <p> elements, not nested ones. Compare with div p which selects ALL descendants. Also watch for p.intro vs .intro p — totally different things! p.intro = a paragraph WITH class intro. .intro p = a paragraph INSIDE something with class intro.
Given this HTML: <div><span><p>Hello</p></span></div>, which selector will style the <p>?
div p — the descendant selector matches <p> at any depth inside <div>. Option A fails because <p> is a grandchild (not direct child) of <div>. The child selector > only matches immediate children.What is the difference between p.intro and .intro p?
p.intro means "a <p> element that HAS class intro" (no space = same element). .intro p means "any <p> that is INSIDE an element with class intro" (space = descendant relationship). Completely different selections.Box Model
Why does the box model matter? Here is the single most important thing to understand about CSS layout: every single HTML element is a rectangular box. Not some elements. Not just divs. EVERY element — paragraphs, headings, images, links — they are all invisible boxes sitting on the page.
The box model describes the four layers that make up every one of these boxes. Think of it like a picture in a frame:
- Content — the picture itself (your text, image, or whatever the element displays)
- Padding — the matting around the picture (space between the picture and the frame). Same background color as the content.
- Border — the actual frame around the matting
- Margin — the wall space between this frame and the next frame hanging on the wall. Always transparent — you can never color a margin.
/*
┌──────────────── margin ────────────────┐
│ ┌──────────── border ────────────────┐ │
│ │ ┌────────── padding ────────────┐ │ │
│ │ │ ┌──────── content ─────────┐ │ │ │
│ │ │ │ │ │ │ │
│ │ │ └──────────────────────────┘ │ │ │
│ │ └───────────────────────────────┘ │ │
│ └────────────────────────────────────┘ │
└────────────────────────────────────────┘
*/
| Layer | What it does | Affected by background? |
|---|---|---|
| Content | The actual text/image | Yes |
| Padding | Space between content and border | Yes |
| Border | Edge around padding | Has own color |
| Margin | Space outside the border | No — always transparent |
width: 200px, you might think the element takes 200px on screen. WRONG. By default, width only sets the content area. Padding and border are ADDED on top.Default (content-box): Total width = width + padding-left + padding-right + border-left + border-right
If
width: 200px; padding: 20px; border: 5px → total = 200 + 40 + 10 = 250pxWith box-sizing: border-box: Total width = width (padding and border included inside)
Same values → total = 200px (content area shrinks to 150px to make room for padding and border)
This is why every modern CSS reset starts with
* { box-sizing: border-box; } — it makes width mean "total width" which is what your brain expects.
.box {
width: 200px;
padding: 20px;
border: 5px solid black;
margin: 10px;
}
/* Total width on screen: 200 + 20*2 + 5*2 = 250px */
/* Total space occupied: 250 + 10*2 = 270px */
/* Fix: use border-box so width means total width */
* { box-sizing: border-box; }
margin-bottom: 30px and element B has margin-top: 20px, the gap between them is 30px (not 50px) — the larger margin absorbs the smaller one. This ONLY happens vertically. Horizontal margins never collapse.
What is the total width of an element with: width: 300px; padding: 20px; border: 5px solid; margin: 10px;?
width only sets the content area.Two adjacent elements: first has margin-bottom: 40px, second has margin-top: 25px. What is the gap between them?
Specificity & Cascade
Why does specificity exist? Imagine you have 3 bosses. Boss A says "paint the wall blue." Boss B says "paint the wall red." Boss C says "paint the wall green." Whose instruction do you follow? You need a pecking order — a way to decide who wins.
That is exactly what specificity is. When multiple CSS rules target the same element with conflicting styles, the browser needs a tiebreaker. Specificity is a scoring system — each selector gets a score, and the highest score wins.
Think of it as a 4-digit address system: Inline, IDs, Classes, Elements — each column is 10x more powerful than the one to its right. One ID beats a hundred classes. One inline style beats everything.
| Selector type | Specificity value | Example | Think of it as... |
|---|---|---|---|
| Inline style | 1,0,0,0 | style="color:red" | The CEO's direct order |
| ID | 0,1,0,0 | #nav | A department head |
| Class / attribute / pseudo-class | 0,0,1,0 | .menu, [type], :hover | A team lead |
| Element / pseudo-element | 0,0,0,1 | div, ::before | An intern |
Universal * | 0,0,0,0 | * | Background noise — no weight at all |
p → 0,0,0,1 (one element).intro → 0,0,1,0 (one class)p.intro → 0,0,1,1 (one class + one element)#main → 0,1,0,0 (one ID)#main p.intro → 0,1,1,1 (one ID + one class + one element p... wait, two elements? No — #main is an ID, not an element. Count carefully!)The higher number ALWAYS wins. 0,1,0,0 beats 0,0,99,99 — one ID outranks any number of classes.
/* Specificity examples — count IDs, classes, elements */ p { } /* 0,0,0,1 */ .intro { } /* 0,0,1,0 */ p.intro { } /* 0,0,1,1 */ #main { } /* 0,1,0,0 */ #main p.intro { } /* 0,1,1,1 */ /* #main p.intro WINS over .intro because 0,1,1,1 > 0,0,1,0 */
!important overrides everything (but avoid using it — it is the nuclear option and the exam loves to test edge cases with it).
Which selector has the highest specificity?
div#nav ul.menu li — specificity is 0,1,1,3 (1 ID + 1 class + 3 elements). A is 0,1,1,1. C is 0,0,0,4. D is 0,0,3,0. Remember: one ID (0,1,0,0) beats any number of classes or elements.Two rules target the same element: .header { color: blue; } appears on line 10, and .header { color: red; } appears on line 50. What color is the text?
.header = 0,0,1,0), the cascade rule kicks in: the one that appears LATER in the stylesheet wins. This is the "C" in CSS — Cascading.Display & Position
Display property
Why does display exist? Every HTML element has a default way it behaves in the page flow. Some elements are like bricks in a wall — they stack vertically and take up the full width (block elements). Others are like words in a sentence — they sit next to each other and only take the space they need (inline elements). The display property lets you change this fundamental behavior.
<div>, <p>, or <h1> is like a brick — it takes the entire row and the next element starts below it.Inline elements = words in a sentence. A
<span>, <a>, or <strong> sits right next to its neighbors. But here is the catch — you CANNOT set width or height on inline elements, just like you cannot make a word in a sentence taller without changing the whole line.Inline-block = the best of both worlds. Sits next to its neighbors like an inline element, BUT you CAN set width and height. Think of it as a picture in a sentence — it flows with the text but has its own dimensions.
| Value | Behavior | Examples |
|---|---|---|
block | Takes full width, starts on new line | div, p, h1–h6, section |
inline | Only takes needed width, no line break. Cannot set width/height | span, a, strong, em |
inline-block | Inline flow but can set width/height | img, button, input |
none | Element is removed from flow entirely | Hidden elements |
flex | Flex container — children become flex items | Layouts |
grid | Grid container — 2D layouts | Complex layouts |
display: none — the element LEAVES the room. It is completely gone from the layout. Other elements move up to fill its space.visibility: hidden — the element puts on an invisibility cloak. You cannot see it, but it is still standing there taking up space. Other elements do NOT move.
Position property
Why does position exist? Normal HTML flows like a Word document — elements stack top to bottom, left to right. But what if you want a chat button floating in the bottom-right corner? Or a navbar that stays at the top when you scroll? Or a tooltip that appears right next to the element you hover? Normal flow cannot do that. The position property lets you break out of normal flow and place elements exactly where you want.
relative = a student who leans 20px to the left from their assigned seat. Their seat (original space) is still reserved — nobody else can sit there. They just appear shifted.
absolute = a student who stands up and goes to stand at a specific spot in the room. Their seat is now empty (other students can fill in). Where they stand depends on the room boundaries (or the nearest "positioned" parent).
fixed = a security camera mounted on the wall. No matter how everyone moves around (scrolls), the camera stays in the exact same spot on screen.
sticky = a student who sits normally until the teacher scrolls past them, then they stick to the top of the whiteboard. Section headers on long pages use this.
| Value | Behavior | Relative to |
|---|---|---|
static | Default. Normal document flow | N/A (ignores top/left/right/bottom) |
relative | Offset from its normal position. Still takes original space | Itself |
absolute | Removed from flow. Positioned relative to nearest positioned ancestor | Nearest ancestor with position != static |
fixed | Removed from flow. Stays in place when scrolling | Viewport |
sticky | Acts relative until scroll threshold, then acts fixed | Scroll container |
/* Relative — nudge from normal position, original space preserved */ .box1 { position: relative; top: 20px; /* moves 20px DOWN from where it would normally be */ left: 10px; /* moves 10px RIGHT */ } /* Absolute — ripped out of flow, positioned inside nearest positioned parent */ .parent { position: relative; } /* parent MUST be positioned! */ .child { position: absolute; top: 0; right: 0; /* top-right corner of .parent */ } /* Fixed — stays on screen even when scrolling */ .navbar { position: fixed; top: 0; width: 100%; }
absolute element looks UP the DOM tree for the nearest ancestor that has position: relative, absolute, or fixed. If none found, it positions relative to <html> (the viewport). This is why you almost always see position: relative on a parent when using position: absolute on a child — the parent becomes the reference point.
What is the difference between display: none and visibility: hidden?
display: none removes the element completely — it takes no space, as if it was never there. visibility: hidden makes it invisible but it still occupies its space in the layout. Think: leaving the room vs wearing an invisibility cloak.What does position: absolute do?
static. If no positioned ancestor exists, it uses the document body. Remember: relative = nudge from where you were; absolute = teleport to exact coordinates inside your parent.Flexbox
Why does Flexbox exist? Before Flexbox, centering a div vertically was a legendary CSS struggle. Developers used hacks with tables, floats, and negative margins just to put something in the middle of the page. Flexbox was invented to solve this: it gives you a simple, powerful way to arrange elements in a row or column, with total control over spacing and alignment.
The analogy: Think of a flex container as a shelf. The items on the shelf are flex items. You can decide:
- Should items go left-to-right (row) or top-to-bottom (column)?
- Should items bunch up at the start, spread out evenly, or center themselves?
- Should items stretch to fill the shelf height, or stay their natural size?
- If there are too many items, should they wrap to a new row?
All you do is put display: flex on the parent — the children automatically become flex items.
Container properties (parent)
| Property | Values | Default |
|---|---|---|
flex-direction | row | row-reverse | column | column-reverse | row |
justify-content | flex-start | flex-end | center | space-between | space-around | space-evenly | flex-start |
align-items | flex-start | flex-end | center | stretch | baseline | stretch |
flex-wrap | nowrap | wrap | wrap-reverse | nowrap |
gap | Any length value | 0 |
row, vertical in column). Cross axis = the perpendicular direction.justify-content controls the main axis (think: "justify" like justifying text — left, center, right).align-items controls the cross axis (think: "align" items vertically).If you flip
flex-direction to column, these axes SWAP — justify-content now controls vertical, align-items controls horizontal. This confuses many people on the exam.
flex-start: [A B C ] — items packed to the startflex-end: [ A B C] — items packed to the endcenter: [ A B C ] — items centeredspace-between: [A B C] — first and last touch edges, equal space betweenspace-around: [ A B C ] — equal space around each item (edges get half)space-evenly: [ A B C ] — perfectly equal gaps everywhere
Item properties (children)
| Property | What it does |
|---|---|
flex-grow | How much the item should grow to fill extra space (default: 0 = don't grow) |
flex-shrink | How much the item should shrink when space is tight (default: 1 = shrink equally) |
flex-basis | Starting size before growing/shrinking (default: auto = use the element's natural size) |
align-self | Override align-items for this one item only |
order | Visual order (default: 0, lower = first) |
/* Center something perfectly — the #1 reason Flexbox was invented */ .container { display: flex; justify-content: center; /* horizontal center (main axis) */ align-items: center; /* vertical center (cross axis) */ height: 100vh; /* need a height, or nothing to center against */ } /* Navigation bar — logo on left, links on right */ .nav { display: flex; justify-content: space-between; /* pushes first and last item to edges */ align-items: center; } /* Flex shorthand: flex-grow flex-shrink flex-basis */ .item { flex: 1; } /* same as flex: 1 1 0% — all items grow equally */ .item { flex: 0 0 200px; } /* fixed 200px, don't grow, don't shrink */
Which CSS property is used to align items along the main axis in a flex container?
justify-content — it aligns items along the main axis. align-items aligns along the cross axis. Remember: "justify" = main axis, "align" = cross axis.You have a flex container with flex-direction: column. Which property controls horizontal alignment of the items?
align-items. When flex-direction is column, the main axis becomes vertical and the cross axis becomes horizontal. Since align-items controls the cross axis, it now controls horizontal alignment. This axis-swap is a common exam trap.CSS Grid
Why does Grid exist if we have Flexbox? Flexbox is one-dimensional — it handles a row OR a column. Grid is two-dimensional — it handles rows AND columns at the same time. Think of Flexbox as arranging items on a clothesline (one direction). Grid is like arranging items on a chessboard (rows and columns simultaneously).
Grid is less likely on the FA exam but good to know the basics. Use Grid when you need a page-level layout with defined rows and columns.
.container {
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* 3 columns: 25% 50% 25% */
grid-template-rows: auto;
gap: 16px; /* space between grid cells */
}
/* Span multiple columns/rows */
.wide {
grid-column: 1 / 3; /* spans column line 1 to line 3 (= 2 columns) */
}
/* Repeat shorthand */
.container {
grid-template-columns: repeat(3, 1fr); /* 3 equal columns */
}
Grid: when you need a full page layout with defined rows AND columns (dashboards, galleries, complex layouts).
In practice, you often use Grid for the overall page structure and Flexbox for individual components within it.
Units — px, em, rem, %
Why are there so many unit types? Imagine building with only centimeters — it works for a bookshelf but not for a building that needs to scale. CSS has different units because different situations need different kinds of measurement:
- Fixed sizes (borders, shadows) →
px - Scalable text that respects user preferences →
rem - Relative sizing based on parent →
em,% - Viewport-based layouts →
vw,vh
| Unit | Type | Relative to | Best for |
|---|---|---|---|
px | Absolute | Screen pixels (fixed) | Borders, shadows, small fixed sizes |
em | Relative | Parent element's font-size | Component-level scaling (padding relative to text size) |
rem | Relative | Root (<html>) font-size (default 16px) | Global consistent sizing (most common for font sizes) |
% | Relative | Parent element's size | Fluid widths (containers, images) |
vw | Relative | 1% of viewport width | Full-screen layouts, hero sections |
vh | Relative | 1% of viewport height | Full-screen layouts, hero sections |
/* If html font-size is 16px (browser default): */ 1rem = 16px 2rem = 32px 0.5rem = 8px /* em depends on parent — this is where it gets tricky: */ .parent { font-size: 20px; } .child { font-size: 1.5em; } /* = 30px (20 × 1.5) */
em is relative to the parent's font-size. So if you nest elements with em sizes, they compound like interest. A parent at 2em with a child at 2em = the child is 4x the root size. And the grandchild at 2em = 8x. This is why rem (root em) was invented — it ALWAYS references the root element, no matter how deeply nested. Use rem for font sizes to stay sane.
If root font-size is 16px, what is 2.5rem in pixels?
rem is always relative to root font-size. 2.5 x 16px = 40px. It does not matter how many elements this is nested inside — rem always looks at the root.Colors & Backgrounds
Why so many color formats? Different formats exist for different use cases: named colors are readable, hex is compact, RGB gives precise control, and RGBA adds transparency. For the exam, know all formats and especially understand opacity vs rgba.
| Format | Example | Notes |
|---|---|---|
| Named | color: red; | ~147 named colors |
| Hex | color: #ff5733; | 6-digit or 3-digit shorthand (#f00 = #ff0000) |
| RGB | color: rgb(255, 87, 51); | 0–255 per channel |
| RGBA | color: rgba(255, 87, 51, 0.5); | Alpha 0 (transparent) to 1 (opaque) |
| HSL | color: hsl(14, 100%, 60%); | Hue, Saturation, Lightness |
/* Background shorthand */ .hero { background: #1a1a2e url("bg.jpg") no-repeat center/cover; } /* Gradient */ .banner { background: linear-gradient(to right, #e94560, #0f3460); } /* opacity — affects the ENTIRE element including ALL children */ .faded { opacity: 0.5; } /* Use rgba for transparent backgrounds WITHOUT affecting children */ .overlay { background: rgba(0, 0, 0, 0.5); }
opacity: 0.5 makes the ENTIRE element (and all its children — text, images, everything) 50% transparent. There is no way to undo this on children.background: rgba(0,0,0,0.5) only makes the background transparent — children remain fully visible. Use rgba when you want a semi-transparent background with readable text on top.
Text & Fonts
Text styling controls how your content reads. The key insight: font-* properties control the typeface itself (family, size, weight), while text-* properties control how the text is displayed (alignment, decoration, transformation).
| Property | Values |
|---|---|
font-family | 'Arial', sans-serif — fallback chain (browser tries each until one works) |
font-size | 16px, 1rem, 1.2em |
font-weight | normal (400), bold (700), 100–900 |
font-style | normal, italic, oblique |
text-align | left, center, right, justify |
text-decoration | none, underline, line-through, overline |
text-transform | uppercase, lowercase, capitalize |
line-height | 1.5 (unitless multiplier preferred — it scales with font-size) |
letter-spacing | 2px, 0.1em |
word-spacing | 4px |
/* Font shorthand: style weight size/line-height family */ p { font: italic 700 16px/1.5 'Arial', sans-serif; } /* Remove underline from links */ a { text-decoration: none; } /* Ellipsis for overflow text — all 3 properties are required */ .truncate { white-space: nowrap; /* prevent text wrapping */ overflow: hidden; /* hide the overflow */ text-overflow: ellipsis; /* show "..." at the cut point */ }
Pseudo-classes & Pseudo-elements
Why do these exist? Sometimes you want to style an element based on its state (is the mouse hovering over it? is it the first item in a list?) or a part of an element (just the first letter, or insert an icon before it). You cannot create a CSS class for "the paragraph the mouse is currently hovering over" because that changes every second. Pseudo-classes and pseudo-elements solve this.
:) = styles based on STATE or POSITION. "Is this link being hovered? Is this the 3rd child?" These select whole elements in a particular condition.Pseudo-element (double colon
::) = styles a PART of an element or creates a virtual element. "Style just the first letter. Insert content before this element." These target pieces of an element.Memory trick: one colon = one whole element in a state. Two colons = part of an element.
Pseudo-classes (single colon — state/position)
| Pseudo-class | Selects |
|---|---|
:hover | When mouse is over the element |
:active | When element is being clicked (mouse button held down) |
:focus | When element has keyboard focus (tabbed to or clicked on an input) |
:visited | Links that have been visited |
:first-child | First child of its parent |
:last-child | Last child of its parent |
:nth-child(n) | nth child — :nth-child(odd), :nth-child(2n), :nth-child(3) |
:not(selector) | Elements that don't match — :not(.active) |
Pseudo-elements (double colon — parts of element)
| Pseudo-element | What it does |
|---|---|
::before | Inserts virtual content before element's content |
::after | Inserts virtual content after element's content |
::first-line | Styles the first line of text |
::first-letter | Styles the first letter (drop caps) |
::placeholder | Styles input placeholder text |
/* Link states — order matters! (LoVe HAte) */ a:link { color: blue; } a:visited { color: purple; } a:hover { color: red; } a:active { color: orange; } /* Zebra-striped table rows */ tr:nth-child(even) { background: #f4f4f4; } /* ::before and ::after REQUIRE the content property — without it, nothing appears */ .required::after { content: " *"; color: red; }
:hover comes before :visited, visited links will not show the hover color.
Which pseudo-element requires the content property to work?
::before (and ::after) require the content property — without it, they will not render at all. Even if you want nothing visible, you need content: "". Note: :hover is a pseudo-CLASS (single colon), not a pseudo-element.Transitions & Animations
Why do transitions exist? Without transitions, CSS changes happen instantly — a button goes from blue to red in 0 milliseconds. That feels jarring and cheap. Transitions add smooth, gradual changes that make your UI feel polished and professional. Think of it like a dimmer switch vs a light switch — both control brightness, but the dimmer does it smoothly.
Transition vs Animation: A transition is a simple A-to-B change triggered by a state change (like hover). An animation can have multiple steps (A → B → C → D), can loop, and can run automatically without any trigger.
/* Transition — smooth change when state changes (e.g., hover) */ .btn { background: #e94560; transition: background 0.3s ease, transform 0.2s; } .btn:hover { background: #d63850; transform: scale(1.05); } /* Transition shorthand: property duration timing-function delay */ .box { transition: all 0.3s ease-in-out; } /* Animation with @keyframes — multiple steps, can loop */ @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } .element { animation: fadeIn 1s ease-in forwards; /* forwards = stay at the final state after animation ends */ }
| Timing function | Behavior |
|---|---|
ease | Slow start, fast middle, slow end (default — most natural) |
linear | Constant speed (robotic, use for loading bars) |
ease-in | Slow start, fast end (like dropping a ball) |
ease-out | Fast start, slow end (like a car braking) |
ease-in-out | Slow start and slow end (most elegant) |
transition property on the base state (not the hover state). This way, the transition plays both when hovering IN and OUT. If you put it only on :hover, the transition will play when hovering in but snap back instantly when hovering out.
Responsive Design
Why does responsive design matter? People browse on phones, tablets, laptops, and 4K monitors. A design that looks perfect on a laptop will be unreadable on a phone if it is not responsive. Media queries let you write different CSS rules for different screen sizes — like having different outfits for different weather.
There are two approaches:
- Mobile-first (recommended): Write base CSS for mobile, then use
min-widthto add styles for larger screens. You are "building up." - Desktop-first: Write base CSS for desktop, then use
max-widthto override for smaller screens. You are "scaling down."
/* Mobile-first approach — start small, scale up */ .container { width: 100%; } /* base: full width on mobile */ @media (min-width: 768px) { /* tablets and up */ .container { width: 750px; } } @media (min-width: 1024px) { /* desktops and up */ .container { width: 960px; } } /* Desktop-first (max-width) — hide sidebar on mobile */ @media (max-width: 600px) { .sidebar { display: none; } .main { margin-left: 0; } }
<head>, media queries will NOT work on mobile devices. The browser will render the page at desktop width and zoom out, making everything tiny:<meta name="viewport" content="width=device-width, initial-scale=1.0">
In a mobile-first approach, which media query do you use to add styles for larger screens?
min-width means "apply these styles when the screen is AT LEAST this wide." In mobile-first, you write base styles for small screens, then use min-width breakpoints to progressively add styles for larger screens. max-width is for desktop-first (scaling down).Shorthand Properties
Shorthand properties let you set multiple related properties in one line. Less typing, cleaner code. But you need to remember the order of values.
/* Margin / Padding shorthand */ margin: 10px; /* all 4 sides = 10px */ margin: 10px 20px; /* top/bottom = 10px, left/right = 20px */ margin: 10px 20px 30px; /* top = 10, left/right = 20, bottom = 30 */ margin: 10px 20px 30px 40px; /* top right bottom left (clockwise) */ /* Border shorthand */ border: 2px solid #333; /* width style color */ /* Background shorthand */ background: #fff url("img.png") no-repeat center/cover; /* Font shorthand */ font: italic bold 16px/1.5 Arial, sans-serif;
What does margin: 10px 20px 30px; mean?
More Practice Questions
An element has width: 200px; box-sizing: border-box; padding: 20px; border: 5px solid;. What is the total width on screen?
box-sizing: border-box, the width includes padding and border. The content area shrinks to 150px (200 - 20*2 - 5*2) to accommodate, but the total on-screen width remains 200px.What is the specificity of the selector div.container > ul li a:hover?
.container + :hover = 2. Elements = div + ul + li + a = 4. The > combinator has no specificity value.You want a transparent background on a div WITHOUT making its child text transparent. Which approach works?
rgba makes only the background transparent. opacity would make the entire element AND all children transparent — you cannot override it on children. This is one of the most practical CSS distinctions to understand.A flex container has flex-direction: row and justify-content: space-between. Where do the items appear?
space-between places the first item flush to the start edge and the last item flush to the end edge, distributing remaining space equally between items. No space before the first or after the last.An element has position: relative; top: 20px;. What happens?
position: relative, the element shifts 20px down from where it WOULD have been, but its original space in the document flow is preserved. Other elements do not move to fill the gap — they act as if the element is still in its original position.