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.

Key Benefit CSS separates presentation from content, making it easy to change the look of an entire website by editing one stylesheet file.
CSS
/* Applies green background to all paragraphs */
p {
  background-color: #e8f5e9;
  color: #1b5e20;
  padding: 10px;
  border-radius: 5px;
}
► Try It Yourself

CSS Syntax & Selectors

CSS Syntax
/* 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 */
► Try It Yourself

How to Add CSS

HTML
<!-- 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>
► Try It Yourself

CSS Colors

CSS
/* 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;
► Try It Yourself

CSS Backgrounds

CSS
.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;
}
► Try It Yourself

CSS Borders

CSS
.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;
}
► Try It Yourself
Border Examples
solid
dashed
dotted
double
circle

CSS Margins

CSS
.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 */
}
► Try It Yourself

CSS Padding

Padding creates inner space between the content and the border. Same syntax as margin.

CSS
.card {
  padding: 20px;
  padding: 10px 24px;          /* vertical horizontal */
  padding: 5px 10px 15px 10px; /* top right bottom left */
}
► Try It Yourself

CSS Box Model

Every HTML element is a rectangular box made up of: content ? padding ? border ? margin.

Content
? padding ?
? border ?
? margin ?
CSS
.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 */
}
► Try It Yourself

CSS Text Styling

CSS
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 */
}
► Try It Yourself

CSS Fonts

CSS
/* 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 */
► Try It Yourself

CSS Display & Visibility

CSS
/* 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 */
► Try It Yourself

CSS Position

CSS
/* 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; }
► Try It Yourself

CSS Flexbox

Flexbox is a 1D layout system for arranging items in a row or column.

CSS Flexbox
/* 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 */
}
► Try It Yourself
Flexbox Demo
Item 1
Item 2 (flex:2)
Item 3

CSS Grid

CSS Grid is a 2D layout system - rows AND columns simultaneously.

CSS Grid
/* 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;
}
► Try It Yourself
Grid Example
header (full width)
sidebar
main content
footer

CSS Media Queries

CSS
/* 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; }
}
► Try It Yourself

Pseudo-classes & Pseudo-elements

CSS
/* 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; }
► Try It Yourself

CSS Custom Properties (Variables)

CSS
/* 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');
► Try It Yourself

CSS Animations

CSS
/* 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;
}
► Try It Yourself
Animation Demo

CSS Transitions

CSS
.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 */
► Try It Yourself

CSS Transforms

CSS
/* 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;
► Try It Yourself

CSS Overflow

CSS
.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;
}
► Try It Yourself

CSS Shadows

CSS
/* 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 */
► Try It Yourself

CSS Gradients

CSS
/* 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);
► Try It Yourself
Gradient Demos

CSS Specificity

When multiple rules target the same element, specificity determines which wins.

SelectorSpecificityExample
Inline style1,0,0,0 (highest)style="color:red"
ID selector0,1,0,0#main
Class, attribute, pseudo-class0,0,1,0.btn, :hover
Element selector0,0,0,1 (lowest)p, div
!importantOverrides everythingcolor: red !important

Advanced CSS Selectors

CSS
/* :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 */ }
► Try It Yourself

CSS Best Practices

  • Use box-sizing: border-box globally.
  • Use CSS custom properties (variables) for colors and spacing.
  • Mobile-first approach with min-width media 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 transition on 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.

ApproachIdeaWhen to use it
BEMComponent naming using blocks, elements, and modifiersLarge component libraries
Utility-firstSmall classes for spacing, layout, color, and stateFast prototyping and design systems
Layered CSSSplit reset, base, components, utilities, and overridesTeams that need predictable override rules
CSS
@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.

CSS
.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.

Rule of thumb Put resets first, then base styles, then components, then utilities, then emergency overrides.