CSS · Lesson 43

CSS Performance Optimization

20 phases  ·  Build: Project Overview

👋 Welcome to Lesson 43

Have you ever visited a website that felt painfully slow to load? You waited and waited, and maybe you just gave up and left. That experience is exactly what CSS performance optimization is designed to prevent.

CSS Performance Optimization means writing and organizing your CSS code in ways that make your website load faster and run more smoothly. It is not just about making things look good · it is about making sure the code that makes things look good does not waste the user's time.

Think of it like this: imagine you are packing a suitcase for a trip. A badly packed suitcase takes forever to close, weighs too much, and is hard to search through. A well-packed suitcase is compact, light, and organized. CSS optimization is the art of packing your stylesheet suitcase efficiently.

By the end of this lesson, you will understand:

  • Why CSS optimization matters for users and search engines
  • The main techniques to make CSS smaller and faster
  • How to avoid common mistakes that slow websites down
  • How to apply these techniques in a real mini-project

No prior optimization knowledge is needed. If you know how to write basic CSS rules, you are ready for this lesson.


📚 20 phases🏗️ Project Overview🌐 GitHub Pages
Phase 1 of 20
Lesson Introduction

Have you ever visited a website that felt painfully slow to load? You waited and waited, and maybe you just gave up and left. That experience is exactly what CSS performance optimization is designed to prevent.

CSS Performance Optimization means writing and organizing your CSS code in ways that make your website load faster and run more smoothly. It is not just about making things look good · it is about making sure the code that makes things look good does not waste the user's time.

Think of it like this: imagine you are packing a suitcase for a trip. A badly packed suitcase takes forever to close, weighs too much, and is hard to search through. A well-packed suitcase is compact, light, and organized. CSS optimization is the art of packing your stylesheet suitcase efficiently.

By the end of this lesson, you will understand:

  • Why CSS optimization matters for users and search engines
  • The main techniques to make CSS smaller and faster
  • How to avoid common mistakes that slow websites down
  • How to apply these techniques in a real mini-project

No prior optimization knowledge is needed. If you know how to write basic CSS rules, you are ready for this lesson.


✏️ Your Task
Practise what you just learned about Lesson Introduction. Open your editor, type the examples above by hand, modify them, and observe what changes.
Phase 2 of 20
Prerequisite Concepts

Before we dive in, let us make sure you understand two foundational ideas that make optimization necessary.

What Is a Stylesheet?

A stylesheet is a file (usually ending in .css) that contains all the visual instructions for a web page · colors, fonts, sizes, layouts, and more. When a browser loads your page, it downloads this file before it can display anything styled.

The bigger the file, the longer the download takes.

What Is an HTTP Request?

Every time a browser fetches a file from the internet (an image, a CSS file, a JavaScript file), it sends an HTTP request · a "please give me this file" message to the server. Each request takes time.

If your page asks for 10 separate CSS files, the browser makes 10 separate requests. If you combine them into 1 file, only 1 request is needed. That saves time.

Key insight: Fewer requests + smaller files = faster website.


✏️ Your Task
Practise what you just learned about Prerequisite Concepts. Open your editor, type the examples above by hand, modify them, and observe what changes.
Phase 3 of 20
Conceptual Understanding

Why Does CSS Performance Matter?

Let us look at this from several angles:

1. User Experience: Research shows that if a website takes more than 3 seconds to load, more than half of visitors will abandon it. Slow CSS is one of the main causes of slow loading.

2. SEO (Search Engine Optimization): Google uses page speed as one of its ranking signals. A faster page ranks higher in search results. Slow CSS directly hurts your visibility on Google.

3. Mobile Users: Many users in countries with slower internet connections (including much of Africa and Asia) experience websites on mobile data. Bloated CSS files create a terrible experience for them.

4. Battery and Data: Heavy CSS files drain mobile batteries faster and consume more of users' limited data plans.

Real-world analogy: Think of CSS as electricity running through the wires of your home. Poorly managed wiring wastes electricity, causes delays, and can even cause problems. Well-optimized wiring is efficient, clean, and fast.


✏️ Your Task
Practise what you just learned about Conceptual Understanding. Open your editor, type the examples above by hand, modify them, and observe what changes.
Phase 4 of 20
The Core Optimization Techniques · One at a Time

Let us now explore each major CSS optimization technique in detail, starting from the simplest ideas.


✏️ Your Task
Practise what you just learned about The Core Optimization Techniques · One at a Time. Open your editor, type the examples above by hand, modify them, and observe what changes.
Phase 5 of 20
Technique 1: Minify Your CSS

