Dashboard

Audio Settings

1.0x
Status: Ready to play
System Voice Guide: To add Male/Veena/Ravi Indian voices on Windows, go to Settings > Time & Language > Speech and install the English (India) language pack.
Phase 1 · Core Frontend Engineering
essay 1.2 of 63  ·  series: faang roadmap

CSS: Making
Things Look Good

Your HTML skeleton gets a body. CSS is what transforms a plain document into something people actually want to look at. This essay changes how you see every website forever.

Phase 1 — Style & Presentation
Read Time ~40 minutes
Prerequisites Essay 1.1 — HTML complete
Deliverables Styled portfolio & responsive landing page
↓   scroll to begin
01

CSS is not decoration — it is communication

Every visual decision a website makes — the colour of a button, the size of a heading, the space between lines, the way a card lifts when you hover it — is a CSS decision. CSS is how the web communicates trust, urgency, hierarchy, personality, and professionalism. Writing good CSS is not an artistic skill. It is an engineering skill.

CSS stands for Cascading Style Sheets. The name reveals everything about how it works. Style Sheets — files that describe how elements should look. Cascading — the system by which multiple rules are applied in priority order, with more specific rules overriding less specific ones. Understanding the cascade is the difference between CSS that works and CSS that confuses you for years.

CSS works through a simple mechanism: you write rules. A rule says: "find these elements (the selector), and apply these visual properties (the declarations) to them." That is all CSS is. The complexity comes from selectors being powerful, properties being numerous, and the cascade determining which rule wins when multiple rules target the same element.

Why CSS Matters for FAANG

Your projects will be judged by how they look before anyone reads the code. A recruiter opening your portfolio project has a visual first impression within 50ms. Google's PageSpeed Insights and Core Web Vitals — which directly affect search rankings — measure CSS rendering performance. Every FAANG company has dedicated CSS architecture at scale. Learning CSS deeply now means your projects look professional, which gets your GitHub clicked, which gets you interviews.

This essay covers the box model (the single most important CSS concept), selectors and specificity, the cascade, colours and typography, responsive design with media queries, transitions and pseudo-classes, and CSS variables. You will apply all of it to your portfolio project from essay 1.1 — watching it transform from a plain document into a professional page.

02

Phase 1 building block two

1.2 — CSS (Here)
Phase 2: React

CSS from this essay is the foundation for essay 1.3 (Flexbox and Grid for layouts), which is itself the foundation for essay 2.1 (React components — which generate CSS-styled HTML). The concepts you learn here — box model, specificity, the cascade, CSS variables — are used identically in every framework, every component library, and every design system you will encounter for the rest of your career.

Project Connection

The portfolio you style this week will be expanded in every Phase 1 essay. By essay 1.7 (Local Storage), your portfolio will be complete, deployed, and live. CSS variables you define this week will persist through that entire build. The Job Board project (10.1) uses CSS Grid for its layout — built on what you learn here. Build the CSS habit correctly now.

03

Three analogies — simple to deep

CSS is deceptively simple to start and genuinely deep to master. These three mental models take you from understanding the basics to thinking about CSS the way senior engineers do.

Level 1 — The Tailor

You built a mannequin in essay 1.1 (the HTML skeleton). CSS is the tailor. The tailor looks at the mannequin and applies: fabric colour (background-color), fit (width, height, padding), spacing between items (margin), typography (font-family, font-size), and finishing details (border, border-radius, box-shadow). Just as a tailor works with measurements and proportions, CSS works with sizes, spacing, and visual relationships.

Level 2 — The Priority System

Imagine three people all giving instructions to the same employee: the CEO, the manager, and a colleague. When instructions conflict, the CEO always wins, then the manager, then the colleague. CSS works identically. The cascade has a priority order: inline styles > ID selectors > class selectors > tag selectors. When two rules conflict, the more specific one wins. This system is called specificity — and it is the number one source of CSS confusion for beginners who don't understand it.

Level 3 — Everything is a Box

