CSS Explained: Complete Beginner to Advanced Guide 2026
CSS (Cascading Style Sheets) is the language that makes the web beautiful. It controls every visual aspect of a web page — colors, fonts, layouts, animations, and responsive behavior. Whether you are just starting out or want to solidify your understanding of modern CSS, this complete guide covers everything from the basics to advanced techniques used in production today.
3
CSS versions (CSS1, CSS2, CSS3+)
500+
CSS properties available
98%
browser support for Flexbox
96%
browser support for CSS Grid
What is CSS and How Does it Work?
CSS stands for Cascading Style Sheets. The word "cascading" means that styles apply in a specific order of priority, with later rules overriding earlier ones. CSS works by selecting HTML elements and applying visual rules to them.
There are three ways to add CSS to an HTML document:
| Item | Method | When to use |
|---|---|---|
| External stylesheet | <link rel="stylesheet" href="styles.css"> | Always — best practice for reusability and caching. |
| Internal style tag | <style>body { color: red; }</style> | Quick prototypes or email HTML templates. |
| Inline style | <p style="color:red">...</p> | Dynamic styles from JavaScript, or single-element overrides. |
CSS Selectors
Selectors are patterns that match HTML elements. They are the most important part of CSS to master — without the right selector, your styles will not reach the right elements.
/* Universal selector — matches everything */
* { box-sizing: border-box; }
/* Type selector — matches all <p> elements */
p { line-height: 1.6; }
/* Class selector — matches elements with class="card" */
.card { border-radius: 8px; }
/* ID selector — matches element with id="header" */
#header { background: #1a1a2e; }
/* Attribute selector — matches <input type="email"> */
input[type="email"] { border: 2px solid blue; }
/* Descendant — <a> inside .nav */
.nav a { text-decoration: none; }
/* Child — direct <li> children of <ul> only */
ul > li { padding: 8px; }
/* Adjacent sibling — <p> immediately after <h2> */
h2 + p { font-size: 1.1rem; }
/* Pseudo-class — link on hover */
a:hover { color: royalblue; }
/* Pseudo-element — first line of a paragraph */
p::first-line { font-weight: bold; }Specificity determines which rule wins
The CSS Box Model
Quick fact
Every HTML element is a rectangular box. Understanding the box model is the foundation of all CSS layout work.
The box model describes how every element is rendered as a box with four layers: Content, Padding, Border, and Margin.
.box {
width: 200px;
height: 100px;
padding: 16px;
border: 2px solid #333;
border-radius: 8px;
margin: 24px;
}
/* box-sizing: border-box makes width include padding+border */
* {
box-sizing: border-box;
}Without border-box (confusing)
/* Without border-box: element overflows its container */
.card {
width: 300px;
padding: 20px;
border: 2px solid black;
/* Actual rendered width: 300 + 40 + 4 = 344px */
}With border-box (predictable)
/* With border-box: padding and border included in width */
*, *::before, *::after {
box-sizing: border-box;
}
.card {
width: 300px;
padding: 20px;
border: 2px solid black;
/* Actual rendered width: 300px exactly */
}CSS Flexbox
Flexbox is a one-dimensional layout system — it arranges items in a row or column. It is the best tool for navigation bars, card rows, centering content, and any layout where items need to flex and wrap.
/* Make a container a flex container */
.container {
display: flex;
flex-direction: row; /* row | column */
flex-wrap: wrap; /* wrap items to next line */
justify-content: space-between; /* main-axis alignment */
align-items: center; /* cross-axis alignment */
gap: 16px;
}
/* Flex item properties */
.item {
flex: 1 0 200px; /* grow shrink basis */
align-self: flex-end;
}
/* Center anything perfectly */
.centered {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}CSS Grid
CSS Grid is a two-dimensional layout system — it manages rows AND columns simultaneously. Use Grid for page-level layouts: headers, sidebars, content areas, and complex responsive designs.
/* Responsive grid with auto-fill */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;
}
/* Named grid areas */
.page-layout {
display: grid;
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer";
grid-template-columns: 250px 1fr 1fr;
grid-template-rows: 60px 1fr 80px;
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
/* Span multiple cells */
.featured-card {
grid-column: span 2;
grid-row: span 2;
}CSS Positioning
| Item | Position value | Behavior |
|---|---|---|
| static | static (default) | Normal document flow. top/left/right/bottom have no effect. |
| relative | relative | Offset from its normal position. Other elements are unaffected. |
| absolute | absolute | Removed from flow. Positioned relative to nearest non-static ancestor. |
| fixed | fixed | Removed from flow. Positioned relative to viewport. Stays on scroll. |
| sticky | sticky | Normal flow until scroll threshold, then fixed. Great for headers. |
/* Sticky navigation bar */
.navbar {
position: sticky;
top: 0;
z-index: 100;
background: white;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
/* Badge on a card */
.card { position: relative; }
.badge {
position: absolute;
top: -8px;
right: -8px;
background: red;
border-radius: 50%;
width: 24px;
height: 24px;
}Responsive Design and Media Queries
Quick fact
Mobile-first CSS means writing your base styles for small screens, then using media queries to add complexity for larger screens.
/* Mobile-first base styles */
.card-grid {
display: grid;
grid-template-columns: 1fr;
gap: 16px;
}
/* Tablet: 768px and up */
@media (min-width: 768px) {
.card-grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* Desktop: 1024px and up */
@media (min-width: 1024px) {
.card-grid {
grid-template-columns: repeat(3, 1fr);
}
}
/* Dark mode preference */
@media (prefers-color-scheme: dark) {
body { background: #0f0f0f; color: #f5f5f5; }
}
/* Reduced motion preference */
@media (prefers-reduced-motion: reduce) {
* { animation: none !important; transition: none !important; }
}CSS Custom Properties (Variables)
/* Declare variables on :root for global scope */
:root {
--color-primary: #3b82f6;
--color-text: #1f2937;
--spacing-md: 16px;
--border-radius: 8px;
--shadow-md: 0 4px 6px -1px rgba(0,0,0,0.1);
}
.button {
background: var(--color-primary);
padding: var(--spacing-md);
border-radius: var(--border-radius);
}
/* Override for dark mode */
@media (prefers-color-scheme: dark) {
:root {
--color-primary: #60a5fa;
--color-text: #f9fafb;
}
}CSS Animations and Transitions
/* Smooth hover transition */
.button {
background: #3b82f6;
transform: scale(1);
transition: background 0.2s ease, transform 0.15s ease;
}
.button:hover {
background: #1d4ed8;
transform: scale(1.05);
}
/* Keyframe animation */
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.card {
animation: fadeInUp 0.4s ease forwards;
}
/* Stagger children */
.card:nth-child(1) { animation-delay: 0ms; }
.card:nth-child(2) { animation-delay: 100ms; }
.card:nth-child(3) { animation-delay: 200ms; }
/* Spinning loader */
@keyframes spin {
to { transform: rotate(360deg); }
}
.loader {
width: 32px;
height: 32px;
border: 3px solid #e5e7eb;
border-top-color: #3b82f6;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}Modern CSS Features (2024-2026)
:has() selector
Parent selector — style a parent based on its children. .card:has(img) targets cards that contain an image.
CSS Container Queries
Style elements based on their container size instead of viewport size. Perfect for truly reusable components.
CSS Nesting
Write nested selectors directly in CSS (like Sass), now supported natively in all modern browsers.
color-mix()
Mix two colors in CSS: color-mix(in srgb, blue 30%, white) creates a light blue tint.
CSS Layers (@layer)
Explicitly control cascade layers, making it easier to manage third-party styles vs. your own styles.
Logical properties
margin-inline-start instead of margin-left — works correctly for both LTR and RTL languages.
/* :has() — parent selector */
.form-group:has(input:invalid) { border-color: red; }
/* Container queries */
.card-wrapper { container-type: inline-size; }
@container (min-width: 400px) {
.card { flex-direction: row; }
}
/* CSS Nesting (native, no Sass needed) */
.nav {
display: flex;
gap: 16px;
& a {
text-decoration: none;
&:hover { color: royalblue; }
}
}
/* CSS @layer */
@layer reset, base, components, utilities;
@layer reset {
* { margin: 0; padding: 0; box-sizing: border-box; }
}CSS Specificity and the Cascade
| Item | Selector | Specificity score |
|---|---|---|
| * | * (universal) | 0,0,0,0 — lowest possible |
| p | p (type) | 0,0,0,1 |
| .class | .card (class) | 0,0,1,0 |
| #id | #header (ID) | 0,1,0,0 |
| inline | style="..." | 1,0,0,0 — highest |
| !important | !important | Overrides everything — use sparingly |
Frequently Asked Questions
CSS mastery comes from practice