What Is Minification?

Minification is the process of removing all unnecessary characters from your CSS file · spaces, line breaks, comments, and tabs · without changing what the code does. The result is a compressed, smaller file that browsers can download faster.

Think of it like sending a text message. When you text a friend, you might write:

"Hey, I am going to the market. Do you want anything?"

But in a text message (where every character costs you), you might write:

"hey going 2 market want anything?"

Same message. Fewer characters. Faster to send.

Minification does the same to CSS.

Before Minification

Here is a normal, human-readable CSS file:

css
/* Main button styles */
.button {
    background-color: blue;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 5px;
    font-size: 16px;
}

/* Hover effect */
.button:hover {
    background-color: darkblue;
}

This file has spaces, line breaks, and comments. It is easy for humans to read and edit.

File size: approximately 220 bytes

After Minification

css
.button{background-color:blue;color:white;padding:10px 20px;border:none;border-radius:5px;font-size:16px}.button:hover{background-color:darkblue;}

Exact same code. Same visual result. No human-readable spaces or comments.

File size: approximately 140 bytes

Result: The minified version is roughly 36% smaller! On a large website with thousands of CSS rules, this difference becomes enormous.

Important: Keep Two Copies!

Always keep your original, readable CSS file for development. Only use the minified version for the live website.

VersionUse case
styles.cssDevelopment · readable, with comments
styles.min.cssProduction · minified, sent to users

Tools for Minification

You do not need to minify manually. These free tools do it automatically:

  • CSSNano · a build tool (for advanced developers using Node.js)
  • CleanCSS · available online at cleancss.com
  • CSS Minifier · available online at cssminifier.com
  • VS Code Extensions · many code editors have minifier plugins built in

Thinking Prompt

What would happen if someone gave you a minified CSS file and asked you to edit it? Would it be easy or hard? Why is it important to always keep your unminified source file?


✏️ Your Task
Practise what you just learned about Technique 1: Minify Your CSS. Open your editor, type the examples above by hand, modify them, and observe what changes.
Phase 6 of 20
Technique 2: Reduce the Number of HTTP Requests

The Problem

Every separate CSS file your HTML page links to requires the browser to send a new HTTP request. Each request adds delay (called latency) to the page load.

Imagine ordering food at a restaurant:

  • Sending 5 separate orders one at a time: slow.
  • Sending 1 combined order: fast.

Multiple CSS files work the same way.

Bad Practice: Many Separate Files

html
<!-- Slow: 5 separate HTTP requests for CSS -->
<link rel="stylesheet" href="reset.css">
<link rel="stylesheet" href="layout.css">
<link rel="stylesheet" href="buttons.css">
<link rel="stylesheet" href="forms.css">
<link rel="stylesheet" href="typography.css">

Each of these <link> tags causes the browser to make a separate trip to the server.

Better Practice: One Combined File

html
<!-- Fast: only 1 HTTP request -->
<link rel="stylesheet" href="styles.min.css">

The single file styles.min.css contains all the styles from all those files combined and minified.

What About HTTP/2?

Note for curious learners: Modern servers use a protocol called HTTP/2 that handles multiple files more efficiently. On HTTP/2, multiple requests are less of a problem. However, combining files is still a good practice because it keeps your code organized and reduces complexity.

Micro Demo: The Difference in HTML

html
<!-- BEFORE: 3 requests -->
<link rel="stylesheet" href="colors.css">
<link rel="stylesheet" href="fonts.css">
<link rel="stylesheet" href="layout.css">

<!-- AFTER: 1 request -->
<link rel="stylesheet" href="combined.min.css">

Expected result: The second version loads with one fewer server round trip per additional file, meaning noticeably faster page rendering on slow connections.


✏️ Your Task
`html ` Each of these tags causes the browser to make a separate trip to the server.
Phase 7 of 20
Technique 3: Remove Unused CSS

The Problem

As websites grow, developers often add CSS rules for features that are later removed or changed. These unused rules stay in the file, taking up space and making the browser parse (read and process) more code than necessary.

Imagine a recipe book where half the recipes are for dishes you never cook. The book is twice as heavy, but you only use half of it.

Example of Unused CSS

css
/* This button no longer exists in the HTML */
.old-signup-button {
    background-color: green;
    font-size: 18px;
    padding: 15px;
}

/* This class is still used */
.main-nav {
    display: flex;
    gap: 20px;
}

The .old-signup-button rule wastes space and processing time if no element in your HTML uses that class.