This is how senior engineers think about CSS. Every single element on every webpage is a rectangular box. Text, images, buttons, divs, paragraphs — all boxes. Each box has four layers: the content (the actual text or image), padding (space between the content and the border), border (the edge of the element), and margin (space outside the border, separating this element from others). This is the CSS Box Model — and understanding it fully explains why spacing behaves the way it does, why elements overlap, and why percentage widths sometimes work unexpectedly.

The 15-year-old version

CSS is like the settings panel for your HTML. HTML said "this is a heading." CSS says "make that heading dark blue, 36px big, bold, with 20px of space above it." You write the instruction once (in a .css file), and every heading on every page follows it automatically. Change one line of CSS and you change every heading everywhere.

04

Interactive Box Model + Live CSS Playground

The Box Model is the single most important CSS concept to internalise. Use the sliders to change each layer and watch the diagram and CSS update in real time.

Interactive Box Model Adjust sliders to see each layer
Content
Margin20px
Border4px
Padding16px
Content Width80px

Now write CSS and see it render live. Pick a preset or write your own:

Live CSS Playground
Edit the CSS on the left — the preview updates instantly. The HTML is fixed; only CSS changes.

Now try the specificity calculator — paste any CSS selector and see its exact score:

Specificity Calculator — type a CSS selector
0
Inline
0
IDs
0
Classes
0
Tags
Type a selector above to calculate its specificity score.
05

CSS from first principles — everything that matters

CSS has hundreds of properties. You do not need to memorise them all. You need to understand the core concepts deeply — box model, cascade, specificity, layout, responsive design — and then look up specific properties as you need them.

How CSS is Applied — The Three Methods

There are three ways to apply CSS to HTML, listed from worst to best practice:

1. Inline styles (worst) — CSS written directly in the HTML element's style attribute: <p style="color: red;">. Hard to maintain, mixes structure with presentation, impossible to reuse, highest specificity so it overrides everything.

2. Internal stylesheet (sometimes useful) — CSS written in a <style> tag inside <head>. Good for single-page demos. Not ideal for real projects because styles cannot be shared between HTML files.

3. External stylesheet (correct) — CSS in a separate .css file, linked from HTML with <link rel="stylesheet" href="style.css">. This is how real projects work. One CSS file can style all pages of a website. Change one file; everything updates.

Selectors — Finding the Elements You Want

Selector Type
Example
What it selects
Tag
p { }
All <p> elements on the page. Lowest specificity.
Class
.card { }
All elements with class="card". Medium specificity. Most common.
ID
#nav { }
The element with id="nav". High specificity. Use sparingly.
Descendant
.card p { }
All <p> elements anywhere inside a .card element.
Direct Child
.nav > a { }
Only <a> elements that are direct children of .nav (not deeper).
Adjacent Sibling
h2 + p { }
The first <p> immediately following an <h2>.
Attribute
input[type="email"]
All inputs with type="email". Useful for form styling.
Pseudo-class
a:hover { }
An <a> when the mouse is over it. Other examples: :focus, :first-child, :nth-child(2).
Pseudo-element
p::first-line { }
The first line of every <p>. Others: ::before, ::after, ::placeholder.
Universal
* { }
Every single element. Used in CSS resets. Zero specificity.

Specificity — Why Your CSS Sometimes Gets Overridden

When two rules target the same element and set the same property, the browser must decide which one wins. The answer is specificity — a scoring system. Each selector type contributes to a score written as three numbers: IDs — Classes — Tags.

A tag selector p scores 0-0-1. A class selector .card scores 0-1-0. An ID selector #nav scores 1-0-0. Combined selectors add: #nav .link = 1 ID + 1 class = 1-1-0. Higher score always wins. If scores are equal, the rule that appears later in the stylesheet wins — this is the cascade.

Never Use !important

!important overrides all specificity calculations. It is a shortcut that causes long-term pain. If you are reaching for !important, you have a specificity problem to fix, not override. The only legitimate use is overriding third-party library styles you cannot change. In your own code: never.

The Box Model — Master This or Struggle Forever

