CSS Session Plan v2
CSS Session Plan v2
CSS is a language that describes the visual presentation of Styles flow (cascade) from multiple sources — browser defaults,
HTML. HTML creates the structure (skeleton), CSS adds the style your stylesheet, inline styles. When two rules target the same
(clothes, colours, layout). Without CSS, every webpage would element, CSS has a clear system to decide which wins. This is
look like a plain text document. called Specificity.
[Link]
📋 What This Does
<!-- Inline: style written directly
inside the HTML tag --> The style="" attribute accepts any CSS property.
Each property is separated by a semicolon.
<h1 style="color: red;
font-size: 36px;"> ✅ Good for: Quick one-off overrides, email
Hello World templates, testing a single style.
</h1>
❌ Avoid for: Real projects — styles are scattered
<p style="color: blue; across 100s of HTML tags. Changing the color
background: yellow; means editing every single tag.
padding: 10px;">
This paragraph is styled inline.
</p>
⚡ Pro Tip
[Link]
📋 What This Does
<!-- Internal: <style> block inside
the <head> of your HTML file --> All CSS is written inside <style> tags in the <head>.
[Link]
📋 What This Does
<!-- HTML file ([Link]) -->
<!DOCTYPE html> The <link> tag connects an HTML file to an
<html> external .css file.
<head>
<!-- Link to external CSS file --> ✅ Best for: ALL real websites
<link rel="stylesheet" • One CSS file styles EVERY page
href="[Link]"> • Browser caches the file — pages load faster on
</head> repeat visits
<body> • Team collaboration — developer edits CSS,
<h1>Hello World</h1> designer edits HTML
<p>Styled paragraph</p> • Easy maintenance — change one file, update
</body> everything
</html>
[Link]
📋 What This Does
/* When multiple rules target same element,
CSS picks the MOST SPECIFIC one */ The cascade has 4 levels, highest wins:
1. Inline style (1000 pts) → wins
/* Specificity: element = 1 point */ 2. ID selector (100 pts)
p { 3. Class selector (10 pts)
color: blue; /* specificity: 1 */ 4. Element selector (1 pt)
}
When specificity is EQUAL, the rule written LAST in
/* Specificity: class = 10 points */ the CSS file wins.
.intro {
color: green; /* specificity: 10 */ This is why your styles sometimes don't seem to
} work — an earlier more specific rule is overriding
them!
/* Specificity: id = 100 points */
#main-text {
color: red; /* specificity: 100 */ ⚡ Pro Tip
}
Use browser DevTools (F12 → Elements → Styles) to
/* Inline style = 1000 points */ see exactly which CSS rules are applied or crossed
/* <p style="color: purple"> */ out due to the cascade.
[Link]
📋 What This Does
/* Define variables in :root
(available everywhere) */ CSS variables store reusable values. Define once at
:root { the top, use everywhere.
--primary-color: #7C3AED;
--secondary-color: #06B6D4; Real scenario: Your client says "Change the brand
--font-size-base: 16px; color from purple to orange."
--border-radius: 8px;
--spacing: 16px; WITHOUT variables: Hunt through 500 lines,
} change color in 40 places. Miss some → broken
design.
/* USE them anywhere with var() */
h1 { WITH variables: Change --primary-color: #7C3AED
color: var(--primary-color); to --primary-color: #F97316 in ONE place. Done.
font-size: calc(var(--font-size-base) * 2.5); Every button, heading, and border updates
}
automatically.
.btn { ⚡ Pro Tip
background: var(--primary-color);
border-radius: var(--border-radius); Variables also enable Dark Mode! Define --bg: white;
padding: var(--spacing); --text: black; normally, then override inside a .dark-
} mode class.
.card {
border: 2px solid var(--secondary-color);
border-radius: var(--border-radius);
}
Day 4 — CSS Introduction: Tasks
5 Create two conflicting rules for the same <p>: one using element selector, one Airbnb: CSS variables control the entire brand
using class. Observe which wins. color system. Rebranding = changing ~5
variable values.
6 Bonus: Create a second HTML page ([Link]) that links to the SAME
[Link]. Both pages should look consistent.
CSS Selectors
Precisely target any HTML element — Universal, Type, Class, ID and beyond
Selects EVERY element on the page. Selects all elements of that HTML tag.
* { box-sizing: border-box; margin: 0; } h1 { } selects ALL <h1> tags.
Most common use: a CSS reset at the top of your stylesheet to p { } selects ALL <p> tags.
remove browser default spacing. Use when you want a consistent style across ALL occurrences of
a tag.
Selects elements with that class attribute. Selects the element with that id.
.card { } matches <div class="card"> #navbar { } matches <nav id="navbar">
REUSABLE — multiple elements can share a class. IDENTIFIER — must be UNIQUE per page.
One element can have MULTIPLE classes. Highest specificity (100 pts). Creates maintenance problems if
<div class="card featured"> overused.
Class vs ID — Real Difference
Classes are the backbone of scalable CSS. Amazon, Flipkart, and
Zomato all use .card or .product-item classes to style thousands of
product cards from a single CSS rule. IDs are reserved for JavaScript ✅ With CSS
<!--hooks andID
Using unique
for page
eachsections
card -->like #navbar or #footer. <!-- Using Class for each card -->
<div id="card1">Product A</div> <div class="card">Product A</div>
<div id="card2">Product B</div> <div class="card featured">Product B</div>
<div id="card3">Product C</div> <div class="card">Product C</div>
/* Must write separate CSS for each! */ /* Write CSS ONCE, applies to all */
#card1 { background: white; .card {
padding: 20px; background: white;
border-radius: 8px; } padding: 20px;
#card2 { background: white; border-radius: 8px;
padding: 20px; }
border-radius: 8px; }
#card3 { background: white; /* Extra style for special card */
padding: 20px; .[Link] {
border-radius: 8px; } border: 2px solid #7C3AED;
/* Repeating same CSS 3 times = bad! */ transform: scale(1.05);
}
[Link]
📋 What This Does
/* Descendant: ALL <a> inside ANY <nav> */
nav a { color: white; text-decoration: none; } Descendant (space): nav a targets links inside
navbars specifically, without affecting all links on
/* Child: ONLY direct <li> inside <ul> */ the page.
ul > li { list-style: none; padding: 8px; }
Child (>): ul > li skips nested lists — only the direct
/* Adjacent sibling: <p> immediately after <h2> */ children get styled.
h2 + p { font-size: 1.1em; color: #555; }
Grouping (,): Instead of writing font-family three
/* General sibling: ALL <p> after an <h2> */ times, one rule applies to all headings.
h2 ~ p { margin-left: 20px; }
Attribute []: Perfect for forms — style password
/* Grouping: apply same rule to multiple selectors */ fields differently from email fields without adding
h1, h2, h3 { font-family: Georgia, serif; } classes.
/* Chaining classes: element must have BOTH */ ⚡ Pro Tip
.[Link] { background: #7C3AED; color: white; }
Chaining .[Link] (no space between) means the
/* Attribute selector */ element must have BOTH classes. .btn .active (with
input[type="email"] { border: 2px solid blue; } space) would mean an .active inside a .btn — totally
a[href^="https"] { color: green; } different!
a[href*="github"] { font-weight: bold; }
Pseudo-classes — Style Based on State
[Link]
📋 What This Does
/* LINK STATES — must be in this order */
a:link { color: #7C3AED; } /* unvisited */ Pseudo-classes select elements based on their
a:visited { color: gray; } /* already clicked */ STATE or POSITION — no extra HTML needed.
a:hover { color: #06B6D4; /* mouse over */
text-decoration: underline; } :hover enables interactive menus, button effects,
a:active { color: #EF4444; } /* being clicked */ card highlights without JavaScript.
/* NEGATION */
li:not(.active) { opacity: 0.5; }
Pseudo-elements — Style Parts of Elements
[Link]
📋 What This Does
/* ::before and ::after inject virtual content */
::before and ::after create virtual elements INSIDE
/* Add decorative arrow before each list item */ the targeted element — first child and last child
li::before { respectively.
content: "→ ";
color: #7C3AED; They REQUIRE the content: "" property (can be
font-weight: bold; empty string).
}
Use case: notification badges, decorative icons,
/* Add a colored underline after headings */ quote marks around blockquotes, custom list
h2::after { bullets — all without adding extra HTML tags.
content: ""; /* required, even if empty */
display: block; ::first-letter creates a newspaper-style drop-cap
width: 60px; effect used on news sites and blogs like Medium.
height: 3px;
background: #06B6D4; ⚡ Pro Tip
margin-top: 8px;
} Pseudo-elements use :: (double colon). Older
browsers used single : — both work for
/* Style just the first letter (newspaper drop-cap) */ compatibility, but :: is the modern standard.
[Link]::first-letter {
font-size: 3.5em;
float: left;
line-height: 0.8;
color: #7C3AED;
margin-right: 6px;
Day 5 — Selectors: Tasks
6 Challenge: Style a table with zebra rows (:nth-child), bold header (:first-child),
no border on last row (:last-child), and highlight on :hover.
Properties: Text, Font & Color
Typography and color — the two biggest factors in a website's readability and brand
[Link]
📋 What This Does
/* Text alignment */
.left { text-align: left; } /* default */ line-height: 1.6 means the line height = 1.6 × the
.center { text-align: center; } font size. For a 16px font, that's 25.6px of vertical
.right { text-align: right; } space per line. This dramatically improves
.justify { text-align: justify; } /* newspaper-style */ readability for long paragraphs.
/* Line height — space between lines */ text-overflow: ellipsis is used everywhere: product
p { line-height: 1.6; } /* 1.6 × font-size */ titles on e-commerce that might be too long,
/* Unitless values are BEST — scale with font */ notification text in apps, file names in dashboards.
/* Letter spacing — space between characters */ Letter spacing: Tight (-0.02em) on large headings
.heading { letter-spacing: -0.02em; } /* tight */ looks professional. Wide (0.1em+) on small
.btn-text { letter-spacing: 0.08em; } /* spaced */ uppercase labels (like button text) improves
.label { letter-spacing: 0.15em; } /* wide */ legibility.
/* Word spacing */ ⚡ Pro Tip
.quote { word-spacing: 0.1em; }
For body text: line-height: 1.5 to 1.7 is the sweet
/* Text decoration */ spot. Below 1.3 = cramped, above 2.0 = too airy.
a { text-decoration: none; } /* remove
underline */
.strike { text-decoration: line-through; }
.mark { text-decoration: underline
underline-offset: 4px; }
[Link]
📋 What This Does
<!-- Step 1: Add to <head> of HTML BEFORE your CSS -->
<link rel="preconnect" Google Fonts provides 1400+ free fonts. The
href="[Link] browser downloads them on first page load.
<link
href="[Link] Pairing strategy:
family=Inter:wght@400;600;700& • Sans-serif body + serif heading = editorial feel
family=Playfair+Display:wght@700& (like Medium, New Yorker)
display=swap" • Sans-serif body + sans-serif heading = modern,
rel="stylesheet"> tech feel (like Google, Stripe)
• Monospace for all = developer tool feel (like
/* Step 2: Use in CSS */ GitHub)
body {
font-family: 'Inter', sans-serif; The display=swap parameter shows your fallback
font-size: 16px; font immediately while Google Font loads,
}
preventing flash of invisible text.
⚡ Pro Tip
h1, h2, h3 {
font-family: 'Playfair Display', serif; Only load font WEIGHTS you actually use. Loading all
font-weight: 700; 9 weights of a font (100–900) adds 500KB+ to your
} page. Load only 400 and 700 unless you need others.
hsl(0, 100%, 50%) = red color: red; color: navy; color: tomato;
hsl(240, 100%, 50%) = blue color: cornflowerblue; color: limegreen;
hsl(270, 60%, 50%) = purple (like #7C3AED) 148 named colors exist. Fine for learning and quick demos, but
INTUITIVE: Hue=colour wheel, Saturation=vivid vs grey, use HEX/HSL for real projects (more control, exact brand colors).
Lightness=dark vs light
Color Properties — Background, Border, Opacity
[Link]
📋 What This Does
/* Text color */
h1 { color: #1E293B; } opacity vs rgba: This is a common mistake.
p { color: rgba(0, 0, 0, 0.7); } /* 70% black */
opacity: 0.5 on a div makes EVERYTHING inside it
/* Background */ (text, images, children) 50% transparent.
body { background-color: #F8FAFC; }
background: rgba(0,0,0,0.5) only makes the
.hero { background semi-transparent — the text inside
background-color: #0F172A; stays fully visible.
/* Gradient background */
background: linear-gradient( Gradients: linear-gradient(direction, color1,
135deg, color2). Widely used for hero sections, cards,
#7C3AED 0%, buttons.
#06B6D4 100%
);
Focus ring: The box-shadow trick (0 0 0 3px)
} ⚡ Pro aTip
creates soft glow without affecting layout —
used by Stripe, Tailwind, and most modern design
.card { For accessible color contrast, text on background
background: white;
systems.
needs a minimum 4.5:1 contrast ratio. Use tools like
/* Semi-transparent overlay */ WebAIM Contrast Checker.
background: rgba(255, 255, 255, 0.9);
}
/* Opacity vs rgba */
.overlay { background: black;
opacity: 0.5; } /* EVERYTHING fades */
Day 8 — Text, Font & Color: Tasks
PADDING
CONTENT Inner cushion. Shares background color with
content.
(your text, image, etc.)
MARGIN
Outer gap. Transparent, creates space
between elements.
box-sizing: border-box — The Most Important CSS Reset
[Link]
📋 What This Does
/* DEFAULT behavior (box-sizing: content-box) */
.card { This is the #1 layout confusion for beginners.
width: 300px;
padding: 20px; Without border-box: You say width: 300px but the
border: 2px solid gray; browser renders 344px because padding and
} border are added ON TOP of the width.
[Link]
📋 What This Does
/* Padding shorthand — 4 ways to write it */
padding: 20px; /* all 4 sides */ margin: 0 auto centers a block element
padding: 10px 20px; /* top/bottom left/right */ horizontally. It means: top/bottom margin = 0,
padding: 10px 20px 15px; /* top left/right bottom */ left/right margin = auto (equal on both sides).
padding: 5px 10px 15px 20px; /* top right bottom left */
/* Memory trick: Top → Right → Bottom → Left (clockwise) */ This ONLY works when the element has a fixed
width (width: 300px or similar). Without a width, a
/* Same shorthand works for margin */ block element already fills 100% width, so there's
margin: 0 auto; /* center block horizontally */ nothing to center.
margin: 24px 0; /* vertical gap, no horizontal */
margin-top: 0; /* individual side */ Clockwise shorthand: Think of a clock — Top (12),
Right (3), Bottom (6), Left (9). Same order for
/* Border shorthand: width style color */ padding, margin, and border-radius.
border: 2px solid #E2E8F0;
border: 3px dashed #EF4444;
border-radius: 50% on a square div = perfect
border: 0; /* remove border */ ⚡ ProThis
Tipis how profile picture circles are made
circle.
everywhere.
/* Individual border sides */ Margin collapse: Adjacent vertical margins (top of
border-top: 4px solid #7C3AED; /* top accent */ one div touching bottom of another) merge into the
border-bottom: 1px solid #E2E8F0; /* divider line */ LARGER single value. 20px margin-bottom + 16px
margin-top = 20px gap (not 36px). Horizontal
/* Border radius */ margins never collapse.
border-radius: 8px; /* all corners */
border-radius: 50%; /* perfect circle */
border-radius: 12px 4px; /* top-bottom left-right */
Display Property — How Elements Flow
[Link]
📋 What This Does
/* BLOCK — full width, stacks vertically */
/* Default: div, p, h1-h6, ul, li */ The 3 main display types you'll use constantly:
.block-demo {
display: block; block: div, sections, paragraphs. Stack on top of
width: 300px; /* can set width */ each other. Full width. Use for layout structure.
height: 50px; /* can set height */
background: #E0E7FF; inline: text-level elements (links, spans). Flow in a
} line like words. Can't set width/height.
/* INLINE — flows with text, no width/height */ inline-block: Best of both. Flows in a line like inline
/* Default: span, a, strong, em */ but accepts width, height, padding like block. Used
.inline-demo { for buttons, tags, and icon+text combos.
display: inline;
/* width: 300px; ← IGNORED */ display: none is how you show/hide modals,
/* height: 50px; ← IGNORED */
dropdowns, and menus. Add/remove a class with
background: #D1FAE5; ⚡ Pro Tipto toggle it.
JavaScript
padding: 0 8px; /* only horizontal works */
} visibility: hidden hides the element but keeps its
space in the layout (like invisible ink). display: none
/* INLINE-BLOCK — flows inline BUT accepts dimensions */ removes it completely (the next element moves up
/* Perfect for: buttons, badges, nav items */ to fill the gap).
.btn {
display: inline-block;
width: 120px; /* works! */
height: 40px; /* works! */
text-align: center;
CSS Positioning — All 5 Values Explained
[Link]
📋 What This Does
/* STATIC — default, follows normal document flow */
div { position: static; } /* top/left/right/bottom ignored */ The key to understanding absolute positioning:
/* RELATIVE — offset from where it WOULD normally be */ An absolute element is positioned relative to its
.shifted { nearest ancestor that has position: relative,
position: relative; absolute, or fixed.
top: 20px; /* moves DOWN 20px from normal spot */
left: 30px; /* moves RIGHT 30px from normal spot */ If no such ancestor exists, it positions relative to
/* Other elements don't move — gap remains */ the <body>.
}
Common pattern:
/* ABSOLUTE — positioned relative to nearest 1. Give parent div: position: relative
positioned ancestor (relative/absolute/fixed) */ 2. Give child badge/tooltip: position: absolute
.parent { position: relative; } 3. Use top/right/bottom/left to place it inside
.tooltip {
parent
position: absolute; ⚡ Pro Tip
top: -35px; right: 0;
fixed vs sticky:
/* Floats above, outside normal flow */ Always
}
• fixed:add z-index
Always to fixed/sticky
at that position onelements (z-index:
screen, even
100+) or other
when user scrolls elements will overlap them as you
scroll.
• sticky: Scrolls normally until it hits the edge, then
/* FIXED — relative to VIEWPORT, stays on scroll */
.navbar { "sticks"
position: fixed;
top: 0; left: 0; right: 0;
z-index: 1000;
}
element visually and a colored top border creates hierarchy. margin
creates the gap between multiple cards in a grid. border-radius softens ✅ With CSS
the design — sharp corners feel harsh, rounded feel modern. box-
/* Card
shadow without
lifts the card offproper box model
the background, */
indicating it is an interactive /* Card with proper box model */
.card { element. *, *::before, *::after {
background: white; box-sizing: border-box;
} }
/* Result: Text is pressed against .card {
all edges. No visual separation. width: 320px;
Looks broken and unfinished. background: white;
padding: 24px;
border: 1px solid #E2E8F0;
border-radius: 12px;
border-top: 4px solid #7C3AED;
*/ margin-bottom: 24px;
box-shadow: 0 4px 6px rgba(0,0,0,0.07);
}
.card h3 {
💡 undefined
margin-top: 0;
margin-bottom: 8px;
}
.card p { margin: 0; }
Day 9 — Box Model: Tasks
5 Debug task: Given a card with width: 200px, padding: 30px, border: 5px — Every modal/popup on the web: position:
calculate and verify the actual rendered width in DevTools. fixed, centered using top: 50%, left: 50%,
transform: translate(-50%, -50%).
6 Bonus: Recreate a Twitter/X style tweet card with avatar (rounded), name,
handle, tweet text, action icons at bottom.
Flexbox: Basics, Alignment &
Ordering
The modern CSS layout engine — build any 1D layout with just a few properties
Add display: flex to a PARENT element. That parent becomes Flexbox has two axes:
the 'flex container'. Its direct children automatically become • Main axis: direction items flow (default: horizontal →)
'flex items'. • Cross axis: perpendicular to main (default: vertical ↓)
Controls spacing/alignment ALONG the main axis: Controls alignment PERPENDICULAR to main axis:
flex-start → items at start stretch → fill full height (default)
center → items at center flex-start → align to top
flex-end → items at end flex-end → align to bottom
space-between → equal gaps BETWEEN center → vertically center
space-around → equal space around each baseline → align by text baseline
space-evenly → equal space everywhere
Flexbox Fundamentals — The 6 Core Properties
[Link]
📋 What This Does
/* Parent (Container) Properties */
.container { These 6 properties on the CONTAINER control
display: flex; almost everything:
[Link]
📋 What This Does
/* Child (Item) Properties */
flex: 1 is the most commonly used shorthand. It
/* flex: grow shrink basis (shorthand) */ means: "grow to fill available space, can shrink,
.item { flex: 1; } start at 0 basis."
/* = flex: 1 1 0% → can grow AND shrink equally */
The sidebar + main layout (flex: 0 0 260px on
/* Real-world: sidebar + main content */ sidebar, flex: 1 on main) is used in EVERY
.sidebar { flex: 0 0 260px; } /* fixed, never shrinks */ dashboard app — Gmail, Notion, Slack, VS Code.
.main { flex: 1; } /* takes all remaining space */
align-self is powerful for "break out" elements. In
/* flex-grow: how much to grow relative to siblings */ a card row where all cards stretch to equal height,
.col-1 { flex-grow: 1; } /* gets 1 share */ use align-self: flex-start on a card to make it
.col-2 { flex-grow: 2; } /* gets 2 shares (twice as wide) */ shrink-wrap its content instead.
.col-3 { flex-grow: 1; } /* gets 1 share */
/* total shares: 4. col-2 gets 50%, others get 25% */
order lets you rearrange items on mobile without
⚡ Pro Tip
changing HTML structure — the image can show
/* align-self: override container's align-items */
before the text on small screens using media
.card-featured { flex: 0 0 260px means: don't grow (0), don't shrink
queries + order.
align-self: flex-start; /* while others stretch */ (0), always be 260px. Perfect for fixed sidebars.
}
💡 undefined
.col { flex: 1; }
/* Clearing floats was required */ /* All columns same height by default */
.container::after {
content: ""; /* Sidebar + main content */
display: table; .layout {
clear: both; display: flex;
} }
.sidebar { flex: 0 0 250px; }
.content { flex: 1; }
/* No floats, no clears needed! */
Real-World Flexbox Patterns
[Link]
📋 What This Does
/* Pattern 1: Responsive card grid */
.cards { flex: 1 1 280px is the most powerful responsive
display: flex; pattern in CSS:
flex-wrap: wrap; • flex-grow: 1 — item expands to fill available
gap: 20px; space
} • flex-shrink: 1 — item can compress when
.card { needed
flex: 1 1 280px; • flex-basis: 280px — never smaller than 280px
/* Grows and shrinks, minimum 280px
3 per row on desktop, 2 on tablet, On a 1200px container with 20px gaps: 4 cards fit
1 on mobile — automatically! */ (4×280 + 3×20 = 1180px)
} On a 600px container: 2 cards fit
On a 300px container: 1 card
/* Pattern 2: Navigation bar */
.nav {
This gives you responsive layouts WITHOUT media
display: flex; ⚡ Pro Tip
queries for the grid logic.
align-items: center;
justify-content: space-between; The
The flex:
nav 1pattern
1 280px(space-between
approach is howforAirbnb,
logo+links,
padding: 0 32px; [Link],
height: 64px;
align-items: center for vertical alignment)that
and Zomato build listing grids is the
gracefully reflow recreated
most commonly at any screen width.
UI component in CSS.
}
.nav-links {
display: flex;
gap: 32px;
list-style: none;
}
Day 10 — Flexbox: Tasks
T1 T2 T3 T4 T5