How to Find Unused CSS

Browser DevTools (Free, Built-In):

  1. Open your website in Google Chrome.
  2. Press F12 to open DevTools.
  3. Go to the Coverage tab (found under More Tools).
  4. Click the record button and reload the page.
  5. The tool will highlight which CSS rules were actually used (green) and which were unused (red).

Online Tools:

  • PurifyCSS · analyzes your HTML and CSS and removes unused rules
  • UnCSS · a Node.js tool that does the same

Quick Illustration

Imagine your CSS file has 500 rules. You use 300 of them. Removing unused rules reduces the file by 40%, leading to faster downloads and faster parsing.

Thinking Prompt: Why might unused CSS accumulate on a large website over time? Can you think of a real-world project where this could happen?


✏️ Your Task
Practise what you just learned about Technique 3: Remove Unused CSS. Open your editor, type the examples above by hand, modify them, and observe what changes.
Phase 8 of 20
Technique 4: Simplify CSS Selectors

What Is a CSS Selector?

A selector is the part of a CSS rule that tells the browser which HTML elements to style.

css
/* "p" is the selector — it targets all paragraph elements */
p {
    color: black;
}

The Problem with Overly Complex Selectors

Some selectors are written to be extremely specific. While this works, it is inefficient · the browser has to do more work to figure out which elements match the rule.

Complex (Slow) Selector Example

css
/* Very specific — browser has to check many levels of nesting */
body div#main-content article.post h2.headline {
    font-size: 24px;
    color: navy;
}

Let us decode this selector step by step:

  • body · start from the body element
  • div#main-content · find a div with the ID main-content inside it
  • article.post · find an article with class post inside that
  • h2.headline · find an h2 with class headline inside that

The browser reads selectors right to left. So it first finds all h2.headline elements, then checks if each one is inside an article.post, then checks for div#main-content, then checks for body. That is a lot of checking!

Simplified (Fast) Selector Example

css
/* Simple class — browser immediately finds matching elements */
.headline {
    font-size: 24px;
    color: navy;
}

This single class selector achieves the same result much faster. The browser just looks for anything with the class headline · no chain-checking needed.

Comparison Side by Side

css
/* SLOW: deeply nested, over-qualified */
body div#main-content article.post h2.headline { font-size: 24px; }

/* FAST: simple, direct class selector */
.headline { font-size: 24px; }

Expected result: Both produce the same visual output, but the second version processes faster, especially on pages with hundreds of elements.

Real-World Analogy

Imagine finding a person named "John Smith, who lives in Lagos, Nigeria, in the Ibadan district, on Oak Street, in house number 5." That works, but it takes time to verify every detail. Saying "the person wearing a red hat" is faster when that detail is unique enough.

Selectors work the same way. Use the simplest selector that uniquely identifies your target element.


✏️ Your Task
Practise what you just learned about Technique 4: Simplify CSS Selectors. Open your editor, type the examples above by hand, modify them, and observe what changes.
Phase 9 of 20
Technique 5: Use Shorthand Properties

What Are Shorthand Properties?

CSS allows you to combine several related properties into one single shorthand line. This reduces the number of lines in your file, making it smaller and faster to download.

Without Shorthand (Verbose)

css
/* Long-form: 4 separate lines */
.box {
    margin-top: 10px;
    margin-right: 20px;
    margin-bottom: 10px;
    margin-left: 20px;
}

With Shorthand (Compact)

css
/* Shorthand: 1 line (top, right, bottom, left) */
.box {
    margin: 10px 20px 10px 20px;
}

Even shorter:

css
/* Even more compact (top+bottom: 10px, left+right: 20px) */
.box {
    margin: 10px 20px;
}

All three versions produce the exact same result. The shorthand versions take up fewer bytes.

More Shorthand Examples

Background shorthand:

css
/* Long form */
.hero {
    background-color: #003366;
    background-image: url("banner.jpg");
    background-repeat: no-repeat;
    background-position: center top;
}

/* Shorthand — one line! */
.hero {
    background: #003366 url("banner.jpg") no-repeat center top;
}

Expected output for both: Same blue background with a non-repeating image centered at the top.

Font shorthand:

css
/* Long form */
p {
    font-style: italic;
    font-weight: bold;
    font-size: 16px;
    line-height: 1.5;
    font-family: Arial, sans-serif;
}

/* Shorthand */
p {
    font: italic bold 16px/1.5 Arial, sans-serif;
}

Shorthand Properties to Know