Every element is a box with four layers. The total rendered width of an element by default is: content width + left padding + right padding + left border + right border + left margin + right margin. This surprises beginners who set width: 200px and get something wider.

The fix: box-sizing: border-box. With this declaration, the width property includes padding and border — so width: 200px means the element is exactly 200px wide, regardless of padding and border. Always apply this globally:

style.css — Always start with this CSS resetcss
/* The universal reset — every professional CSS file starts with this */
*,
*::before,
*::after {
  box-sizing: border-box;  /* width includes padding and border */
  margin: 0;               /* remove browser default margins */
  padding: 0;              /* remove browser default padding */
}

/* Base body styles */
body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 16px;        /* base size — all rem values are relative to this */
  line-height: 1.6;       /* comfortable reading line height */
  color: #1a1a2e;         /* near-black text — not pure black (too harsh) */
  background-color: #ffffff;
}

/* Images responsive by default */
img {
  max-width: 100%;         /* images never overflow their container */
  display: block;         /* removes the small gap below inline images */
}
      

CSS Variables — Write Once, Change Everywhere

CSS custom properties (variables) let you define a value once and reuse it everywhere. When you need to change your brand colour, you change it in one place instead of hunting through your entire stylesheet. This is how every professional design system works.

CSS Variables — Your design system foundationcss
/* :root targets the html element — the highest scope */
/* Variables defined here are available everywhere in the document */
:root {
  /* Colours */
  --colour-primary: #7c3aed;     /* your main brand colour */
  --colour-primary-dark: #5b21b6;
  --colour-text: #1a1a2e;
  --colour-text-muted: #6b7280;
  --colour-bg: #ffffff;
  --colour-surface: #f9fafb;
  --colour-border: #e5e7eb;

  /* Typography */
  --font-size-sm: 0.875rem;     /* 14px */
  --font-size-base: 1rem;       /* 16px */
  --font-size-lg: 1.125rem;    /* 18px */
  --font-size-xl: 1.25rem;     /* 20px */
  --font-size-2xl: 1.5rem;     /* 24px */
  --font-size-4xl: 2.25rem;    /* 36px */

  /* Spacing scale */
  --space-1: 0.25rem;          /* 4px */
  --space-2: 0.5rem;           /* 8px */
  --space-4: 1rem;             /* 16px */
  --space-8: 2rem;             /* 32px */
  --space-16: 4rem;            /* 64px */

  /* Border radius */
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 16px;
  --radius-full: 9999px;      /* pill shape */

  /* Shadows */
  --shadow-sm: 0 1px 3px rgba(0,0,0,0.1);
  --shadow-md: 0 4px 12px rgba(0,0,0,0.12);
  --shadow-lg: 0 8px 30px rgba(0,0,0,0.15);
}

/* Using variables: */
.button {
  background-color: var(--colour-primary);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-4);
  font-size: var(--font-size-base);
  box-shadow: var(--shadow-sm);
}

/* Dark mode — just swap variable values */
@media (prefers-color-scheme: dark) {
  :root {
    --colour-bg: #0f172a;
    --colour-text: #e2e8f0;
    --colour-surface: #1e293b;
  }
  /* Every element using variables now has dark mode — no other changes needed */
}
      

Responsive Design — Making Pages Work on Every Screen

Responsive design means your layout adapts to different screen sizes. The core tool is media queries — CSS rules that only apply when the browser window is a certain width. The modern approach is mobile-first: write CSS for mobile screens by default, then add media queries to enhance the layout for larger screens.

Responsive design — mobile-first breakpointscss
/* Mobile first — default styles apply to mobile (smallest screens) */
.container {
  max-width: 1200px;
  margin: 0 auto;          /* centres the container */
  padding: 0 1rem;          /* side padding so content doesn't touch edges */
}

.projects-grid {
  display: grid;
  grid-template-columns: 1fr;   /* 1 column on mobile */
  gap: 1.5rem;
}

