By the end of this lesson, you will be able to:
Welcome to the world of advanced CSS layouts! Today we'll explore CSS Grid, the most powerful layout system in CSS. We'll also discover modern CSS features that make our code cleaner and easier to maintain.
:information_source: CSS Grid is a two-dimensional layout system that lets you create complex layouts with rows and columns. Unlike Flexbox (which works in one direction), Grid gives you control over both horizontal and vertical positioning.
:bulb: Tip Think of Flexbox as arranging items in a line (horizontal or vertical), while Grid arranges items in rows AND columns at the same time!
.grid-container {
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* 3 columns */
grid-template-rows: auto 1fr auto; /* 3 rows */
gap: 20px; /* Space between grid items */
}
Key Terms to Remember:
display: grid
)fr
UnitThe fr
(fraction) unit is Grid's special way of dividing space:
.three-column-layout {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
/* Column 1: 25% | Column 2: 50% | Column 3: 25% */
}
:memo: Note The
fr
unit automatically calculates sizes for you! In the example above:
- 1fr + 2fr + 1fr = 4 total fractions
- First column gets 1/4 of the space
- Middle column gets 2/4 (or 1/2) of the space
- Last column gets 1/4 of the space
Let's create a classic webpage layout step by step:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Grid Layout Example</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.page-layout {
display: grid;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
gap: 20px;
padding: 20px;
}
.header {
grid-area: header;
background: #3498db;
color: white;
padding: 20px;
text-align: center;
}
.sidebar {
grid-area: sidebar;
background: #e74c3c;
color: white;
padding: 20px;
}
.main {
grid-area: main;
background: #2ecc71;
color: white;
padding: 20px;
}
.aside {
grid-area: aside;
background: #f39c12;
color: white;
padding: 20px;
}
.footer {
grid-area: footer;
background: #34495e;
color: white;
padding: 20px;
text-align: center;
}
</style>
</head>
<body>
<div class="page-layout">
<header class="header">
<h1>Website Header</h1>
</header>
<nav class="sidebar">
<h2>Navigation</h2>
<ul>
<li>Home</li>
<li>About</li>
<li>Services</li>
<li>Contact</li>
</ul>
</nav>
<main class="main">
<h2>Main Content</h2>
<p>This is where your main content goes. The grid makes it easy to create professional layouts!</p>
</main>
<aside class="aside">
<h2>Sidebar</h2>
<p>Additional information or ads can go here.</p>
</aside>
<footer class="footer">
<p>© 2024 Your Website. All rights reserved.</p>
</footer>
</div>
</body>
</html>
Modern CSS includes custom properties (also called CSS variables) that make your code much easier to maintain and update:
:root {
/* Define variables at the root level */
--primary-color: #3498db;
--secondary-color: #e74c3c;
--accent-color: #f39c12;
--text-color: #2c3e50;
--background-color: #ecf0f1;
--spacing-small: 10px;
--spacing-medium: 20px;
--spacing-large: 40px;
--border-radius: 8px;
--box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.card {
background: var(--background-color);
color: var(--text-color);
padding: var(--spacing-medium);
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
border-left: 4px solid var(--primary-color);
}
.button {
background: var(--primary-color);
color: white;
padding: var(--spacing-small) var(--spacing-medium);
border: none;
border-radius: var(--border-radius);
cursor: pointer;
}
.button:hover {
background: var(--secondary-color);
}
:bulb: Tip Name your variables clearly! Use
--primary-color
instead of--blue
so you can change the color later without confusion.
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: var(--spacing-medium);
padding: var(--spacing-medium);
}
This powerful one-liner creates a responsive grid that:
.featured-item {
grid-column: 1 / 3; /* Span from line 1 to line 3 */
grid-row: 1 / 3; /* Span from row 1 to row 3 */
}
/* Or use span notation */
.wide-item {
grid-column: span 2; /* Span across 2 columns */
}
.magazine-layout {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: repeat(4, 200px);
gap: 15px;
}
.article-1 { grid-area: 1 / 1 / 3 / 4; } /* Large feature */
.article-2 { grid-area: 1 / 4 / 2 / 7; } /* Top right */
.article-3 { grid-area: 2 / 4 / 3 / 6; } /* Medium */
.article-4 { grid-area: 2 / 6 / 3 / 7; } /* Small */
.article-5 { grid-area: 3 / 1 / 5 / 4; } /* Bottom left */
.article-6 { grid-area: 3 / 4 / 5 / 7; } /* Bottom right */
CSS now has smarter properties that adapt to different languages and writing directions:
.card {
margin-inline-start: 20px; /* Left in LTR, right in RTL */
margin-inline-end: 20px; /* Right in LTR, left in RTL */
margin-block-start: 10px; /* Top */
margin-block-end: 10px; /* Bottom */
}
/* Shorthand */
.card {
margin-inline: 20px; /* Horizontal margins */
margin-block: 10px; /* Vertical margins */
}
:memo: Note Logical properties are especially helpful for international websites that support languages written right-to-left (like Arabic or Hebrew).
The clamp()
function creates text that automatically resizes:
.responsive-heading {
font-size: clamp(1.5rem, 4vw, 3rem);
/* Minimum: 1.5rem, Preferred: 4vw, Maximum: 3rem */
}
This means your heading will:
:root {
--primary: hsl(210, 100%, 50%);
--primary-light: hsl(210, 100%, 70%);
--primary-dark: hsl(210, 100%, 30%);
/* Or use the newer color functions */
--accent: color(display-p3 0.8 0.2 0.4);
}
Let's put everything together! Create a responsive photo gallery using CSS Grid:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Photo Gallery</title>
<style>
:root {
--grid-gap: 15px;
--border-radius: 12px;
--shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
--transition: transform 0.3s ease, box-shadow 0.3s ease;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 40px 20px;
}
.gallery-container {
max-width: 1200px;
margin: 0 auto;
}
.gallery-title {
text-align: center;
color: white;
font-size: clamp(2rem, 5vw, 3.5rem);
margin-bottom: 40px;
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
}
.photo-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: var(--grid-gap);
}
.photo-item {
background: white;
border-radius: var(--border-radius);
overflow: hidden;
box-shadow: var(--shadow);
transition: var(--transition);
cursor: pointer;
}
.photo-item:hover {
transform: translateY(-10px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}
.photo-item:nth-child(1) {
grid-row: span 2;
}
.photo-item:nth-child(4) {
grid-column: span 2;
}
.photo-item:nth-child(7) {
grid-row: span 2;
}
.photo-img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
min-height: 200px;
}
.photo-caption {
padding: 15px;
text-align: center;
font-weight: bold;
color: #333;
}
@media (max-width: 768px) {
.photo-item:nth-child(n) {
grid-column: span 1 !important;
grid-row: span 1 !important;
}
}
</style>
</head>
<body>
<div class="gallery-container">
<h1 class="gallery-title">Modern Photo Gallery</h1>
<div class="photo-grid">
<div class="photo-item">
<img src="https://picsum.photos/400/600?random=1" alt="Photo 1" class="photo-img">
<div class="photo-caption">Mountain View</div>
</div>
<div class="photo-item">
<img src="https://picsum.photos/400/400?random=2" alt="Photo 2" class="photo-img">
<div class="photo-caption">City Life</div>
</div>
<div class="photo-item">
<img src="https://picsum.photos/400/400?random=3" alt="Photo 3" class="photo-img">
<div class="photo-caption">Ocean Waves</div>
</div>
<div class="photo-item">
<img src="https://picsum.photos/800/400?random=4" alt="Photo 4" class="photo-img">
<div class="photo-caption">Desert Landscape</div>
</div>
<div class="photo-item">
<img src="https://picsum.photos/400/400?random=5" alt="Photo 5" class="photo-img">
<div class="photo-caption">Forest Path</div>
</div>
<div class="photo-item">
<img src="https://picsum.photos/400/400?random=6" alt="Photo 6" class="photo-img">
<div class="photo-caption">Urban Art</div>
</div>
<div class="photo-item">
<img src="https://picsum.photos/400/600?random=7" alt="Photo 7" class="photo-img">
<div class="photo-caption">Sunset Sky</div>
</div>
<div class="photo-item">
<img src="https://picsum.photos/400/400?random=8" alt="Photo 8" class="photo-img">
<div class="photo-caption">Wild Flowers</div>
</div>
</div>
</div>
</body>
</html>
Create a simple 3x3 grid layout with:
Build a card layout that:
auto-fit
and minmax()
(no media queries!)Create a magazine-style layout where:
Items not positioning correctly
/* Problem: Forgot to set display: grid */
.container {
grid-template-columns: 1fr 1fr 1fr; /* This won't work! */
}
/* Solution: Always set display first */
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
Grid items overflowing
/* Problem: Content too wide for grid */
.grid-item {
width: 500px; /* Fixed width might overflow */
}
/* Solution: Use min-width and max-width */
.grid-item {
min-width: 0; /* Allow shrinking */
max-width: 100%; /* Prevent overflow */
}
Your browser has amazing tools for debugging Grid:
:bulb: Tip The Grid inspector shows line numbers, making it easy to see exactly where your items should go!
Using named areas makes your code easier to understand:
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
They're best friends! Use Grid for layout, Flexbox for content:
.grid-item {
display: flex;
align-items: center;
justify-content: center;
}
Start with mobile, then add complexity:
/* Mobile first */
.grid-container {
display: grid;
grid-template-columns: 1fr;
}
/* Tablet and up */
@media (min-width: 768px) {
.grid-container {
grid-template-columns: 200px 1fr;
}
}
:information_source: Responsive Web Design means creating web pages that look great and work well on all devices - from tiny phones to giant desktop monitors.
Your web page should automatically adjust to fit any screen size.
Example of Responsive Web Page on phone, tablet, and desktop
We use HTML and CSS to make content adapt by:
:information_source: Viewport is the visible area of a web page on your device's screen.
Key facts about viewports:
<meta>
tagEvery responsive web page needs this line in the <head>
section:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Let's break down what this does:
Attribute | What it Does |
---|---|
name="viewport" |
Tells the browser this tag controls the viewport |
width=device-width |
Makes the page width match the device's screen width |
initial-scale=1.0 |
Sets the starting zoom level (1.0 = no zoom) |
:warning: Warning Without this viewport meta tag, mobile browsers will try to show your page as if it's on a desktop, making everything tiny!
An example of a web page without the viewport meta tag, and the same web page with the viewport meta tag:
Example of the Same Web Page Without and With the Viewport Meta Tag
Media queries are CSS's superpower for responsive design! They let you apply different styles based on the device or screen size.
Key points:
@media
ruleMedia queries are like asking questions about the device:
@media mediatype and (mediafeature and|or mediafeature) {
CSS-Code;
}
Common media types you'll use:
Media Type | When to Use It |
---|---|
all |
Works for all devices (most common) |
screen |
For devices with screens (computers, phones, tablets) |
print |
For when someone prints your page |
speech |
For screen readers that speak content aloud |
:memo: Note Most of the time, you'll use
screen
for regular web development!
The most important media features for responsive design:
Media Feature | What It Checks |
---|---|
width |
The exact viewport width |
min-width |
Is the viewport at least this wide? |
max-width |
Is the viewport no wider than this? |
:bulb: Tip Use
min-width
for mobile-first design andmax-width
for desktop-first design!
For more media features, visit W3Schools Media Query Reference
Conditional Rule | How It Works |
---|---|
and |
Both conditions must be true |
or (using comma) |
At least one condition must be true |
Let's see media queries in action!
body {
background-color: lightblue; /* Default for larger screens */
}
@media screen and (max-width: 400px) {
body {
background-color: pink; /* Only applies when screen is 400px or smaller */
}
}
Viewport at 500 pixels shows light blue
Viewport at 400 pixels shows pink
Now let's combine Grid with media queries for amazing responsive layouts:
.responsive-grid {
display: grid;
gap: 20px;
/* Mobile first approach */
grid-template-columns: 1fr;
grid-template-areas:
"header"
"nav"
"main"
"aside"
"footer";
}
/* Tablet */
@media (min-width: 768px) {
.responsive-grid {
grid-template-columns: 200px 1fr;
grid-template-areas:
"header header"
"nav main"
"nav aside"
"footer footer";
}
}
/* Desktop */
@media (min-width: 1024px) {
.responsive-grid {
grid-template-columns: 200px 1fr 200px;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
}
}
Container queries are the future! They let you style elements based on their container size, not the viewport:
.card-container {
container-type: inline-size;
}
@container (min-width: 300px) {
.card {
display: flex;
flex-direction: row;
}
}
:memo: Note Container queries are newer than media queries. They're perfect for component-based design where you don't know what size container your component will be in!
In this lesson, you've learned powerful modern CSS techniques:
CSS Grid Fundamentals:
fr
units to divide space proportionallyModern CSS Features:
clamp()
creates responsive typography without media queriesResponsive Design:
In our next lesson, we'll explore why CSS frameworks exist and start our journey into modern framework development. You'll learn about the problems that frameworks solve and get your first taste of both Tailwind CSS and Bootstrap.
But first, practice what you've learned! CSS Grid combined with responsive design principles creates incredibly powerful and flexible layouts. The more you experiment with these modern techniques, the more natural they become.
Use these prompts to get help with CSS Grid:
"I want to create a [description] layout for my website. Can you suggest a CSS Grid structure with grid-template-areas that would work well? The layout should include [list your requirements]."
"Help me make this CSS Grid layout responsive. I want [desktop behavior] on desktop, [tablet behavior] on tablet, and [mobile behavior] on mobile. Here's my current CSS: [paste your code]"
"My CSS Grid isn't working as expected. [Describe the problem]. Here's my CSS: [paste your code]. Can you help me identify what's wrong?"
"I want to create a [specific layout type] using CSS Grid. Can you show me an example with CSS custom properties for theming and proper responsive design?"
Remember: CSS Grid is like a puzzle - once you understand how the pieces fit together, you can create amazing layouts!
Ready to practice? Try these challenges:
Grid Gallery Challenge: Create a photo gallery where the first photo is twice as big as the others. Use Grid to make it responsive without media queries.
Dashboard Layout: Build a dashboard with a header, sidebar, main content area, and footer. Make it collapse to a single column on mobile.
Variable Theme: Create a simple page with CSS variables for all colors. Then add a button that switches between light and dark themes by changing the variables.
Responsive Cards: Make a card component that uses container queries to change from vertical to horizontal layout based on available space.
Magazine Layout: Design a magazine-style layout with articles of different sizes. Use Grid areas to name your sections and rearrange them at different screen sizes.
:bulb: Tip Start with the simplest challenge and work your way up. Each one teaches different Grid and responsive design concepts!