Longhand propertiesShorthand property
margin-top, margin-right, margin-bottom, margin-leftmargin
padding-top, padding-right, padding-bottom, padding-leftpadding
border-width, border-style, border-colorborder
background-color, background-image, background-repeat, background-positionbackground
font-style, font-weight, font-size, font-familyfont

✏️ Your Task
Practise what you just learned about Technique 5: Use Shorthand Properties. Open your editor, type the examples above by hand, modify them, and observe what changes.
Phase 10 of 20
Technique 6: Use CSS Variables to Avoid Repetition

What Is Code Repetition?

If the same color, font size, or spacing value appears dozens of times in your CSS, every change requires finding and updating every occurrence. This also means the same value is written out many times, using extra bytes.

The Problem: Repeated Values

css
/* Same color written 4 times */
.header { background-color: #003366; }
.footer { background-color: #003366; }
.sidebar { border-color: #003366; }
.button { background-color: #003366; }

The Solution: CSS Variables (Custom Properties)

css
/* Define the color ONCE at the top */
:root {
    --brand-color: #003366;
}

/* Use the variable everywhere */
.header { background-color: var(--brand-color); }
.footer { background-color: var(--brand-color); }
.sidebar { border-color: var(--brand-color); }
.button { background-color: var(--brand-color); }

Now if you need to change the brand color, you update one line. Every element using var( · brand-color) automatically updates.

Benefits:

  • Shorter code in total (the variable name may be shorter than the value)
  • Easier maintenance
  • Less chance of inconsistency

Thinking Prompt: Can you imagine managing a website with 50 pages where the brand color appears 200 times? How much time would CSS variables save?


✏️ Your Task
Practise what you just learned about Technique 6: Use CSS Variables to Avoid Repetition. Open your editor, type the examples above by hand, modify them, and observe what changes.
Phase 11 of 20
Technique 7: Avoid Redundant/Duplicate Code

The Problem

Sometimes developers write the same rule twice · either by accident or because multiple people worked on the same file. Duplicate code wastes bytes.

Example of Duplicate Rules

css
/* First occurrence */
h1 {
    font-size: 32px;
    color: #222;
}

/* Duplicate — written again later by mistake */
h1 {
    font-size: 32px;
    color: #222;
}

The browser processes both rules even though the second one adds nothing new.

Solution: Review and Consolidate

css
/* Clean: only one rule */
h1 {
    font-size: 32px;
    color: #222;
}

Tools to detect duplication: CSS Lint, StyleLint, browser DevTools audits, and manual code review.


✏️ Your Task
Practise what you just learned about Technique 7: Avoid Redundant/Duplicate Code. Open your editor, type the examples above by hand, modify them, and observe what changes.
Phase 12 of 20
Technique 8: Load CSS Efficiently in HTML

Placement Matters

CSS should always be loaded in the <head> section of your HTML, not at the bottom of the <body>. This allows the browser to download and parse your CSS before it starts rendering the page, which prevents a "flash of unstyled content" (where the page appears briefly without styling).

Correct Way

html
<!DOCTYPE html>
<html>
<head>
    <!-- CSS loaded here — correct! -->
    <link rel="stylesheet" href="styles.min.css">
</head>
<body>
    <h1>My Website</h1>
    <p>Hello, world!</p>
</body>
</html>

Incorrect Way (Do Not Do This)

html
<!DOCTYPE html>
<html>
<head>
    <title>My Website</title>
</head>
<body>
    <h1>My Website</h1>
    <p>Hello, world!</p>
    <!-- CSS loaded here — WRONG! Causes flash of unstyled content -->
    <link rel="stylesheet" href="styles.css">
</body>
</html>

Use media Attributes for Responsive CSS

If you have CSS that only applies to specific screen sizes, you can use the media attribute on your link tag. The browser will only fully apply those styles when the condition is met, reducing unnecessary blocking.

html
<!-- This CSS only applies when printing — does not block page render on screen -->
<link rel="stylesheet" href="print.css" media="print">

<!-- This CSS only applies on screens wider than 600px -->
<link rel="stylesheet" href="large-screen.css" media="(min-width: 600px)">

✏️ Your Task
Practise what you just learned about Technique 8: Load CSS Efficiently in HTML. Open your editor, type the examples above by hand, modify them, and observe what changes.
Phase 13 of 20
Technique 9: Prefer Modern Layout Methods (Flexbox and Grid)

The Old Way: Floats

Before CSS Flexbox and Grid existed, developers used a property called float to create layouts. This was a workaround that required a lot of extra code · extra clearfix hacks, extra margin adjustments, and many lines just to make a basic two-column layout.

css
/* Old float-based layout — messy! */
.sidebar { float: left; width: 30%; }
.main-content { float: left; width: 70%; }
.container::after {
    content: "";
    display: table;
    clear: both;
}

The New Way: Flexbox

css
/* Modern Flexbox layout — clean and efficient */
.container {
    display: flex;
}
.sidebar { flex: 0 0 30%; }
.main-content { flex: 1; }

Expected result: Both produce the same two-column layout. But Flexbox uses fewer lines, is easier to read, and renders faster because the browser has native optimized support for Flexbox and Grid calculations.

The New Way: Grid

css
/* Two-column layout with Grid */
.container {
    display: grid;
    grid-template-columns: 30% 70%;
}

Benefits of Flexbox and Grid over floats:

  • Less code = smaller file size
  • Browser renders them more efficiently
  • Easier to make responsive
  • More readable and maintainable

✏️ Your Task
Practise what you just learned about Technique 9: Prefer Modern Layout Methods (Flexbox and Grid). Open your editor, type the examples above by hand, modify them, and observe what changes.
Phase 14 of 20
Technique 10: Optimize Animations and Transitions

Why Animations Can Hurt Performance

CSS animations and transitions trigger the browser to recalculate layouts and repaint pixels. When done poorly, animations cause jank · that stuttery, choppy visual effect that makes a website feel unresponsive.

Properties That Cause Layout Recalculation (Avoid Animating These)

Animating properties like width, height, margin, padding, or top/left forces the browser to recalculate the entire page layout on every animation frame. This is expensive.

css
/* SLOW: animating width forces layout recalculation */
.box {
    transition: width 0.3s ease;
}
.box:hover {
    width: 200px; /* browser recalculates layout on every frame */
}

Properties That Are GPU-Accelerated (Prefer These)

The transform and opacity properties are handled by the graphics card (GPU), not the CPU. They are much smoother and faster to animate.

css
/* FAST: animating transform is GPU-accelerated */
.box {
    transition: transform 0.3s ease;
}
.box:hover {
    transform: scaleX(1.2); /* GPU handles this — much smoother! */
}

Simple Rule to Remember:

Avoid animatingUse instead
width, heighttransform: scale()
top, left, right, bottomtransform: translate()
margin, paddingtransform: translate()
opacity: 1opacity: 0opacity IS GPU-accelerated · this one is fine!

Micro Demo: Smooth vs. Janky Button Animation

css
/* JANKY: changes margin causes layout reflow */
.btn-janky {
    transition: margin-left 0.3s;
}
.btn-janky:hover {
    margin-left: 10px;
}

/* SMOOTH: uses transform — no layout reflow */
.btn-smooth {
    transition: transform 0.3s;
}
.btn-smooth:hover {
    transform: translateX(10px);
}

Expected result: Both buttons appear to move right on hover. But btn-smooth will animate at a consistent 60 frames per second. btn-janky may stutter, especially on lower-end devices.


✏️ Your Task
Practise what you just learned about Technique 10: Optimize Animations and Transitions. Open your editor, type the examples above by hand, modify them, and observe what changes.
Phase 15 of 20
Technique 11: Limit the Number of Web Fonts

The Problem with Web Fonts

Fonts like Google Fonts are loaded from the internet. Every font family and every font weight (normal, bold, italic, etc.) is a separate file download. Using too many fonts slows the page.

Costly Font Usage

html
<!-- Loading 4 different font families — SLOW -->
<link href="https://fonts.googleapis.com/css2?family=Roboto&family=Open+Sans&family=Montserrat&family=Lato" rel="stylesheet">

This triggers 4+ separate requests for font files.

Better Font Usage

html
<!-- Only load what you actually use -->
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700" rel="stylesheet">

This loads only the Roboto font, in only two weights (regular 400 and bold 700).

Font Optimization Tips

  1. Limit yourself to 1 or 2 font families per website.
  2. Only load the weights you actually use. If you do not use bold italic, do not load it.
  3. Use font-display: swap to show fallback text while the font loads:
css
@font-face {
    font-family: 'MyFont';
    src: url('myfont.woff2') format('woff2');
    font-display: swap; /* Show fallback text immediately while font loads */
}

This prevents a "flash of invisible text" where users see nothing while waiting for the custom font.

  1. Use modern font formats. WOFF2 is the most compressed format and is supported by all modern browsers.

✏️ Your Task
Practise what you just learned about Technique 11: Limit the Number of Web Fonts. Open your editor, type the examples above by hand, modify them, and observe what changes.
Phase 16 of 20
Technique 12: Use Browser Caching

What Is Caching?

Caching means storing a copy of a file in the browser's memory so that on the next visit, the browser uses the stored copy instead of downloading the file again.

Think of it like this: imagine you borrow the same book from the library every week. After the first time, you keep a photocopy at home. Now you never have to go back to the library for that book.

CSS files are perfect candidates for caching because they rarely change.

How It Works

When a user visits your website for the first time, the browser downloads styles.min.css and saves a copy. The next time they visit, the browser checks: "Do I already have this file and is it still fresh?" If yes, it uses the cached copy · zero download time.

How to Enable Caching

Caching is set up on your web server using response headers. Here is an example of an Apache server configuration:

apache
# Tell browsers to cache CSS files for 1 year
<FilesMatch "\.css$">
    Header set Cache-Control "max-age=31536000, public"
</FilesMatch>

For a Nginx server:

nginx
location ~* \.css$ {
    expires 1y;
    add_header Cache-Control "public";
}

Note: When you update your CSS file, you need to rename it or add a version number (e.g., styles.v2.min.css) so browsers know to download the new version. This is called cache busting.


✏️ Your Task
Practise what you just learned about Technique 12: Use Browser Caching. Open your editor, type the examples above by hand, modify them, and observe what changes.
Phase 17 of 20
Putting It All Together · Summary of Techniques

Here is a quick reference of all the techniques covered:

#TechniqueWhat it does
1Minify CSSRemoves whitespace and comments to shrink file size
2Reduce HTTP requestsCombines files so fewer round trips are needed
3Remove unused CSSDeletes dead code that the browser still has to read
4Simplify selectorsReduces the browser's selector matching work
5Use shorthand propertiesFewer lines for the same result
6Use CSS variablesPrevents repeated values, easier maintenance
7Avoid duplicate codePrevents the browser from processing redundant rules
8Load CSS in <head>Prevents unstyled content flashing
9Use Flexbox/GridLess code, faster rendering than floats
10Optimize animationsUse transform/opacity for GPU-accelerated smoothness
11Limit web fontsFewer font files = fewer downloads
12Enable browser cachingReturning visitors load from memory, not network

✏️ Your Task
Practise what you just learned about Putting It All Together · Summary of Techniques. Open your editor, type the examples above by hand, modify them, and observe what changes.
Phase 18 of 20
Simple Standalone Examples

Example 1: Minified vs. Unminified

Unminified (for development):

css
/* Navigation styles */
.nav {
    display: flex;
    justify-content: space-between;
    padding: 15px 30px;
    background-color: #1a1a2e;
}

.nav a {
    color: white;
    text-decoration: none;
    font-size: 14px;
}

Minified (for production):

css
.nav{display:flex;justify-content:space-between;padding:15px 30px;background-color:#1a1a2e}.nav a{color:white;text-decoration:none;font-size:14px}

Expected result: Same visual output. The minified version is about 40% smaller.


Example 2: Complex Selector vs. Simple Selector

css
/* BEFORE: overly complex */
html body main section div.card p.description {
    font-size: 14px;
    line-height: 1.6;
    color: #555;
}

/* AFTER: simplified — same result */
.description {
    font-size: 14px;
    line-height: 1.6;
    color: #555;
}

Expected result: Both style the .description paragraph identically. The second version is faster for the browser to process.


Example 3: Animation Optimization

css
/* BEFORE: animating height (triggers layout reflow) */
.accordion-panel {
    overflow: hidden;
    transition: height 0.4s ease;
}
.accordion-panel.open {
    height: 200px;
}

/* AFTER: animating max-height with transform is still better than height alone */
/* Even better: use opacity + transform combination */
.fade-in {
    opacity: 0;
    transform: translateY(10px);
    transition: opacity 0.3s ease, transform 0.3s ease;
}
.fade-in.visible {
    opacity: 1;
    transform: translateY(0);
}

Expected result: .fade-in.visible fades in and slides up smoothly. Both opacity and transform are GPU-accelerated, giving 60fps animation even on slower devices.


✏️ Your Task
Practise what you just learned about Simple Standalone Examples. Open your editor, type the examples above by hand, modify them, and observe what changes.
Phase 19 of 20
Guided Practice Exercises
🎯 Your Challenge

Exercise 1: Identifying Unoptimized CSS

Objective: Spot performance problems in a given CSS snippet.

Scenario: Your team inherited an old website. Here is some of the CSS file. Find as many optimization problems as you can.

✏️ Task
Practise what you just learned about Guided Practice Exercises. Open your editor, type the examples above by hand, modify them, and observe what changes.
css
/* Old website styles */

/* Colors and fonts */
body {
    font-family: Georgia, serif;
    background-color: #ffffff;
    color: #333333;
}

/* Header */
html body div#wrapper header#site-header nav ul li a.nav-link {
    color: #0055cc;
    text-decoration: none;
    font-size: 16px;
}

/* Old promo section that was removed 6 months ago */
#old-promo-banner {
    background-color: red;
    padding: 20px 40px;
    font-size: 24px;
    text-align: center;
    display: block;
}

/* Redundant rule */
body {
    font-family: Georgia, serif;
    background-color: #ffffff;
    color: #333333;
}

/* Button hover animation */
.cta-button {
    transition: margin-left 0.3s ease;
}
.cta-button:hover {
    margin-left: 5px;
}

Your Task: List all the performance issues you can find. Use the techniques from this lesson.

Hints:

  • Look for over-qualified selectors
  • Look for rules targeting elements that no longer exist
  • Look for duplicated rules
  • Look for animation properties that cause layout reflow

Expected answers (check yourself):

  1. html body div#wrapper header#site-header nav ul li a.nav-link · massively over-qualified selector. Should be .nav-link.
  2. #old-promo-banner · targets an element removed 6 months ago. This is unused CSS.
  3. The body rule appears twice · identical duplicate. Remove one.
  4. .cta-button:hover { margin-left: 5px; } · animating margin-left triggers layout reflow. Should use transform: translateX(5px) instead.

Self-check questions:

  • Did you find all 4 issues?
  • Can you explain WHY each one hurts performance?
  • Could you fix each issue with the correct code?

Exercise 2: Rewriting for Performance

Objective: Rewrite the CSS below to be optimized.

Scenario: You are building a blog. Here is the current CSS for blog post cards:

css
/* Original — unoptimized */
.card {
    background-color: #ffffff;
    border: 1px solid #dddddd;
    padding-top: 20px;
    padding-right: 20px;
    padding-bottom: 20px;
    padding-left: 20px;
    margin-top: 10px;
    margin-right: 0px;
    margin-bottom: 10px;
    margin-left: 0px;
    border-radius: 8px;
}

.card:hover {
    transition: box-shadow 0.3s ease;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

/* Unused — the sidebar was removed last month */
.sidebar-widget {
    background-color: #f5f5f5;
    padding: 15px;
    border-left: 3px solid #0055cc;
}

Your Task: Rewrite the .card styles using shorthand, remove unused code, and fix the hover transition placement.

Expected optimized version:

css
/* Optimized */
.card {
    background-color: #fff;
    border: 1px solid #ddd;
    padding: 20px;
    margin: 10px 0;
    border-radius: 8px;
    transition: box-shadow 0.3s ease; /* moved here, not in :hover */
}

.card:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

/* .sidebar-widget REMOVED — it is unused */

What changed:

  • padding-top/right/bottom/leftpadding: 20px (shorthand)
  • margin-top/bottom: 10px, left/right: 0margin: 10px 0 (shorthand)
  • #ffffff#fff and #dddddd#ddd (shorter hex values)
  • transition moved to .card (base state) · it should not be inside :hover
  • .sidebar-widget removed (unused code)

Self-check questions:

  • Did you use all available shorthands?
  • Is the transition on the base selector (.card) or the hover state?
  • Did you remove the unused rule?

Exercise 3: Font Loading Audit

Objective: Identify wasteful font loading and fix it.

Scenario: A developer added these font imports to a website:

html
<!-- In the HTML head -->
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700&display=swap" rel="stylesheet">

After auditing the CSS, you discover:

  • Roboto is used in body text, only in weights 400 and 700
  • Montserrat is used for headings only in weight 700
  • Lato is not used anywhere in the CSS

Your Task: Write the optimized font loading HTML.

Expected optimized version:

html
<!-- Load only what is actually used -->
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&family=Montserrat:wght@700&display=swap" rel="stylesheet">

What improved:

  • Removed Lato entirely (unused)
  • Combined both font families into one URL (1 request instead of 3)
  • Removed unused Roboto weights (100, 300, 500, 900, and all italic variants)
  • Added display=swap to prevent invisible text while loading

Phase 20 of 20
Common Beginner Mistakes

Mistake 1: Minifying Too Early

Many beginners minify their CSS while still actively developing. This makes the file impossible to read and edit. Always minify only when deploying to a live server.

Wrong workflow:

  1. Write CSS → Minify → Try to edit the minified file → Get frustrated

Correct workflow:

  1. Write CSS (readable) → Test → When ready to deploy → Minify → Upload minified version

Mistake 2: Putting transition Only in the Hover State

css
/* WRONG — transition only in hover means it animates on hover but snaps back instantly */
.button:hover {
    background-color: darkblue;
    transition: background-color 0.3s;
}

/* CORRECT — transition on the base element animates both ways */
.button {
    background-color: blue;
    transition: background-color 0.3s;
}
.button:hover {
    background-color: darkblue;
}

If transition is only in the :hover rule, the animation plays when you hover in, but the element snaps back instantly when you hover out. Always put transition on the base selector.


Mistake 3: Over-Qualifying Selectors

css
/* WRONG: unnecessarily specific */
div.card-container .card-inner p.card-text { color: gray; }

/* CORRECT: just use the class directly */
.card-text { color: gray; }

Add hierarchy to selectors only when you absolutely need to distinguish between two elements with the same class in completely different contexts.


Mistake 4: Animating the Wrong Properties

css
/* WRONG: animating width causes layout reflow */
.menu {
    width: 0;
    overflow: hidden;
    transition: width 0.3s;
}
.menu.open {
    width: 250px;
}

/* BETTER: use transform for movement effects */
.menu {
    transform: translateX(-100%);
    transition: transform 0.3s ease;
}
.menu.open {
    transform: translateX(0);
}

Mistake 5: Loading Many Font Weights You Do Not Use

css
/* WRONG: loading all 9 Roboto weights */
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@100;200;300;400;500;600;700;800;900');

/* Check your CSS — do you actually use weights 100, 200, 300, 500, 600, 800, 900? */
/* If you only use 400 and 700: */
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700');

Mistake 6: Forgetting to Remove Debug/Test CSS

css
/* Left behind from testing — delete before going live! */
* { border: 1px solid red !important; }
body { background: yellow !important; }

✏️ Your Task
Practise what you just learned about Common Beginner Mistakes. Open your editor, type the examples above by hand, modify them, and observe what changes.
🏗️ Build It — Mini Project
Project Overview

Project Overview

You will take an unoptimized CSS file for a simple personal portfolio page and apply all the optimization techniques you have learned.

Scenario: You built your first portfolio website but never optimized the CSS. Now you want to make it faster before sharing it with potential employers.

Stage 1: Setup · The Starting Code

Here is your current unoptimized portfolio.css:

starter.html
/* Portfolio styles — UNOPTIMIZED */

/* Reset */
* {
    margin: 0;
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* Body */
html body {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    background-color: #fafafa;
    color: #333333;
    font-size: 16px;
    line-height: 1.6;
}

/* Navigation */
html body header nav ul li a {
    color: #0066cc;
    text-decoration: none;
    font-size: 15px;
    font-weight: 500;
}

/* Hero section */
.hero {
    background-color: #1a1a2e;
    padding-top: 80px;
    padding-right: 40px;
    padding-bottom: 80px;
    padding-left: 40px;
    text-align: center;
}

.hero h1 {
    color: #ffffff;
    font-size: 48px;
    margin-bottom: 20px;
    margin-top: 0px;
    margin-left: 0px;
    margin-right: 0px;
}

.hero p {
    color: #cccccc;
    font-size: 20px;
    max-width: 600px;
    margin-left: auto;
    margin-right: auto;
    margin-top: 0;
    margin-bottom: 30px;
}

/* Projects grid */
.projects-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 30px;
    padding: 60px 40px;
    background-color: #fafafa;
}

/* Project card */
.project-card {
    background-color: #ffffff;
    border: 1px solid #e0e0e0;
    border-radius: 8px;
    padding-top: 24px;
    padding-right: 24px;
    padding-bottom: 24px;
    padding-left: 24px;
}

/* Old card hover from version 1 — not used anymore, new design uses JS */
.old-card-hover-effect {
    background-color: #eef2ff;
    border-color: #0066cc;
    transition: all 0.3s;
}

/* Card hover — current */
.project-card {
    transition: top 0.3s ease;
    position: relative;
    top: 0;
}

.project-card:hover {
    top: -5px;
}

/* Footer */
html body footer {
    background-color: #1a1a2e;
    color: #ffffff;
    text-align: center;
    padding-top: 40px;
    padding-right: 0px;
    padding-bottom: 40px;
    padding-left: 0px;
}

Lesson 43 complete! 🎉

You covered: