Topic 6: CSS Advance
📖 12 min read · 🎯 intermediate · 🧭 Prerequisites: table-forms-page-layout-introduction, transition-animations
Why this matters
Up until now, your CSS probably gets the job done — but barely. You've wrestled with things not lining up, layouts that look fine on your laptop but break on a phone, or changing one colour and realising you have to hunt it down in fifteen different places. I've been there. That's exactly why advanced CSS exists. Grid, Flexbox, Custom Properties, Media Queries, and precision selectors — these aren't extras. They're the tools that take your pages from "held together with guesswork" to genuinely clean, responsive, and easy to maintain. Let's learn them properly.
What You'll Learn
- Structure two-dimensional layouts with CSS Grid and control both rows and columns
- Use Flexbox to align and distribute items efficiently inside a container
- Define CSS Custom Properties (variables) at the
:rootand reuse them across your stylesheet - Write Media Queries that reshape a layout at specific viewport breakpoints
- Target elements precisely with attribute selectors, pseudo-classes, and pseudo-elements
- Combine all five techniques to build a fully responsive photo gallery
The Analogy
Think of a city's zoning department. CSS Grid is the master city planner who draws a full map — streets running both east–west and north–south — before a single building goes up. Flexbox is the interior architect who arranges furniture inside a room so pieces line up neatly no matter how many chairs you bring. CSS Variables are the paint-swatch standard the city adopts: every building uses --city-blue so repainting the whole town means updating one swatch card. Media Queries are the building codes that say "if the lot is narrower than 500 metres, stack units vertically instead of side by side." And advanced selectors are the inspector's fine-print rules: "only flag signs whose URLs end in .com" or "highlight only the first paragraph of every report."
Chapter 1: CSS Grid Layout
CSS Grid is a two-dimensional layout system — it governs both columns and rows simultaneously. Before Grid, building complex multi-column designs required floats, tables, or fragile position hacks. Grid makes those patterns declarative.
Core properties
| Property | What it does |
|---|---|
display: grid | Turns the element into a grid container |
grid-template-columns | Defines the column track sizes |
gap | Sets gutters between rows and columns |
repeat() | Shorthand for repeated track definitions |
auto-fill / auto-fit | Fills available space with as many tracks as fit |
minmax(min, max) | Sets a track's minimum and maximum size |
Basic named-column grid
.grid-container {
display: grid;
grid-template-columns: auto auto auto;
gap: 10px;
}
.grid-item {
background-color: rgba(255, 255, 255, 0.8);
padding: 20px;
text-align: center;
}
grid-template-columns: auto auto auto creates three equally-sized columns that share available space. The gap property adds 10 px gutters between every cell.
Responsive fluid grid with repeat + minmax
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 10px;
}
auto-fill packs as many 200 px columns as fit; 1fr lets them grow to fill any leftover space. The grid reflows automatically as the viewport widens or narrows — no JavaScript required.
flowchart LR
subgraph Grid Container
A[Item 1] --- B[Item 2] --- C[Item 3]
D[Item 4] --- E[Item 5] --- F[Item 6]
end
style A fill:#ccc
style B fill:#ccc
style C fill:#ccc
style D fill:#ccc
style E fill:#ccc
style F fill:#ccc
Chapter 2: Flexbox Layout
Flexbox is a one-dimensional layout model — it works along a single axis (row or column) at a time. It excels at distributing space among items and aligning them even when their sizes are unknown or dynamic.
Core container properties
| Property | Common values |
|---|---|
display: flex | Activates Flexbox on the container |
justify-content | Aligns items along the main axis |
align-items | Aligns items along the cross axis |
flex-direction | row (default) or column |
flex-wrap | nowrap / wrap — whether items wrap to a new line |
Basic flex container
.flex-container {
display: flex;
justify-content: space-around;
}
.flex-item {
padding: 10px;
}
justify-content: space-around places equal space around each item — half-sized space at the edges, full-sized between items.
Flex vs Grid — when to reach for each
- Grid — when you need two-dimensional control (rows and columns), e.g., a magazine layout or a photo grid.
- Flexbox — when you're aligning items in a single direction, e.g., a navigation bar, a button row, or centering a card.
They complement each other: a Grid container can hold Flex children, and a Flex container can hold Grid children.
Chapter 3: Custom Properties (CSS Variables)
CSS Custom Properties let you store a value once and reference it by name everywhere. When you update the variable, every rule that uses it updates automatically — no search-and-replace required.
Syntax
- Declare a variable with a double-dash prefix:
--variable-name: value; - Use it with the
var()function:var(--variable-name) - Declaring on
:rootmakes a variable globally available across the entire document.
:root {
--main-color: blue;
}
body {
color: var(--main-color);
}
Practical palette example
:root {
--primary: #3a86ff;
--accent: #ff006e;
--gap: 10px;
}
.button-primary {
background-color: var(--primary);
}
.button-accent {
background-color: var(--accent);
}
.grid-container {
gap: var(--gap);
}
Change --primary in one place and every button, badge, and border that references it updates instantly. This makes theming — or a dark-mode toggle — trivially simple.
Chapter 4: Media Queries
Media queries let you apply CSS rules conditionally, based on characteristics of the output device — most commonly viewport width. They are the foundation of responsive design.
Syntax
@media (condition) {
/* rules that apply only when condition is true */
}
Common breakpoint example
@media (max-width: 600px) {
.responsive-text {
font-size: 14px;
}
}
When the viewport is 600 px or narrower, .responsive-text shrinks to 14 px. Above 600 px the rule is ignored entirely.
Gallery breakpoint — single-column on small screens
@media (max-width: 500px) {
.gallery {
grid-template-columns: 1fr;
}
}
On phones the gallery drops to one column; on wider screens the repeat(auto-fill, minmax(200px, 1fr)) rule from Chapter 1 takes over.
Typical breakpoint ladder
/* Mobile-first base styles apply to all screen sizes */
@media (min-width: 600px) {
/* tablet overrides */
}
@media (min-width: 1024px) {
/* desktop overrides */
}
Mobile-first means you write defaults for small screens and progressively add complexity for larger ones — generally easier to maintain than desktop-first.
Chapter 5: Advanced Selectors
CSS offers a rich selector vocabulary beyond plain class and ID selectors. Attribute selectors, pseudo-classes, and pseudo-elements give you surgical precision without touching your HTML.
Attribute Selectors
Target elements based on the presence or value of an HTML attribute.
| Selector | Matches |
|---|---|
[attr] | Elements that have attr at all |
[attr="val"] | Exact value match |
[attr^="val"] | Value starts with val |
[attr$="val"] | Value ends with val |
[attr*="val"] | Value contains val |
/* Highlight links pointing to .com domains */
a[href$=".com"] {
background-color: yellow;
}
Pseudo-Classes
Pseudo-classes describe an element's state or position in the document.
/* Style only the first <p> inside its parent */
p:first-of-type {
color: red;
}
Common pseudo-classes:
:hover— pointer is over the element:focus— element has keyboard/input focus:nth-child(n)— element is the nth child:first-of-type/:last-of-type— first or last element of that tag:not(selector)— elements that do NOT matchselector
Pseudo-Elements
Pseudo-elements let you style a part of an element or inject content without extra markup.
p::first-line {
font-weight: bold;
}
.card::before {
content: "★ ";
color: gold;
}
Common pseudo-elements: ::before, ::after, ::first-line, ::first-letter, ::placeholder, ::selection.
Chapter 6: Putting It Together — Responsive Photo Gallery
The following task assembles Grid, Flexbox, Media Queries, and Custom Properties into one working page.
HTML scaffold
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Advanced CSS Gallery</title>
<link rel="stylesheet" href="gallery.css" />
</head>
<body>
<div class="gallery">
<div class="photo">Photo 1</div>
<div class="photo">Photo 2</div>
<div class="photo">Photo 3</div>
<!-- Add more photos as needed -->
</div>
</body>
</html>
Step 1 — Grid layout for the gallery
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 10px;
}
.photo {
background-color: #ccc;
height: 200px;
display: flex;
justify-content: center;
align-items: center;
font-size: 20px;
}
Each .photo card is itself a Flex container — using justify-content: center and align-items: center to perfectly centre its label text in both axes.
Step 2 — Media query for small screens
@media (max-width: 500px) {
.gallery {
grid-template-columns: 1fr;
}
}
On viewports narrower than 500 px the gallery collapses to a single column stack, preventing horizontal overflow on phones.
Full stylesheet with CSS variables added
:root {
--card-bg: #cccccc;
--card-height: 200px;
--gap: 10px;
--min-col: 200px;
}
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(var(--min-col), 1fr));
gap: var(--gap);
}
.photo {
background-color: var(--card-bg);
height: var(--card-height);
display: flex;
justify-content: center;
align-items: center;
font-size: 20px;
}
@media (max-width: 500px) {
.gallery {
grid-template-columns: 1fr;
}
}
Swapping --card-bg or --min-col in :root instantly repaints the entire gallery — one variable, zero repetition.
🧪 Try It Yourself
Task: Build the responsive photo gallery above from scratch.
- Create
index.htmlwith the scaffold from Chapter 6. - Create
gallery.cssand paste the full stylesheet. - Open
index.htmlin your browser and resize the window slowly.
Success criteria:
- At full width you see multiple columns (three or more on a 1200 px screen).
- Drag the browser window narrower than 500 px — the gallery collapses to a single column.
- In DevTools, change
--card-bgin:rootto#3a86ffand verify all cards turn blue instantly.
Starter HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>My Gallery</title>
<link rel="stylesheet" href="gallery.css" />
</head>
<body>
<div class="gallery">
<div class="photo">Photo 1</div>
<div class="photo">Photo 2</div>
<div class="photo">Photo 3</div>
<div class="photo">Photo 4</div>
<div class="photo">Photo 5</div>
<div class="photo">Photo 6</div>
</div>
</body>
</html>
🔍 Checkpoint Quiz
Q1. Why would you declare a Custom Property on :root rather than on a specific selector like .gallery?
A) Because :root selectors have lower specificity and are easier to override
B) Because variables declared on :root are globally available to every element in the document
C) Because CSS variables only work on the root element
D) Because it makes the file load faster
Q2. Given this CSS, what happens when the viewport is 480 px wide?
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 10px;
}
@media (max-width: 500px) {
.gallery {
grid-template-columns: 1fr;
}
}
A) The gallery shows three fixed 200 px columns
B) The gallery shows one column that takes the full width
C) The gallery hides all .photo items
D) The gap property is removed
Q3. What does the selector a[href$=".com"] match?
A) All anchor tags on the page
B) Anchor tags whose href attribute contains .com anywhere in the value
C) Anchor tags whose href attribute ends with .com
D) Anchor tags whose href attribute starts with .com
Q4. You have a navigation bar where all links must sit side by side and be evenly spaced. Which CSS layout system is the most direct fit, and what property controls the spacing?
A) CSS Grid with grid-template-columns: repeat(auto-fill, 1fr)
B) Flexbox with justify-content: space-between (or space-around) on the container
C) Absolute positioning with left offsets on each link
D) CSS Grid with align-items: center
A1. B — :root is the top-level element, so variables declared there cascade down to every child element in the document, making them globally available.
A2. B — At 480 px the @media (max-width: 500px) condition is true, so grid-template-columns: 1fr overrides the multi-column rule and the gallery collapses to one full-width column.
A3. C — The $= attribute selector operator matches elements whose attribute value ends with the given string, so only href values ending in .com are selected.
A4. B — Flexbox is designed for single-axis alignment of items inside a container. justify-content: space-between or space-around distributes the available space between or around the nav links without any column math.
🪞 Recap
- CSS Grid controls two-dimensional layouts using
grid-template-columns,gap, andrepeat(auto-fill, minmax()). - Flexbox handles one-dimensional alignment — distributing and centering items along a row or column axis.
- CSS Custom Properties declared on
:rootact as named tokens you can reuse and update across the entire stylesheet. - Media queries apply rules conditionally at breakpoints, enabling layouts to reflow for mobile, tablet, and desktop.
- Attribute selectors (
[href$=".com"]), pseudo-classes (:first-of-type,:hover), and pseudo-elements (::before,::after) give you fine-grained control without extra HTML.
📚 Further Reading
- CSS Grid Layout — MDN — the authoritative reference for every Grid property and value
- A Complete Guide to Flexbox — CSS-Tricks — the most-bookmarked Flexbox cheat-sheet on the web
- Using CSS Custom Properties — MDN — covers variable scope, fallbacks, and JavaScript interop
- Responsive Design with Media Queries — MDN — mobile-first strategy and common breakpoint patterns
- CSS Selectors Reference — MDN — complete list of attribute selectors, pseudo-classes, and pseudo-elements
- ⬅️ Previous: Transition & Animations
- ➡️ Next: DIV Page Design