/* Tablet: screens 640px and wider */
@media (min-width: 640px) {
  .projects-grid {
    grid-template-columns: repeat(2, 1fr);  /* 2 columns */
  }
}

/* Desktop: screens 1024px and wider */
@media (min-width: 1024px) {
  .projects-grid {
    grid-template-columns: repeat(3, 1fr);  /* 3 columns */
  }

  .container {
    padding: 0 2rem;
  }
}

/* Common breakpoints used in the industry: */
/* sm: 640px, md: 768px, lg: 1024px, xl: 1280px, 2xl: 1536px */
/* (These match Tailwind CSS's defaults — you'll use Tailwind in Phase 2+) */
      

Transitions and Hover States — The Polish That Matters

Transitions make state changes smooth instead of instant. A button that changes colour on hover instantly feels cheap. The same button that transitions over 200ms feels professional. This is a small detail that enormously affects perceived quality.

Transitions — the detail that makes things feel polishedcss
.btn {
  background-color: var(--colour-primary);
  color: white;
  padding: 0.75rem 1.5rem;
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;

  /* transition: property duration easing */
  /* 'all' means every animatable property transitions */
  /* 0.2s is fast enough to feel snappy, slow enough to be visible */
  transition: all 0.2s ease;
}

.btn:hover {
  background-color: var(--colour-primary-dark);
  transform: translateY(-2px);    /* subtle lift effect */
  box-shadow: var(--shadow-md);
}

.btn:active {
  transform: translateY(0);        /* press back down on click */
  box-shadow: var(--shadow-sm);
}

/* Card hover: subtle lift */
.card {
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-lg);
  padding: var(--space-8);
  transition: transform 0.2s, box-shadow 0.2s;
}

.card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lg);
}
      
06

Style your portfolio — the complete CSS file

Create style.css in your portfolio folder and link it from index.html. Build this file section by section, understanding every property before you write it.

First, link the stylesheet. In your index.html <head>, add:

index.html — Link your stylesheethtml
<!-- Add this inside <head>, after the meta tags -->
<link rel="stylesheet" href="css/style.css">

<!-- Import Google Fonts (optional but recommended) -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap" rel="stylesheet">
      

Now build the complete CSS file. Every section is explained:

css/style.css — Complete portfolio stylesheetcss
/* ═══════════════════════════════════════
   SECTION 1 — DESIGN TOKENS (variables)
   Change these to change your entire site
═══════════════════════════════════════ */
:root {
  --primary: #7c3aed;
  --primary-dark: #5b21b6;
  --text: #111827;
  --text-muted: #6b7280;
  --bg: #ffffff;
  --surface: #f3f4f6;
  --border: #e5e7eb;
  --font: 'Inter', -apple-system, sans-serif;
  --radius: 12px;
  --shadow: 0 4px 20px rgba(0,0,0,0.08);
  --max-width: 1100px;
}

/* ═══════════════════════════════════════
   SECTION 2 — RESET
═══════════════════════════════════════ */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }

/* ═══════════════════════════════════════
   SECTION 3 — BASE TYPOGRAPHY
═══════════════════════════════════════ */
body {
  font-family: var(--font);
  font-size: 1rem;
  line-height: 1.7;
  color: var(--text);
  background: var(--bg);
}

h1, h2, h3, h4 { line-height: 1.2; font-weight: 700; color: var(--text); }
h1 { font-size: clamp(2rem, 5vw, 3.5rem); }  /* clamp(min, preferred, max) */
h2 { font-size: clamp(1.5rem, 3vw, 2.25rem); }
h3 { font-size: 1.25rem; }
p { color: var(--text-muted); max-width: 65ch; } /* ch = width of '0'. 65ch is ideal line length */

/* ═══════════════════════════════════════
   SECTION 4 — LAYOUT UTILITIES
═══════════════════════════════════════ */
.container { max-width: var(--max-width); margin: 0 auto; padding: 0 1.5rem; }

/* ═══════════════════════════════════════
   SECTION 5 — NAVIGATION
═══════════════════════════════════════ */
header {
  position: sticky;          /* sticks to top when scrolling */
  top: 0;
  background: rgba(255,255,255,0.9);
  backdrop-filter: blur(10px); /* frosted glass effect */
  border-bottom: 1px solid var(--border);
  z-index: 100;
}
nav {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 1rem 1.5rem;
  display: flex;               /* Flexbox! Full coverage in essay 1.3 */
  align-items: center;
  gap: 2rem;
}
nav a {
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--text-muted);
  transition: color 0.2s;
}
nav a:hover { color: var(--primary); }

/* ═══════════════════════════════════════
   SECTION 6 — HERO (About Section)
═══════════════════════════════════════ */
#about {
  min-height: 90vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 6rem 1.5rem;
  max-width: var(--max-width);
  margin: 0 auto;
}
#about h1 span { color: var(--primary); }  /* highlight name */
#about p { font-size: 1.2rem; margin-top: 1rem; }

/* ═══════════════════════════════════════
   SECTION 7 — PROJECTS
═══════════════════════════════════════ */
#projects { padding: 5rem 1.5rem; max-width: var(--max-width); margin: 0 auto; }
#projects h2 { margin-bottom: 2.5rem; }

article {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 2rem;
  margin-bottom: 1.5rem;
  transition: transform 0.2s, box-shadow 0.2s;
}
article:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow);
}
article h3 { margin-bottom: 0.75rem; }
article p { margin-bottom: 1.25rem; }
article a {
  display: inline-block;
  padding: 0.5rem 1rem;
  border: 1px solid var(--primary);
  border-radius: 6px;
  color: var(--primary);
  font-size: 0.875rem;
  font-weight: 500;
  margin-right: 0.75rem;
  transition: all 0.2s;
}
article a:hover { background: var(--primary); color: white; }

/* ═══════════════════════════════════════
   SECTION 8 — CONTACT FORM
═══════════════════════════════════════ */
#contact { padding: 5rem 1.5rem; max-width: 600px; margin: 0 auto; }
label { display: block; font-size: 0.875rem; font-weight: 500; margin-bottom: 0.4rem; }
input, textarea, select {
  width: 100%;
  padding: 0.75rem 1rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-family: var(--font);
  font-size: 1rem;
  background: var(--bg);
  transition: border-color 0.2s, box-shadow 0.2s;
  margin-bottom: 1.25rem;
}
input:focus, textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(124,58,237,0.15); /* focus ring */
}
button[type="submit"] {
  width: 100%;
  padding: 0.875rem;
  background: var(--primary);
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s;
}
button[type="submit"]:hover { background: var(--primary-dark); transform: translateY(-1px); }

/* ═══════════════════════════════════════
   SECTION 9 — FOOTER
═══════════════════════════════════════ */
footer { text-align: center; padding: 3rem 1.5rem; border-top: 1px solid var(--border); color: var(--text-muted); font-size: 0.875rem; }

/* ═══════════════════════════════════════
   SECTION 10 — RESPONSIVE
═══════════════════════════════════════ */
@media (max-width: 640px) {
  nav { gap: 1rem; flex-wrap: wrap; }
  #about { padding: 4rem 1rem; }
}
      
What your portfolio looks like now

After adding this CSS, open your portfolio with Live Server. The transformation is dramatic — you now have a sticky navigation with frosted glass effect, a hero section centred on screen, styled project cards that lift on hover, a beautiful form with focus states, and a clean footer. This is a real portfolio page that can be shown to recruiters.

07

The CSS errors that trip up beginners for months

01
Not using box-sizing: border-box globally

Without box-sizing: border-box, adding padding to an element makes it wider than the specified width. A button with width: 200px; padding: 20px will actually render as 240px wide. This confuses every beginner who has ever tried to make two elements fit side by side. Always apply the universal reset at the top of every CSS file you write. Make it a reflex.

/* ALWAYS at the top of your CSS file */
*, *::before, *::after {
  box-sizing: border-box;
}
02
Using px for font sizes instead of rem

Using px for font sizes breaks accessibility. If a user has set their browser's default font size to 20px (because they have difficulty reading small text), px values ignore this — the text stays at whatever pixel size you coded. rem values are relative to the browser's base font size and respect user preferences. Use px for borders, shadows, and fixed-size elements. Use rem for all typography and spacing that should scale with user preferences. Standard: 1rem = 16px at default browser settings.

03
Overusing !important to fight specificity battles

When a CSS rule isn't applying, beginners add !important. Then they add it again for something else. Then they use it on three different rules targeting the same element and wonder why nothing works. !important breaks the cascade entirely. The correct solution is to understand specificity and write selectors with the appropriate level of specificity. If your rule isn't applying, open DevTools, click the element, look at the computed styles panel, and find which rule is winning and why.

/* WRONG: fighting specificity with !important */
.button { background: blue !important; }

/* CORRECT: understand why it's not applying and fix the selector */
.hero .button { background: blue; } /* more specific than just .button */
04
Writing desktop CSS first and breaking mobile

Most tutorials show desktop CSS first. But more than 60% of web traffic globally is on mobile devices. If you write desktop-first CSS and try to "undo" it for mobile, you spend more time overriding than building. The modern industry standard is mobile-first: write your default CSS for small screens (single column, large tap targets, simplified navigation), then use @media (min-width: ...) to enhance for larger screens. This produces cleaner, less redundant CSS.

05
Hardcoding colours and spacing values everywhere

Beginners write color: #7c3aed in forty different places. Then a designer says "make the brand colour a bit darker." Now they must find and change forty values. CSS variables (--primary: #7c3aed) mean you change it once. Professional codebases define all design tokens (colours, spacing, typography, border radii, shadows) as CSS variables in :root and never reference raw values anywhere else in the stylesheet. This is the exact approach used at every design-system-driven company.

08

CSS at Google, Meta, and Amazon — specifically

Google — Material Design System
Google's entire product suite (Gmail, Google Docs, Google Search, Maps, YouTube) uses Material Design — a comprehensive design system with documented CSS tokens, component libraries, spacing scales, and colour palettes. The CSS variables you are defining this week are structurally identical to Material Design tokens like --md-sys-color-primary. Google engineers do not write raw CSS properties for colour or spacing — they reference tokens, ensuring visual consistency across every product and every platform. Understanding design tokens at this level puts you ahead of most candidates who have only worked with ad-hoc styling.
Meta — CSS Modules and Atomic CSS
Meta's engineering blog has documented how they built Atomic CSS to handle Facebook's scale — millions of lines of CSS. Their approach: instead of writing component-level CSS, they generate single-purpose utility classes (like Tailwind CSS, which you will use in Phase 2). This dramatically reduces CSS file size because identical declarations (like font-weight: bold) are defined once as a class and reused, rather than repeated in every component. The concepts behind this approach — specificity, the cascade, reusable classes — are exactly what you are learning now.
Amazon — CSS Performance at Scale
Amazon's Core Web Vitals scores directly affect their search ranking and therefore their revenue. CSS has a direct impact on two critical metrics: Largest Contentful Paint (how fast the main content appears) and Cumulative Layout Shift (how much the page "jumps" as it loads). Amazon engineers use critical CSS inlining (placing above-the-fold CSS directly in the HTML to avoid a render-blocking network request) and lazy load non-critical styles. They measure every CSS change's impact on performance before deploying to production. This level of CSS awareness is what differentiates strong frontend engineers.
09

CSS questions that separate candidates at FAANG screens

Classic Frontend Question

"Explain the CSS Box Model. How does box-sizing: border-box change it?"

The Box Model defines how every HTML element occupies space. By default (content-box), an element's total width is: content width + left padding + right padding + left border + right border. If you set width: 200px; padding: 20px; border: 2px solid, the element actually renders 244px wide. With box-sizing: border-box, the width property includes padding and border — so the same element renders exactly 200px wide, with the content area shrinking to accommodate padding and border. Nearly every professional CSS codebase applies border-box globally via the universal selector reset.
Common Specificity Question

"If two CSS rules target the same element, which one wins? How is this calculated?"

The rule with higher specificity wins. Specificity is calculated as a three-number score: (IDs, Classes+Attributes+Pseudo-classes, Tags+Pseudo-elements). A rule with 1-0-0 beats 0-99-99 because IDs are compared first. If scores are equal, the rule appearing later in the stylesheet wins — this is the cascade. Inline styles override all stylesheet rules. !important overrides everything including inline styles, but creates maintenance problems and should be avoided. The practical implication: prefer class selectors for most styling, use IDs sparingly, never use !important in your own code.
System Design — CSS at Scale

"How would you organise CSS for a large application with 50+ components?"

Three approaches are used in industry: (1) CSS Modules — each component has its own .module.css file; class names are scoped locally so they cannot conflict. Used in React projects. (2) CSS-in-JS — styles written as JavaScript objects or tagged template literals, colocated with components. Used in styled-components, Emotion. (3) Utility-first CSS — a single global stylesheet of utility classes (like Tailwind CSS), which you will use in Phase 2. All three approaches solve the same problem: preventing specificity conflicts and style leakage between components as the codebase grows. For a portfolio project, a well-organised single CSS file with CSS variables is sufficient. For a production application, CSS Modules or Tailwind are the modern standard.
10

Answer out loud before revealing

What does "cascading" mean in Cascading Style Sheets, and what determines which rule wins when two rules conflict?

"Cascading" refers to the algorithm that determines which CSS rule applies when multiple rules target the same element and property. The cascade has three factors considered in order: (1) Origin — browser defaults are weakest, author styles (your CSS) are medium, user styles (browser overrides set by users) are strong, !important author styles are strongest. (2) Specificity — calculated as a three-number score based on selector composition. Higher score wins. (3) Source order — if two rules have identical specificity, the one appearing later in the stylesheet wins. Understanding the cascade means you can predict exactly which rule will apply without trial and error.

What is the difference between margin and padding? When would you use each?

Padding is the space between an element's content and its border — it is inside the element. The background colour fills the padding area. Clicking in the padding area fires click events on the element. Margin is the space outside the border — it pushes other elements away. Background does not extend into margins. The key practical rule: use padding to create breathing room inside a component (space between text and the card edge), use margin to create space between components (distance between two cards). Note: vertical margins between block elements collapse — if one element has margin-bottom: 20px and the next has margin-top: 30px, the space between them is 30px (the larger value), not 50px. This surprises many beginners.

What is a CSS variable and why is it better than writing a colour value directly in each rule?

A CSS variable (custom property) stores a value under a name defined with --variable-name in a :root block. It is referenced anywhere with var(--variable-name). The advantage over hardcoded values: when you need to change that value (say, your brand colour), you change it once in :root and it propagates everywhere automatically. With hardcoded values, you must find and change every instance — missing one causes inconsistency. CSS variables also enable theming: defining different variable values for dark mode or different brand themes with just a few overrides. They are also readable: var(--colour-primary) communicates intent better than #7c3aed.

What is the mobile-first approach to responsive design and why is it recommended over desktop-first?

Mobile-first means writing default CSS that works on small screens, then using @media (min-width: ...) queries to add complexity for larger screens. Desktop-first is the reverse — default CSS for large screens, then undoing or changing things for small screens. Mobile-first is recommended for three reasons: (1) Simplicity — mobile layouts are simpler (single column, no complex grids), so starting with the simpler case and adding complexity is easier than starting complex and removing it. (2) Performance — mobile devices are slower and on worse connections; CSS is parsed before rendering. Mobile-first ensures small devices get minimal CSS. (3) User reality — over 60% of global web traffic is mobile; it should be the primary design target, not an afterthought.

What does "position: sticky" do and how is it different from "position: fixed"?

