CSS / CSS3 / SCSS — Complete Course
A twenty-five-lesson deep dive from CSS basics through the box model, layout (Flexbox/Grid), responsive design, animation, and SCSS.
Lesson 1: What is CSS?
CSS (Cascading Style Sheets) controls the visual presentation of HTML. Without CSS, every webpage would be plain black text on a white background.
Three Ways to Add CSS
CSS can be added in three ways: Inline (directly on a tag via the style attribute), Internal (inside a <style> block in <head>), and External (a separate .css file linked with <link>). External stylesheets are the professional standard — they separate content from design and can be browser-cached.
Roman Urdu: CSS teen tareeqon se add hoti hai: Inline — seedha tag ke andar style attribute se. Internal — <head> mein <style> block mein. External — alag .css file banao aur <link> se jodo. Professional kaam mein hamesha external use karein — content aur design alag rahti hai aur browser cache karta hai.
/* 1. Inline */
<p style="color:red; font-size:18px;">Hello</p>
/* 2. Internal — inside <head> */
<style>
p { color: blue; }
</style>
/* 3. External — linked file */
<link rel="stylesheet" href="style.css">
Basic CSS Syntax
A CSS rule has two parts: a selector targeting HTML elements, and a declaration block in curly braces with property–value pairs. Each declaration ends with a semicolon. The "C" in CSS stands for Cascading — when multiple rules target the same element, origin, specificity, and source order determine the winner.
Roman Urdu: CSS rule ke do hisse hain: Selector jo element target karta hai, aur declaration block curly braces mein. Har declaration semicolon pe khatam hoti hai. CSS mein "C" Cascading hai — jab kai rules ek element pe hon, origin, specificity, aur order se decide hota hai kaun jeete ga.
h1 { color: #1a1a2e; font-size: 32px; }
.card { background: white; padding: 20px; border-radius: 8px; }
#hero { background: navy; color: white; }Lesson 2: Selectors
Basic Selectors
CSS provides several selector types. Type selectors target HTML tags. Class selectors (.) are the most reusable. ID selectors (#) are unique per page. The universal selector * targets everything. Group selectors with commas to share styles across multiple elements.
Roman Urdu: CSS mein kuch bunyadi selectors hain. Type seedha tag target karta hai. Class (.) sabse zyada reusable hai. ID (#) ek page pe ek hi element ke liye. Universal * sab kuch target karta hai. Comma se group karke kai elements ko ek jaisi styling de sakte hain.
p { color: gray; }
.btn { padding: 10px 20px; }
#logo { width: 120px; }
* { box-sizing: border-box; }
h1, h2, h3 { font-family: serif; }
Combinator Selectors
Combinators select elements based on their HTML tree relationship. A descendant (space) targets any nested child. A child (>) targets only direct children. An adjacent sibling (+) targets the immediately following sibling. A general sibling (~) targets all following siblings.
Roman Urdu: Combinators HTML tree mein rishte ke hisaab se target karte hain. Descendant (space) kisi bhi nested child ko. Child (>) sirf seedhe bacho ko. Adjacent sibling (+) agle sibling ko. General sibling (~) baad ke tamam siblings ko.
nav a { color: white; } /* any a inside nav */
ul > li { list-style: none; } /* direct li only */
h2 + p { margin-top: 0; } /* adjacent sibling */
h2 ~ p { color: gray; } /* all following siblings */
Attribute Selectors
Attribute selectors target elements by their HTML attributes using square brackets. You can match exact values, values that start with (^=), end with ($=), or contain (*=) a string. Ideal for styling links, input types, and data attributes without adding extra classes to HTML.
Roman Urdu: Attribute selectors elements ko unke HTML attributes se square brackets mein target karte hain. Exact, start (^=), end ($=), ya contain (*=) match kar sakte hain. Links, input types aur data attributes style karne ke liye bina extra HTML classes ke best hai.
a[target="_blank"] { color: orange; }
input[type="email"] { border-color: blue; }
a[href^="https"] { padding-left: 20px; } /* starts with */
a[href$=".pdf"] { color: red; } /* ends with */
[class*="icon-"] { display: inline-block; }
[data-status="active"] { background: green; }Lesson 3: The Box Model
Content, Padding, Border, Margin
Every HTML element is a rectangular box with four layers from inside out: Content (the actual text/image), Padding (space inside between content and border), Border (the visible edge), and Margin (space outside separating it from other elements). This model is the foundation of all CSS layout.
Roman Urdu: Har HTML element ek rectangular box hai jiske chaar hisse hain andar se bahar: Content (actual text/image), Padding (content aur border ke beech andar ki jagah), Border (dikhne wala kinarah), aur Margin (bahar ki jagah jo doosre elements se door rakhti hai). Yeh model tamam CSS layout ki bunyad hai.
.box {
width: 300px;
padding: 20px; /* all sides */
padding: 10px 20px; /* top/bottom left/right */
padding: 5px 10px 15px 20px; /* top right bottom left */
border: 2px solid #ccc;
border-radius: 8px;
margin: 0 auto; /* center horizontally */
}
box-sizing: border-box
By default, width only covers content — padding and border are added on top, making elements larger than expected. box-sizing: border-box includes padding and border inside the declared width. This is so essential that every modern CSS reset applies it globally with *.
Roman Urdu: Default mein width sirf content cover karta hai — padding aur border upar se add hote hain. box-sizing: border-box se dono declared width ke andar aa jaate hain. Yeh itna zaroori hai ke har modern CSS reset isko * se globally apply karta hai.
*, *::before, *::after { box-sizing: border-box; }
.box {
width: 300px; padding: 20px; border: 2px solid black;
/* Total width = exactly 300px */
}
Margin Collapse
When two vertical margins touch between block elements, they "collapse" into one — equal to the larger of the two. This happens between siblings and between parent–first/last child when no border or padding separates them. Flexbox and Grid containers never collapse margins.
Roman Urdu: Jab do vertical margins milen, woh "collapse" ho ke ek ban jaate hain — jo bada ho woh. Siblings ke beech aur parent–child ke beech hota hai jab beech mein border ya padding na ho. Flexbox aur Grid mein margin collapse nahi hota.
Lesson 4: Colors & Units
Color Formats
CSS supports multiple color formats. HEX is most common for web. RGB/RGBA gives control over red, green, blue and opacity. HSL/HSLA (Hue, Saturation, Lightness) is the most intuitive for creating color variations. Modern CSS also supports oklch() — a perceptually uniform format ideal for accessible color systems.
Roman Urdu: CSS mein kai color formats hain. HEX web pe sabse common. RGB/RGBA se red, green, blue aur opacity control hoti hai. HSL/HSLA color variations banane ke liye sabse samajh aane wala format. Modern CSS mein oklch() bhi hai jo accessible color systems ke liye ideal hai.
.box {
color: #c9a84c;
color: rgb(201, 168, 76);
color: rgba(201, 168, 76, 0.5);
color: hsl(42, 53%, 54%);
color: hsla(42, 53%, 54%, 0.8);
background: oklch(72% 0.12 85);
background: currentColor; /* inherits text color */
}
CSS Units
CSS has absolute units (px) and relative units. Relative units are preferred for responsive design. rem is relative to the root font size (16px default) — great for spacing and type. em is relative to the parent font size. % relative to the parent container. vh/vw are percentages of the viewport. clamp() creates fluid values between a min and max.
Roman Urdu: CSS mein absolute (px) aur relative units hain. Responsive design ke liye relative behtar. rem root font size se (default 16px) — spacing aur typography ke liye best. em parent ke font size se. % parent container se. vh/vw viewport ka percentage. clamp() se fluid values banate hain.
.box {
font-size: 16px;
padding: 1rem; /* = 16px, scales with root */
margin: 1.5em; /* relative to own font-size */
width: 50%; /* 50% of parent width */
height: 100vh; /* full viewport height */
font-size: clamp(1rem, 4vw, 3rem); /* min ideal max */
width: min(600px, 100%); /* never wider than container */
}Lesson 5: Typography
Font Properties
Typography controls how text looks and reads. Key properties: font-family (always provide fallbacks), font-size, font-weight (100–900), font-style for italic, line-height for readability (1.5–1.7 ideal for body), letter-spacing for character spacing, and text-transform for uppercase/lowercase.
Roman Urdu: Typography text ki shakal aur readability control karta hai. Key properties: font-family (fallback zaroor do), font-size, font-weight (100–900), font-style italic ke liye, line-height readability (body ke liye 1.5–1.7 best), letter-spacing characters ki spacing, aur text-transform case badalne ke liye.
body {
font-family: 'Inter', system-ui, sans-serif;
font-size: 16px; line-height: 1.6; font-weight: 400;
}
h1 {
font-size: clamp(2rem, 5vw, 4rem);
font-weight: 700; letter-spacing: -0.03em; line-height: 1.1;
}
.caption {
font-size: 0.75rem; text-transform: uppercase;
letter-spacing: 0.1em; color: #888;
}
Google Fonts & @font-face
Google Fonts are free web fonts loaded via a <link> tag. Always add display=swap to prevent invisible text during load. For self-hosted fonts, @font-face defines the font files. Include multiple weight variants and always set font-display: swap.
Roman Urdu: Google Fonts free web fonts hain jo <link> tag se load hote hain. display=swap zaroor lagao taake load ke waqt text invisible na ho. Self-hosted ke liye @font-face use karo. Multiple weights zaroor include karo aur font-display: swap set karo.
/* Google Fonts link tag */
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
/* Self-hosted */
@font-face {
font-family: 'MyFont';
src: url('fonts/myfont.woff2') format('woff2');
font-weight: 400 700; font-display: swap;
}Lesson 6: Display & Position
Display Values
display controls how an element generates its box. block takes full width and stacks vertically. inline flows with text and ignores width/height. inline-block is inline but accepts dimensions. none removes the element from flow entirely. flex and grid unlock powerful layout systems covered in the next two lessons.
Roman Urdu: display control karta hai ke element ka box kaise banta hai. block poori width leta hai aur neeche stack hota hai. inline text ke saath flow karta hai, width/height ignore karta hai. inline-block inline hai lekin dimensions accept karta hai. none element bilkul hata deta hai. flex aur grid powerful layouts ke liye hain.
.block { display: block; }
.inline { display: inline; }
.inline-block { display: inline-block; width: 200px; }
.hidden { display: none; }
.invisible { visibility: hidden; } /* keeps space, not visible */
Position Property
static is the default — normal flow. relative offsets from its natural position without affecting layout. absolute removes the element from flow and positions it relative to the nearest positioned ancestor. fixed anchors to the viewport. sticky scrolls normally until a threshold, then sticks. Use z-index to control stacking order of positioned elements.
Roman Urdu: static default hai — normal flow. relative apni jagah se hata ke offset karta hai bina layout affect kiye. absolute flow se nikaal ke nearest positioned ancestor ke relative position karta hai. fixed viewport se chipka rehta hai. sticky scroll karta hai phir threshold pe chipak jaata hai. z-index se stacking order control karein.
.parent { position: relative; }
.child { position: absolute; top: 0; right: 0; }
.navbar {
position: fixed;
top: 0; left: 0; right: 0;
z-index: 100;
}
.sticky-header { position: sticky; top: 0; }Lesson 7: Flexbox
Flex Container Properties
Flexbox is a one-dimensional layout system. The parent (flex container) controls how its children are arranged along a main axis and a cross axis. flex-direction sets the main axis. justify-content aligns along the main axis. align-items aligns along the cross axis. gap adds spacing between items without margin hacks. flex-wrap allows items to wrap to new lines.
Roman Urdu: Flexbox ek one-dimensional layout system hai. Parent (flex container) apne children ko main axis aur cross axis par control karta hai. flex-direction main axis set karta hai. justify-content main axis par align karta hai. align-items cross axis par. gap spacing deta hai bina margin hacks ke. flex-wrap items ko nai lines par wrap hone deta hai.
.container {
display: flex;
flex-direction: row; /* row | column | row-reverse */
justify-content: space-between; /* flex-start | center | space-around */
align-items: center; /* stretch | flex-start | flex-end */
flex-wrap: wrap;
gap: 16px;
}
/* Perfect centering */
.center { display: flex; justify-content: center; align-items: center; }
Flex Item Properties
Flex items control their own sizing. flex-grow defines how much extra space an item takes (0 = don't grow, 1 = equal share). flex-shrink controls how items shrink when space is tight. flex-basis sets the initial size. The shorthand flex: 1 means grow and shrink equally. align-self overrides the container's align-items for a single item.
Roman Urdu: Flex items apni sizing khud control kar sakte hain. flex-grow extra space kitna le (0 = na le, 1 = barabar). flex-shrink kam jagah mein kitna shrink ho. flex-basis initial size. Shorthand flex: 1 ka matlab barabar grow aur shrink. align-self ek item ke liye container ki align-items override karta hai.
.item {
flex: 1; /* grow shrink equally */
flex: 0 0 200px; /* grow shrink basis */
align-self: flex-end;
order: -1; /* move first visually */
}Lesson 8: CSS Grid
Grid Container & Tracks
CSS Grid is a two-dimensional layout system controlling rows and columns simultaneously. grid-template-columns defines column sizes using the fr fraction unit. repeat() avoids repetition. auto-fill with minmax() creates responsive columns that fill the container automatically — without media queries.
Roman Urdu: CSS Grid two-dimensional layout system hai jo rows aur columns ek saath control karta hai. grid-template-columns se columns define hote hain, fr fraction unit available space ka hissa hai. repeat() repetition se bachata hai. auto-fill aur minmax() se responsive columns bante hain bina media queries ke.
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-columns: 200px 1fr 1fr;
/* Responsive — no media queries */
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-template-rows: auto 1fr auto;
gap: 24px;
}
Grid Areas & Placement
Named template areas let you visually design layouts using ASCII-art-like strings. Grid items can span multiple columns or rows using grid-column and grid-row. The value 1 / -1 means "from first to last line" — spanning the entire axis. This makes complex page layouts readable and easy to restructure with media queries.
Roman Urdu: Named template areas se ASCII art jaisi strings mein visually layout design hota hai. grid-column aur grid-row se kai columns ya rows span kar sakte hain. 1 / -1 ka matlab "pehli se aakhri line tak" — poora axis span. Complex layouts readable aur media queries se restructure karna easy ho jaata hai.
.layout {
display: grid;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 240px 1fr;
grid-template-rows: 60px 1fr 60px;
min-height: 100vh;
}
header { grid-area: header; }
.sidebar { grid-area: sidebar; }
main { grid-area: main; }
footer { grid-area: footer; }
.hero { grid-column: 1 / -1; } /* full width */Lesson 9: Responsive Design
Media Queries
Media queries apply CSS conditionally based on device characteristics. The mobile-first approach writes base styles for mobile, then adds styles for wider screens using min-width. Common breakpoints: 640px (mobile), 768px (tablet), 1024px (laptop), 1280px (desktop). You can also target color scheme preference, motion preference, and print.
Roman Urdu: Media queries device ke characteristics ke hisaab se CSS conditionally apply karti hain. Mobile-first approach: pehle mobile ke base styles, phir bade screens ke liye min-width se add karo. Common breakpoints: 640px (mobile), 768px (tablet), 1024px (laptop), 1280px (desktop). Color scheme, motion preference, aur print bhi target kar sakte hain.
.grid { grid-template-columns: 1fr; } /* mobile base */
@media (min-width: 768px) { .grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1024px) { .grid { grid-template-columns: repeat(3, 1fr); } }
@media (prefers-color-scheme: dark) { body { background: #000; } }
@media (prefers-reduced-motion: reduce) { * { animation: none !important; } }
@media print { .no-print { display: none; } }
Container Queries
Container queries respond to the size of a parent container rather than the viewport — enabling truly component-based responsive design. A card component can reflow based on its own container size, not the full screen. Define the container with container-type, then use @container to write conditional styles.
Roman Urdu: Container queries viewport ki bajaye parent container ki size se respond karte hain — truly component-based responsive design enable karta hai. Ek card component apne container ki size ke hisaab se reflow kar sakta hai. container-type se container define karo, phir @container se conditional styles likho.
.card-wrapper { container-type: inline-size; container-name: card; }
@container card (min-width: 400px) {
.card { display: flex; flex-direction: row; }
}Lesson 10: Transitions
transition Property
Transitions smoothly animate a CSS property when its value changes — usually on :hover or :focus. The transition shorthand takes: property name, duration, easing function, and optional delay. Always specify which properties to transition rather than using all. For best performance only animate transform and opacity — both are GPU-accelerated.
Roman Urdu: Transitions kisi CSS property ko smoothly animate karte hain jab uski value change ho — usually :hover ya :focus pe. transition shorthand mein: property name, duration, easing, aur optional delay. all ki bajaye specific properties batao. Best performance ke liye sirf transform aur opacity animate karo — dono GPU-accelerated hain.
.btn {
background: blue;
transform: scale(1);
transition: background 0.3s ease, transform 0.2s ease;
/* Custom easing */
transition: transform 0.4s cubic-bezier(.16,1,.3,1);
}
.btn:hover { background: darkblue; transform: scale(1.05); }
💡 Performance tip: Onlytransformandopacityare GPU-accelerated. Avoid transitioningwidth,height, ormargin— they trigger expensive layout recalculations.
Lesson 11: Animations
@keyframes & animation
CSS animations play automatically and can loop, reverse, and run on page load — unlike transitions which need a trigger. Define frames with @keyframes using percentages or from/to keywords. Apply with the animation shorthand. animation-fill-mode: forwards keeps the final state after the animation ends. animation-play-state lets you pause/resume via JavaScript.
Roman Urdu: CSS animations khud play hote hain aur loop, reverse kar sakte hain — transitions ke brukhaaf jo trigger chahte hain. @keyframes se frames define karo percentages ya from/to se. animation shorthand se apply karo. animation-fill-mode: forwards animation khatam hone ke baad final state rakhta hai. animation-play-state se JavaScript se pause/resume kar sakte hain.
@keyframes slideIn {
from { transform: translateY(-20px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.05); }
}
.card { animation: slideIn 0.4s ease forwards; }
.badge {
animation: pulse 2s infinite alternate;
animation-fill-mode: forwards;
animation-play-state: paused;
}Lesson 12: Transforms
2D & 3D Transforms
CSS transforms move, rotate, scale, and skew elements without affecting the layout of surrounding elements. Multiple functions chain in one declaration. transform-origin changes the pivot point (default center). For 3D transforms, the parent needs perspective to establish depth. backface-visibility: hidden hides the back of flipped elements.
Roman Urdu: CSS transforms elements ko move, rotate, scale, skew karte hain aas paas ke layout affect kiye bina. Kai functions ek declaration mein chain ho sakte hain. transform-origin pivot point change karta hai (default center). 3D transforms ke liye parent mein perspective chahiye. backface-visibility: hidden flipped element ka peechwala hissa chhupaata hai.
.box {
transform: translate(50px, 20px);
transform: scale(1.5);
transform: rotate(45deg);
transform: skew(10deg, 5deg);
/* Chained */
transform: translateY(-4px) scale(1.02);
transform-origin: top left;
/* 3D */
transform: rotateY(180deg);
transform-style: preserve-3d;
backface-visibility: hidden;
}
.scene { perspective: 800px; }Lesson 13: Gradients
Linear, Radial & Conic Gradients
CSS gradients are treated as images — use them in background-image, not background-color. linear-gradient transitions colors along a line. radial-gradient radiates from a center point. conic-gradient rotates around a center like a pie chart. Multiple gradients stack with commas — letting you layer a semi-transparent gradient over an image.
Roman Urdu: CSS gradients images ki tarah treat hote hain — background-image mein use karo, background-color mein nahi. linear-gradient ek line pe colors transition karta hai. radial-gradient center se radiate karta hai. conic-gradient pie chart ki tarah ghoomta hai. Kai gradients commas se stack ho sakte hain — image ke upar semi-transparent gradient lagaane ke liye.
.box {
background: linear-gradient(to right, #667eea, #764ba2);
background: linear-gradient(135deg, #f6d365 0%, #fda085 100%);
background: radial-gradient(circle at center, #1a1a2e, #0f3460);
background: conic-gradient(red 0deg, yellow 120deg, blue 240deg);
/* Overlay gradient on image */
background:
linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.5)),
url('hero.jpg') center/cover;
}Lesson 14: Shadows & Filters
box-shadow & text-shadow
box-shadow syntax: x-offset y-offset blur-radius spread-radius color. Use inset for inner shadows. Stack multiple shadows with commas for rich depth effects. A coloured glow shadow with zero offset and blur creates popular UI highlight effects. text-shadow works identically but applies to text characters instead of the element box.
Roman Urdu: box-shadow syntax: x-offset y-offset blur-radius spread-radius color. inset se inner shadow milta hai. Kai shadows commas se stack karo depth ke liye. Zero offset coloured glow se popular UI highlight effects bante hain. text-shadow bilkul waise kaam karta hai lekin element box ki jagaye text characters pe lagta hai.
.card {
box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1);
/* Layered depth */
box-shadow:
0 1px 2px rgba(0,0,0,0.07),
0 4px 8px rgba(0,0,0,0.07),
0 8px 16px rgba(0,0,0,0.07);
box-shadow: inset 0 2px 4px rgba(0,0,0,0.2); /* inner */
box-shadow: 0 0 20px rgba(99,102,241,0.5); /* glow */
}
h1 { text-shadow: 2px 2px 4px rgba(0,0,0,0.3); }
CSS Filters & backdrop-filter
CSS filter applies visual effects like Photoshop. Common: blur(), brightness(), contrast(), grayscale(), sepia(), drop-shadow(). backdrop-filter applies the filter to whatever is behind the element — perfect for glassmorphism cards and frosted navigation bars. Requires a background with some transparency to show the effect.
Roman Urdu: CSS filter Photoshop jaisi visual effects apply karta hai. Common: blur(), brightness(), contrast(), grayscale(), sepia(), drop-shadow(). backdrop-filter element ke peeche jo kuch hai us pe filter lagata hai — glassmorphism cards aur frosted navbars ke liye perfect. Effect dikhne ke liye background mein kuch transparency chahiye.
img {
filter: grayscale(100%);
filter: brightness(1.2) contrast(1.1);
filter: blur(4px);
}
/* Glassmorphism */
.glass {
background: rgba(255,255,255,0.1);
backdrop-filter: blur(12px) saturate(180%);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(255,255,255,0.2);
}Lesson 15: Clip & Mask
clip-path
clip-path clips an element into a shape — anything outside is hidden. Use polygon() for custom shapes with vertex coordinates, circle() and ellipse() for round clips, and inset() for rectangles with optional rounded corners. You can animate between two clip-path polygon values for dramatic reveal effects — as long as both have the same number of vertices.
Roman Urdu: clip-path element ko ek shape mein clip karta hai — bahar kuch nahi dikhta. polygon() custom shapes ke liye vertex coordinates se, circle() aur ellipse() round clips ke liye, inset() rectangles ke liye. Do clip-path polygon values ke beech animate kar sakte hain dramatic reveal ke liye — jab tak dono mein vertices ki ginti barabar ho.
.circle { clip-path: circle(50%); }
.triangle { clip-path: polygon(50% 0%, 0% 100%, 100% 100%); }
.slant { clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%); }
.rounded { clip-path: inset(10px round 16px); }
/* Animated reveal */
.reveal { clip-path: inset(0 100% 0 0); transition: clip-path 0.6s ease; }
.reveal.active { clip-path: inset(0 0% 0 0); }Lesson 16: CSS Custom Properties (Variables)
Defining & Using Variables
CSS custom properties store reusable values with a double-dash prefix (--name), accessed via var(). Defined on :root they're globally available. They cascade like normal CSS — child elements can override locally. Unlike SCSS variables, they're live in the browser and can be updated with JavaScript for real-time theming.
Roman Urdu: CSS custom properties double-dash prefix se store hote hain (--name), var() se access hote hain. :root pe define karo to globally available hote hain. Normal CSS ki tarah cascade karte hain — child locally override kar sakta hai. SCSS variables ke brukhaaf yeh browser mein live hain aur JavaScript se real-time theming ke liye update ho sakte hain.
:root {
--color-primary: #6366f1;
--spacing-md: 1rem;
--radius: 8px;
--font-sans: 'Inter', sans-serif;
}
.btn {
background: var(--color-primary);
padding: var(--spacing-md) calc(var(--spacing-md) * 2);
border-radius: var(--radius);
color: var(--color-text, #333); /* fallback */
}
/* Dark theme */
[data-theme="dark"] { --color-primary: #818cf8; }
/* Update from JS: document.documentElement.style.setProperty('--color-primary', '#ff0'); */Lesson 17: Pseudo-classes
State & Structural Pseudo-classes
Pseudo-classes select elements based on their state or DOM position without extra HTML classes. State pseudo-classes (:hover, :focus, :active, :checked, :disabled) respond to user interaction. Structural ones (:nth-child(), :first-child, :last-child, :only-child) target by position. Modern additions :is(), :where(), and :has() are game-changers.
Roman Urdu: Pseudo-classes elements ko unki state ya DOM position ke hisaab se target karte hain bina extra HTML classes ke. State pseudo-classes user interaction se respond karte hain. Structural position se target karte hain. Modern :is(), :where(), aur :has() (parent selector) game-changers hain.
a:hover { color: blue; }
input:focus { outline: 2px solid blue; }
.btn:active { transform: scale(0.98); }
input:disabled { opacity: 0.5; }
li:first-child { font-weight: bold; }
li:last-child { border-bottom: none; }
li:nth-child(2n) { background: #f5f5f5; } /* even rows */
p:not(.intro) { font-size: 0.9rem; }
/* Modern pseudo-classes */
:is(h1, h2, h3) { font-family: serif; }
.card:has(img) { padding: 0; } /* parent selector */
:where(section) p { color: gray; } /* 0 specificity */
a:focus-visible { outline: 3px solid orange; } /* keyboard only */Lesson 18: Pseudo-elements
::before & ::after
Pseudo-elements create virtual sub-elements that don't exist in HTML. ::before inserts content before the element's content, ::after after it. Both require a content property (even if empty ""). They're used for decorative elements, overlays, custom bullets, shape backgrounds, and counter labels — all without extra HTML markup.
Roman Urdu: Pseudo-elements virtual sub-elements banate hain jo HTML mein nahi hote. ::before content se pehle insert karta hai, ::after baad mein. Dono ko content property chahiye (empty "" bhi chal jaata hai). Decorative elements, overlays, custom bullets, shapes, aur counter labels ke liye — bina extra HTML ke.
/* Decorative quote */
blockquote::before { content: '"'; font-size: 4rem; color: #c9a84c; }
/* Dark overlay on hero image */
.hero { position: relative; }
.hero::after {
content: ""; position: absolute; inset: 0;
background: rgba(0,0,0,0.5);
}
/* Read from data attribute */
.badge::after {
content: attr(data-count);
background: red; border-radius: 50%; padding: 2px 6px;
}
Other Pseudo-elements
::placeholder { color: #aaa; font-style: italic; }
::selection { background: #c9a84c; color: white; }
::marker { color: #6366f1; font-size: 1.2em; }
::first-letter { font-size: 3em; float: left; } /* drop cap */
::first-line { font-weight: bold; }Lesson 19: Cascade, Specificity & Inheritance
Specificity Calculation
Specificity is a score determining which CSS rule wins. Calculated as four columns: inline styles (1-0-0-0), IDs (0-1-0-0), classes/attributes/pseudo-classes (0-0-1-0), and type/pseudo-elements (0-0-0-1). Higher score wins. !important overrides all specificity but breaks the cascade — use it only as a last resort. Modern @layer gives explicit control over cascade order.
Roman Urdu: Specificity ek score hai jo decide karta hai kaun sa CSS rule jeete ga. Chaar columns: inline styles (1-0-0-0), IDs (0-1-0-0), classes/attributes/pseudo-classes (0-0-1-0), type/pseudo-elements (0-0-0-1). Zyada score jeeta hai. !important sab override karta hai lekin cascade toot jaata hai — sirf last resort mein use karo. Modern @layer cascade order ka explicit control deta hai.
p { color: gray; } /* 0-0-0-1 */
.text { color: blue; } /* 0-0-1-0 */
#intro { color: green; } /* 0-1-0-0 wins */
p.text { color: red; } /* 0-0-1-1 */
/* Cascade Layers — CSS 2022 */
@layer base, components, utilities;
@layer base { h1 { font-size: 2rem; } }
@layer utilities { .text-xl { font-size: 3rem; } } /* wins */
Inheritance Keywords
Text-related properties inherit by default (color, font-family, line-height). Box-related don't (padding, border, background). Use inherit to force inheritance, initial to reset to browser default, unset to act as either depending on natural behaviour, and revert to restore the browser's user-agent stylesheet value.
Roman Urdu: Text-related properties default mein inherit hoti hain (color, font-family). Box-related nahi hoti (padding, border). inherit se inheritance force karo, initial se browser default par reset karo, unset natural behaviour ke mutabiq kaam karta hai, aur revert browser user-agent stylesheet ki value wapas laata hai.
.child {
color: inherit; /* force inherit from parent */
border: initial; /* browser default */
margin: unset; /* inherit if inheritable, else initial */
padding: revert; /* user-agent stylesheet value */
}
/* Reset all properties on element */
.isolated { all: revert; }Lesson 20: CSS Functions
calc(), min(), max(), clamp()
calc() mixes units in math — perfect for layout. min() picks the smallest value, max() the largest. clamp(min, ideal, max) constrains a fluid value between bounds — the most powerful tool for fluid typography and spacing. env() reads device environment variables like safe-area insets for notched screens. counter() enables CSS-only automatic numbering.
Roman Urdu: calc() mixed units math mein — layout ke liye perfect. min() sabse choti value, max() sabse bari. clamp(min, ideal, max) fluid value ko bounds ke beech constrain karta hai — fluid typography ke liye sabse powerful. env() device environment variables padhta hai notched screens ke liye. counter() CSS-only automatic numbering deta hai.
.sidebar { width: calc(100% - 280px); }
h1 { font-size: clamp(2rem, 5vw, 4rem); }
img { width: min(600px, 100%); }
.content { height: max(200px, 30vh); }
.nav { padding-bottom: env(safe-area-inset-bottom); }
/* CSS counter — automatic numbering */
ol { counter-reset: steps; }
li::before {
counter-increment: steps;
content: counter(steps, decimal-leading-zero);
}
/* CSS logical properties */
.card {
margin-inline: auto; /* left+right in LTR */
padding-block: 1rem; /* top+bottom */
inset-inline-start: 0; /* left in LTR, right in RTL */
}Lesson 21: SCSS Setup & Syntax
What is SCSS & How to Install
SCSS (Sassy CSS) is a CSS preprocessor that compiles to regular CSS. It adds variables, nesting, mixins, functions, and logic. SCSS is a superset of CSS — every valid CSS file is valid SCSS. Install via Node.js, then watch files for automatic compilation. The browser only ever sees plain CSS output.
Roman Urdu: SCSS (Sassy CSS) ek CSS preprocessor hai jo regular CSS mein compile hota hai. Variables, nesting, mixins, functions, aur logic add karta hai. SCSS CSS ka superset hai — har valid CSS valid SCSS hai. Node.js se install karo, phir auto-compilation ke liye files watch karo. Browser sirf plain CSS dekhta hai.
# Install globally
npm install -g sass
# Compile once
sass input.scss output.css
# Watch mode — auto-compile on save
sass --watch scss/:css/
# Compressed output for production
sass --watch scss/:css/ --style=compressed --no-source-map
SCSS File Structure
Organise SCSS into folders. Partial files (prefixed with _) are not compiled on their own — they are meant to be imported. A main main.scss entry file uses @use to pull everything together. This separation keeps styles maintainable as the project grows.
Roman Urdu: SCSS ko folders mein organize karo. Partial files (_ prefix wali) khud compile nahi hote — import ke liye hain. Ek main main.scss entry file @use se sab kuch ek jagah laata hai. Yeh separation project barhne par styles maintainable rakhti hai.
scss/
├── _variables.scss
├── _mixins.scss
├── _components.scss
└── main.scss ← only this compiles
/* main.scss */
@use 'variables';
@use 'mixins';
@use 'components';Lesson 22: Variables & Nesting
SCSS Variables with $
SCSS variables use a $ prefix and store any CSS value. They are resolved at compile time and disappear in the output — unlike CSS custom properties which remain in the browser. This makes them ideal for color palettes, type scales, spacing values, and breakpoints. The !default flag sets a fallback that libraries can override.
Roman Urdu: SCSS variables $ prefix se start hote hain aur koi bhi CSS value store karte hain. Yeh compile time pe resolve hote hain aur output mein nahi ate — CSS custom properties ke brukhaaf jo browser mein rehte hain. Color palettes, type scales, spacing, aur breakpoints ke liye ideal. !default flag fallback set karta hai jo libraries override kar sakti hain.
$primary: #6366f1;
$text: #1a1a2e;
$space: 16px;
$font: 'Inter', sans-serif;
$bp-md: 768px;
$radius: 8px !default; // overridable default
.btn {
background: $primary;
padding: $space calc($space * 2);
border-radius: $radius;
font-family: $font;
}
Nesting & the & Parent Selector
SCSS nesting mirrors HTML structure. The & symbol is the parent selector — use it to write modifier classes (&--dark), state styles (&:hover), and BEM element names (&__title) all inside the parent block. You can also nest media queries inside selectors. Avoid nesting more than 3 levels deep to prevent overly specific selectors.
Roman Urdu: SCSS nesting HTML structure mirror karta hai. & parent selector hai — modifier classes (&--dark), state styles (&:hover), aur BEM element names (&__title) parent block ke andar likhne ke liye. Media queries bhi selectors ke andar nest kar sakte hain. 3 se zyada levels nest karne se selectors bahut specific ho jaate hain.
.card {
padding: 1.5rem;
border-radius: $radius;
&__title { font-size: 1.25rem; font-weight: 700; } // .card__title
&__body { color: #555; }
&--featured { border: 2px solid $primary; } // .card--featured
&:hover { transform: translateY(-4px); }
@media (max-width: $bp-md) { padding: 1rem; } // nested media query
}Lesson 23: Mixins & Functions
@mixin & @include
Mixins are reusable blocks of CSS that accept arguments like function parameters. Define with @mixin, call with @include. Arguments can have default values. Use @content to pass an arbitrary block of styles into the mixin — perfect for responsive breakpoint wrappers. Great for vendor prefixes, component patterns, and anything that repeats.
Roman Urdu: Mixins reusable CSS blocks hain jo function parameters ki tarah arguments accept karte hain. @mixin se define, @include se call. Arguments ke defaults ho sakte hain. @content se mixin mein styles ka block pass karo — responsive breakpoint wrappers ke liye perfect. Vendor prefixes, component patterns, aur repeating patterns ke liye best.
@mixin flex-center($dir: row) {
display: flex; justify-content: center;
align-items: center; flex-direction: $dir;
}
@mixin respond($bp) {
@media (min-width: $bp) { @content; }
}
@mixin button($bg, $color: white) {
background: $bg; color: $color;
padding: 0.6em 1.4em; border-radius: 6px;
&:hover { background: darken($bg, 10%); }
}
.hero { @include flex-center(column); }
.btn-blue { @include button(#3b82f6); }
.sidebar { @include respond(768px) { width: 280px; } }
@function & @return
SCSS functions return a single computed value — unlike mixins which output CSS rules. Use them for math, unit conversion, and color calculations. SCSS includes built-in functions: lighten(), darken(), mix(), percentage(), map.get(). Custom functions use @function and must end with @return.
Roman Urdu: SCSS functions ek computed value return karte hain — mixins ke brukhaaf jo CSS rules output karte hain. Math, unit conversion, aur color calculations ke liye. Built-in functions: lighten(), darken(), mix(), map.get(). Custom functions @function se banate hain aur @return se khatam hone chahiye.
@function rem($px, $base: 16) {
@return calc($px / $base * 1rem);
}
@function spacing($n) { @return $n * 8px; }
.card {
font-size: rem(14); // → 0.875rem
padding: spacing(3); // → 24px
background: lighten($primary, 40%);
border-color: mix(white, $primary, 80%);
}Lesson 24: Partials, Modules & Control Flow
@use & @forward
The modern module system uses @use (loads a file with a namespace) and @forward (re-exports contents for others). This prevents the name collision problems of the old @import. Create an _index.scss barrel file that forwards all partials in a folder — then consumers only need one @use statement to access everything.
Roman Urdu: Modern module system @use (namespace ke saath file load karta hai) aur @forward (doosron ke liye re-export) use karta hai. Yeh purane @import ke name collision problems se bachata hai. Ek _index.scss barrel file banao jo folder ke tamam partials forward kare — phir users ko sirf ek @use ki zarurat hoti hai.
// abstracts/_index.scss
@forward 'variables';
@forward 'mixins';
@forward 'functions';
// components/_button.scss
@use '../abstracts' as a;
.btn { background: a.$primary; @include a.flex-center; }
Control Flow: @if, @each, @for
SCSS has programming-style control flow. @if/@else for conditional output. @each loops over lists or maps — use it with maps to auto-generate utility classes for colors, sizes, and states. @for runs numeric loops for generating spacing scales. This is the core technique behind how CSS frameworks like Bootstrap and Tailwind generate their utility classes.
Roman Urdu: SCSS mein programming-style control flow hai. @if/@else conditional output ke liye. @each lists ya maps par loop karta hai — maps ke saath colors, sizes, states ke utility classes auto-generate karo. @for numeric loops se spacing scales banao. Yahi technique hai jisse Bootstrap aur Tailwind apni utility classes generate karti hain.
// @if / @else
@mixin theme($t) {
@if $t == dark { background: #000; color: #fff; }
@else { background: #fff; color: #000; }
}
// @each — map generates utility classes
$colors: ('primary': #6366f1, 'success': #22c55e, 'danger': #ef4444);
@each $name, $value in $colors {
.text-#{$name} { color: $value; }
.bg-#{$name} { background: $value; }
}
// @for — spacing scale
@for $i from 1 through 8 {
.mt-#{$i} { margin-top: calc($i * 4px); }
.p-#{$i} { padding: calc($i * 4px); }
}Lesson 25: SCSS Architecture
The 7-1 Pattern
The 7-1 pattern organises SCSS into 7 purpose-built folders, all imported into 1 main entry file. Folders: abstracts (tokens, variables, mixins), base (reset, typography), components (buttons, cards, forms), layout (header, grid, sidebar), pages (page-specific overrides), themes (dark mode), and vendors (third-party CSS). This scales cleanly to any project size.
Roman Urdu: 7-1 pattern SCSS ko 7 purpose-built folders mein organise karta hai, sab 1 main entry file mein import hote hain. Folders: abstracts (tokens, variables, mixins), base (reset, typography), components (buttons, cards, forms), layout (header, grid), pages (page-specific overrides), themes (dark mode), aur vendors (third-party CSS). Kisi bhi size project pe cleanly scale karta hai.
scss/
├── abstracts/
│ ├── _tokens.scss // design tokens (colors, spacing)
│ ├── _variables.scss // $vars from tokens
│ ├── _mixins.scss // reusable patterns
│ ├── _functions.scss // rem(), spacing()
│ └── _index.scss // @forward all
├── base/
│ ├── _reset.scss // *, box-sizing
│ └── _typography.scss // h1-h6, body, links
├── components/
│ ├── _button.scss
│ ├── _card.scss
│ └── _form.scss
├── layout/
│ ├── _grid.scss
│ ├── _header.scss
│ └── _footer.scss
├── pages/
│ └── _home.scss
├── themes/
│ └── _dark.scss
├── vendors/
│ └── _normalize.scss
└── main.scss // @use all
Design Tokens + BEM + SCSS
At expert level, combine three approaches: Design Tokens as the single source of truth for all visual values, BEM naming (Block__Element--Modifier) for predictable class structure, and SCSS nesting to keep component code co-located. This is the exact pattern used by large design systems like Material Design, IBM Carbon, and Atlassian Design System.
Roman Urdu: Expert level par teen cheezein combine karo: Design Tokens — tamam visual values ka ek source of truth. BEM naming (Block__Element--Modifier) — predictable class structure ke liye. SCSS nesting — component code ek jagah rakhne ke liye. Yahi pattern Material Design, IBM Carbon, aur Atlassian Design System use karti hain.
// abstracts/_tokens.scss
@use 'sass:map';
$tokens: (
'color-brand-500': #6366f1,
'color-brand-600': #4f46e5,
'space-4': 16px,
'space-8': 32px,
'radius-md': 8px,
);
@function token($key) { @return map.get($tokens, $key); }
// components/_card.scss — BEM + Tokens
.card {
padding: token('space-4');
border-radius: token('radius-md');
&__header { padding-bottom: token('space-4'); }
&__body { color: #555; }
&__footer { border-top: 1px solid #eee; }
&--featured { border: 2px solid token('color-brand-500'); }
&--shadow { box-shadow: 0 4px 24px rgba(0,0,0,.1); }
}
🟣 Course complete! You now understand everything from basic CSS selectors to expert-level SCSS architecture and design token systems. Next steps: JavaScript DOM manipulation, a CSS framework (Tailwind or Bootstrap), and component libraries.