CSS Tutorial - Complete Guide
CSS (Cascading Style Sheets) controls the visual appearance of HTML elements - colors, layout, typography, animations, and responsive design.
What is CSS?
CSS stands for Cascading Style Sheets. It is used to style and lay out web pages. "Cascading" means that multiple style rules can apply to one element and they cascade (combine) based on specificity and order.
/* Applies green background to all paragraphs */
p {
background-color: #e8f5e9;
color: #1b5e20;
padding: 10px;
border-radius: 5px;
}
CSS Syntax & Selectors
/* selector { property: value; } */
/* Element selector */
h1 { color: #04AA6D; }
/* Class selector */
.highlight { background: yellow; }
/* ID selector */
#navbar { background: #282A35; }
/* Universal selector */
* { box-sizing: border-box; }
/* Group selector */
h1, h2, h3 { font-family: Arial; }
/* Descendant selector */
nav a { color: white; }
/* Child selector (direct child only) */
ul > li { list-style: square; }
/* Adjacent sibling */
h2 + p { font-size: 18px; }
/* General sibling */
h2 ~ p { color: #555; }
/* Attribute selector */
input[type="email"] { border: 2px solid blue; }
a[href^="https"] { color: green; } /* starts with */
a[href$=".pdf"] { color: red; } /* ends with */
a[href*="edu"] { font-weight: bold; } /* contains */
How to Add CSS
<!-- 1. External (Recommended) -->
<link rel="stylesheet" href="style.css">
<!-- 2. Internal -->
<style>
body { background: #f4f4f4; }
</style>
<!-- 3. Inline (avoid for maintenance) -->
<p style="color: red; padding: 10px;">Inline styled paragraph</p>
CSS Colors
/* Named */
color: tomato;
/* HEX */
color: #04AA6D;
background-color: #282A35;
/* RGB / RGBA */
color: rgb(4, 170, 109);
color: rgba(4, 170, 109, 0.5); /* 50% opacity */
/* HSL / HSLA */
color: hsl(148, 95%, 34%);
color: hsla(148, 95%, 34%, 0.8);
/* CSS color keywords */
color: currentColor; /* inherits from parent */
color: inherit;
color: transparent;
CSS Backgrounds
.box {
background-color: #f4f4f4;
background-image: url("pattern.png");
background-repeat: no-repeat; /* repeat | repeat-x | repeat-y */
background-position: center center;
background-size: cover; /* cover | contain | 200px 100px */
background-attachment: fixed; /* fixed | scroll | local */
background-origin: border-box;
background-clip: padding-box;
/* Shorthand */
background: #f4f4f4 url("bg.svg") no-repeat center/cover;
/* Multiple backgrounds */
background: url("overlay.png") center/cover,
url("pattern.svg") repeat,
#282A35;
}
CSS Borders
.box {
border: 2px solid #04AA6D; /* shorthand: width style color */
border-top: 3px dashed red;
border-radius: 10px; /* rounded corners */
border-radius: 50%; /* circle */
border-radius: 10px 5px 10px 5px; /* TL TR BR BL */
/* Outline (doesn't take up space) */
outline: 2px solid blue;
outline-offset: 4px;
}
CSS Margins
.box {
margin: 20px; /* all sides */
margin: 10px 20px; /* top/bottom left/right */
margin: 5px 10px 15px 20px; /* top right bottom left */
margin-top: 10px;
margin-right: 20px;
margin-bottom: 10px;
margin-left: 20px;
margin: 0 auto; /* center block horizontally */
}
CSS Padding
Padding creates inner space between the content and the border. Same syntax as margin.
.card {
padding: 20px;
padding: 10px 24px; /* vertical horizontal */
padding: 5px 10px 15px 10px; /* top right bottom left */
}
CSS Box Model
Every HTML element is a rectangular box made up of: content ? padding ? border ? margin.
? margin ?
.box {
width: 300px; /* content width */
padding: 20px;
border: 2px solid;
margin: 10px;
/* Total width = 300 + 20*2 + 2*2 + 10*2 = 364px */
}
/* Border-box: width INCLUDES padding and border */
* { box-sizing: border-box; }
.box {
width: 300px; /* total width = 300px */
padding: 20px; /* content width = 300 - 40 = 260px */
}
CSS Text Styling
p {
color: #333;
font-size: 16px; /* px, em, rem, %, vw */
font-weight: bold; /* 100-900, normal, bold */
font-style: italic;
text-align: center; /* left | right | center | justify */
text-decoration: underline; /* none | underline | line-through | overline */
text-transform: uppercase; /* uppercase | lowercase | capitalize */
text-indent: 30px;
line-height: 1.6;
letter-spacing: 2px;
word-spacing: 5px;
white-space: nowrap; /* normal | nowrap | pre | pre-wrap */
text-overflow: ellipsis; /* clips overflowing text with - */
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
direction: ltr; /* ltr | rtl */
}
CSS Fonts
/* Google Fonts */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');
body {
font-family: 'Inter', 'Segoe UI', Arial, sans-serif;
}
/* @font-face (custom font file) */
@font-face {
font-family: 'MyFont';
src: url('myfont.woff2') format('woff2'),
url('myfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}
/* Font shorthand: style variant weight size/line-height family */
p { font: italic small-caps bold 16px/1.6 Arial, sans-serif; }
/* CSS Units for font-size */
h1 { font-size: 36px; } /* absolute pixels */
h2 { font-size: 2rem; } /* 2- root font size (16px ? 32px) */
h3 { font-size: 1.5em; } /* 1.5- parent font size */
p { font-size: 100%; } /* % of parent */
p { font-size: 2vw; } /* 2% of viewport width */
CSS Display & Visibility
/* Display values */
display: block; /* full width, new line */
display: inline; /* flows in text, no width/height */
display: inline-block; /* inline but can have width/height */
display: flex; /* flex container */
display: grid; /* grid container */
display: none; /* removes from layout completely */
display: table; /* table behaviour */
display: contents; /* removes wrapper box */
/* Visibility (still takes up space) */
visibility: visible;
visibility: hidden; /* invisible but space remains */
/* Opacity */
opacity: 0; /* 0=transparent, 1=opaque */
opacity: 0.5; /* 50% transparent */
CSS Position
/* static (default) - normal flow */
.box { position: static; }
/* relative - offset from normal position, does NOT remove from flow */
.box { position: relative; top: 20px; left: 10px; }
/* absolute - removed from flow, positioned relative to nearest positioned parent */
.container { position: relative; }
.child { position: absolute; top: 0; right: 0; }
/* fixed - relative to viewport, stays on scroll */
.sticky-btn { position: fixed; bottom: 20px; right: 20px; }
/* sticky - relative until scroll threshold, then fixed */
nav { position: sticky; top: 0; z-index: 100; }
/* z-index: controls stacking order (higher = on top) */
.modal { z-index: 1000; }
.overlay { z-index: 999; }
CSS Flexbox
Flexbox is a 1D layout system for arranging items in a row or column.
/* Container */
.flex-container {
display: flex;
flex-direction: row; /* row | column | row-reverse | column-reverse */
flex-wrap: wrap; /* nowrap | wrap | wrap-reverse */
justify-content: center; /* flex-start | flex-end | center | space-between | space-around | space-evenly */
align-items: center; /* stretch | flex-start | flex-end | center | baseline */
align-content: space-between; /* for multi-line wrapping */
gap: 20px; /* shorthand for row-gap + column-gap */
}
/* Flex Items */
.item {
flex: 1; /* flex-grow flex-shrink flex-basis shorthand */
flex-grow: 1; /* how much item grows relative to others */
flex-shrink: 0; /* prevent shrinking */
flex-basis: 200px; /* initial size before growing/shrinking */
align-self: flex-end; /* override parent align-items for this item */
order: 2; /* change visual order */
}
CSS Grid
CSS Grid is a 2D layout system - rows AND columns simultaneously.
/* Container */
.grid {
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* 3 columns */
grid-template-columns: repeat(3, 1fr); /* same shorthand */
grid-template-columns: 200px auto 1fr; /* mixed units */
grid-template-rows: 80px auto 60px;
gap: 20px; /* row-gap column-gap */
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer";
}
/* Items */
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
/* Span across columns/rows */
.hero { grid-column: 1 / 3; } /* spans columns 1-2 */
.hero { grid-column: 1 / -1; } /* spans all columns */
.tall { grid-row: 1 / span 2; } /* spans 2 rows */
/* Responsive auto-fill */
.cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 20px;
}
CSS Media Queries
/* Mobile-first approach */
.container { width: 100%; padding: 15px; }
/* Tablet (=600px) */
@media (min-width: 600px) {
.container { max-width: 750px; margin: 0 auto; }
.grid { grid-template-columns: 1fr 1fr; }
}
/* Desktop (=1024px) */
@media (min-width: 1024px) {
.grid { grid-template-columns: repeat(3, 1fr); }
.sidebar { display: block; }
}
/* Max-width (desktop-first) */
@media (max-width: 768px) {
.nav-links { display: none; }
.hamburger { display: block; }
}
/* Orientation */
@media (orientation: landscape) { ... }
@media (orientation: portrait) { ... }
/* Print styles */
@media print {
.sidebar, nav, footer { display: none; }
body { font-size: 12pt; color: black; }
}
Pseudo-classes & Pseudo-elements
/* Pseudo-classes (single colon) */
a:hover { color: #04AA6D; }
a:visited { color: purple; }
a:active { color: red; }
a:focus { outline: 2px solid #04AA6D; }
li:first-child { font-weight: bold; }
li:last-child { border-bottom: none; }
li:nth-child(2) { background: #e8f5e9; }
li:nth-child(odd) { background: #f9f9f9; }
li:nth-child(3n) { color: red; } /* every 3rd */
p:not(.special) { color: #555; }
input:disabled { opacity: 0.5; }
input:checked { accent-color: #04AA6D; }
input:valid { border-color: green; }
input:invalid { border-color: red; }
input:placeholder-shown { border: 2px dashed #ccc; }
/* Pseudo-elements (double colon) */
p::first-letter { font-size: 2em; float: left; }
p::first-line { font-weight: bold; }
.box::before { content: "? "; color: #04AA6D; }
.box::after { content: " ?"; }
::selection { background: #04AA6D; color: white; }
::placeholder { color: #aaa; font-style: italic; }
CSS Custom Properties (Variables)
/* Define variables on :root (global) */
:root {
--primary: #04AA6D;
--dark: #282A35;
--font-size: 16px;
--spacing: 20px;
--radius: 5px;
}
/* Use variables */
.btn {
background: var(--primary);
font-size: var(--font-size);
padding: var(--spacing);
border-radius: var(--radius);
}
/* Fallback value */
color: var(--highlight, yellow);
/* Override for a scope */
.dark-theme {
--primary: #80cbc4;
--dark: #fff;
}
/* Update with JavaScript */
document.documentElement.style.setProperty('--primary', '#ff6347');
CSS Animations
/* Step 1: Define keyframes */
@keyframes fadeIn {
from { opacity: 0; transform: translateY(-20px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
@keyframes spin {
to { transform: rotate(360deg); }
}
/* Step 2: Apply animation */
.card {
animation: fadeIn 0.5s ease-out;
}
.loader {
animation: spin 1s linear infinite;
}
.btn:hover {
animation: pulse 0.4s ease;
}
/* Full shorthand:
name | duration | timing-function | delay | iteration-count | direction | fill-mode */
.element {
animation: fadeIn 1s ease-in-out 0.2s 1 normal forwards;
}
/* Multiple animations */
.element {
animation: fadeIn 1s ease, pulse 2s infinite;
}
CSS Transitions
.btn {
background: #04AA6D;
padding: 10px 20px;
border-radius: 5px;
/* property | duration | timing-function | delay */
transition: background 0.3s ease, transform 0.2s ease;
}
.btn:hover {
background: #028a57;
transform: translateY(-2px);
}
/* Transition all properties */
.card { transition: all 0.3s ease; }
/* Timing functions */
transition-timing-function: ease;
transition-timing-function: linear;
transition-timing-function: ease-in;
transition-timing-function: ease-out;
transition-timing-function: ease-in-out;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); /* Material Design */
CSS Transforms
/* 2D Transforms */
transform: translate(50px, 20px); /* move X Y */
transform: translateX(50px);
transform: translateY(-20px);
transform: scale(1.2); /* scale uniformly */
transform: scaleX(2); /* scale X axis */
transform: rotate(45deg); /* clockwise rotation */
transform: skew(20deg, 10deg);
/* Multiple transforms (applied right to left) */
transform: rotate(30deg) translateX(100px) scale(0.8);
/* 3D Transforms */
perspective: 1000px; /* on parent */
transform: rotateX(30deg);
transform: rotateY(45deg);
transform: rotateZ(360deg);
transform: translateZ(100px);
transform: rotate3d(1, 1, 0, 45deg);
/* Transform origin */
transform-origin: top left;
transform-origin: center center;
CSS Overflow
.box {
width: 200px; height: 100px;
overflow: visible; /* default - overflows */
overflow: hidden; /* clips content */
overflow: scroll; /* always shows scrollbar */
overflow: auto; /* scrollbar only when needed */
overflow-x: hidden; /* hide horizontal overflow */
overflow-y: auto; /* vertical scroll when needed */
/* Truncate text with ellipsis */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
CSS Shadows
/* Box shadow: offset-x offset-y blur spread color */
.card {
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
box-shadow: 0 4px 20px rgba(4,170,109,0.3);
box-shadow: inset 0 2px 5px rgba(0,0,0,0.15); /* inset */
/* Multiple shadows */
box-shadow: 0 2px 4px rgba(0,0,0,.1), 0 8px 24px rgba(0,0,0,.2);
}
/* Text shadow: offset-x offset-y blur color */
h1 { text-shadow: 2px 2px 4px rgba(0,0,0,0.3); }
h1 { text-shadow: 0 0 10px #04AA6D; } /* glow */
CSS Gradients
/* Linear gradient */
background: linear-gradient(to right, #04AA6D, #282A35);
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
background: linear-gradient(to bottom, #fff 0%, #f4f4f4 100%);
/* Radial gradient */
background: radial-gradient(circle, #04AA6D, #282A35);
background: radial-gradient(circle at 30% 30%, #fff 0%, #04AA6D 100%);
/* Conic gradient */
background: conic-gradient(red, yellow, green, blue, red);
/* Repeating gradients */
background: repeating-linear-gradient(45deg, #fff 0px, #fff 10px, #f4f4f4 10px, #f4f4f4 20px);
CSS Specificity
When multiple rules target the same element, specificity determines which wins.
| Selector | Specificity | Example |
|---|---|---|
| Inline style | 1,0,0,0 (highest) | style="color:red" |
| ID selector | 0,1,0,0 | #main |
| Class, attribute, pseudo-class | 0,0,1,0 | .btn, :hover |
| Element selector | 0,0,0,1 (lowest) | p, div |
!important | Overrides everything | color: red !important |
Advanced CSS Selectors
/* :is() - matches any in list */
:is(h1, h2, h3) { color: #282A35; }
/* :where() - same as :is() but zero specificity */
:where(header, footer) a { color: white; }
/* :has() - parent selector (CSS4) */
.card:has(img) { padding: 0; }
label:has(+ input:required)::after { content: " *"; color: red; }
/* :not() */
li:not(:last-child) { border-bottom: 1px solid #e0e0e0; }
/* :focus-visible - keyboard focus only */
button:focus-visible { outline: 2px solid #04AA6D; }
/* :empty */
p:empty { display: none; }
/* Substring attribute selectors */
[class^="icon-"] { /* starts with */ }
[class$="-large"] { /* ends with */ }
[class*="arrow"] { /* contains */ }
CSS Best Practices
- Use
box-sizing: border-boxglobally. - Use CSS custom properties (variables) for colors and spacing.
- Mobile-first approach with
min-widthmedia queries. - Keep specificity low - prefer classes over IDs for styling.
- Avoid
!important- it creates maintenance problems. - Use Flexbox for 1D layouts, CSS Grid for 2D layouts.
- Group related properties logically (layout, then typography, then visual).
- Use meaningful class names (BEM methodology:
.block__element--modifier). - Use
transitionon hover effects for smooth UI. - Minimize selector nesting depth (max 2-3 levels).
Quick Quiz: Which CSS property centers a flex container's items horizontally?
CSS Architecture
As projects grow, CSS problems usually come from naming and structure rather than syntax. Students should learn how to organize styles before they build larger interfaces.
| Approach | Idea | When to use it |
|---|---|---|
| BEM | Component naming using blocks, elements, and modifiers | Large component libraries |
| Utility-first | Small classes for spacing, layout, color, and state | Fast prototyping and design systems |
| Layered CSS | Split reset, base, components, utilities, and overrides | Teams that need predictable override rules |
@layer reset, base, components, utilities;
@layer base {
body { font-family: Inter, sans-serif; }
}
@layer components {
.pricing-card { border-radius: 20px; padding: 24px; }
}
@layer utilities {
.text-center { text-align: center; }
}
Container Queries
Media queries respond to the viewport. Container queries respond to the size of the parent component. This is powerful when the same card or widget appears in different parts of a layout.
.card-list {
container-type: inline-size;
}
.card {
display: grid;
gap: 16px;
}
@container (min-width: 480px) {
.card {
grid-template-columns: 120px 1fr;
align-items: center;
}
}
Cascade Layers
Cascade layers let you declare which group of styles should win, even before specificity is compared. This reduces the need for !important and makes overrides more predictable.