position: fixed removes an element from the document flow and fixes it at a specified position on the screen — it stays in place as you scroll and can overlap other content. position: sticky is a hybrid: the element stays in the normal document flow but "sticks" to a specified position (e.g., top: 0) once scrolling would make it go past that point. The navigation bar in the portfolio CSS uses sticky — it scrolls with the page until it would disappear off the top, then sticks there. Unlike fixed, a sticky element cannot overlap content before it triggers the stick point, which makes it easier to use without calculating offsets for the content below it.

11

Your two-week CSS checklist

0 / 11 complete
Create css/style.css and link it to your portfolio index.html
Verify the link works by adding body { background: red; } — if the page goes red, the link is correct. Then remove that test.
Add the universal reset and CSS variables as the first thing in your stylesheet
*, *::before, *::after reset + :root variables. These are the foundation everything else builds on.
Style the navigation — make it sticky with frosted glass background
position: sticky, backdrop-filter: blur(), and border-bottom. Test by scrolling — it should stick.
Style the hero section so your name and title are prominent and centred vertically
Use min-height: 90vh and display: flex with justify-content: center + flex-direction: column.
Style your project cards with hover transitions — lift effect on hover
transition: transform 0.2s, box-shadow 0.2s on .card, then transform: translateY(-4px) on :hover.
Style the contact form — inputs with focus states that show a coloured ring
The :focus pseudo-class + box-shadow for a visible focus ring. This is also an accessibility requirement.
Add a responsive breakpoint — on mobile, navigation links wrap instead of overflow
@media (max-width: 640px) { nav { flex-wrap: wrap; } }. Test by dragging your browser window narrow.
Open DevTools, click each element, and read the computed styles + box model panel
Elements panel → Computed tab shows every CSS property applied. Box model diagram shows margin/padding/border visually.
Build a standalone product landing page using only HTML and CSS
A hero section with CTA, a features section with cards, a testimonial quote, and a footer. No JavaScript. Purpose: practice CSS layout before Flexbox/Grid (essay 1.3).
Run Google Lighthouse on your portfolio (DevTools → Lighthouse tab)
Run an audit. Look at the Performance and Accessibility scores. Read the suggestions. Fix at least two issues.
Commit everything to GitHub with a proper commit message
git add . → git commit -m "feat: add complete CSS styling to portfolio" → git push
12

What you must own from this essay

Thing 01
Everything is a box. Margin is outside the border. Padding is inside. box-sizing: border-box makes width include padding and border. Apply it globally. Always.
Thing 02
Specificity determines which rule wins. IDs beat classes beat tags. When confused, open DevTools and read the computed styles — the browser tells you exactly which rule applied and why the others were overridden.
Thing 03
CSS variables are not optional. Define all colours, spacing, and typography as variables in :root. Reference them everywhere. Changing your design system is then one edit, not five hundred.

Vocabulary you now own

Cascade
The algorithm that resolves conflicts when multiple CSS rules apply to the same element. Considers rule origin, specificity, and source order. The "C" in CSS.
Specificity
A three-number score (IDs-Classes-Tags) that determines which CSS rule wins when two rules target the same element and property. Higher score wins.
Box Model
The model describing how every HTML element occupies space: content area + padding + border + margin. With border-box, width includes padding and border.
Pseudo-class
A selector suffix that targets an element in a specific state: :hover (mouse over), :focus (keyboard/click focus), :active (being clicked), :first-child, :nth-child(n).
CSS Variable
A custom property (--name: value) defined in :root and referenced with var(--name). Changes one value and it propagates everywhere the variable is used. Foundation of design systems.
Media Query
A conditional CSS block: @media (min-width: 640px) { ... }. Styles inside only apply when the condition is met. Used to build responsive layouts.
rem / em
Relative length units. rem is relative to the root (html) font size (1rem = 16px by default). em is relative to the current element's font size. Use rem for typography and spacing.
Transition
Animates property changes over time. transition: property duration easing. Without it, state changes (hover, focus) are instant. With it, they are smooth.
Up Next — Phase 1 Continues
Essay 1.3
Flexbox and Grid — Layout Mastery
The two tools that solve every layout problem in modern CSS.
Complete your checklist above first →

Roadmap Account