Exercises: Module 01 — Introduction to CSS¶
Instructions¶
Complete each exercise in order. Exercises increase in difficulty.
You will need a text editor and a web browser to complete these exercises.
Create a new .html file and a companion .css file for each exercise (or use one file pair and replace the content between exercises).
Submit your answers by committing your solution files or by editing the <details> blocks below with your notes.
Easy Exercises (1–3)¶
Exercise 1¶
Difficulty: Easy Objective: Write a valid CSS rule and link it to an HTML page
Create an HTML file exercise1.html with a heading and two paragraphs. Create a companion exercise1.css and link it using <link rel="stylesheet">. Apply these styles:
- All
<h1>elements:font-size: 2rem,color: #1e293b - All
<p>elements:font-size: 1rem,color: #64748b,line-height: 1.7
Verify the styles apply by opening the file in a browser.
Solution
Exercise 2¶
Difficulty: Easy Objective: Identify which CSS origin applies to a property
Open any webpage in your browser. Open DevTools (F12), select an element (e.g., a heading), and look at the "Styles" panel. Answer these questions in the space below:
- Find a style that comes from the user-agent stylesheet (it will be labelled "user agent stylesheet" in Chrome/Firefox). What property is it?
- Find a style that is being overridden (shown with a strikethrough). What is overriding it?
- Is there a style with
!important? If so, where does it come from?
Sample answers (your results will vary by site)
A common observation on most pages: 1. The `` or `
` element will show user-agent styles like `display: block`, `margin-block-start: 0.67em`, or `font-size: 2em` sourced from the "user agent stylesheet". 2. Often you will see `color`, `font-size`, or `margin` with a strikethrough because the page's author stylesheet has a more specific or later rule. 3. CSS resets and frameworks often use `!important` on utility classes — for example, `display: none !important` on a `.hidden` class.
Exercise 3¶
Difficulty: Easy Objective: Demonstrate order-of-appearance cascade resolution
Create a stylesheet with two rules that target the same element:
/* Add this to your stylesheet and predict which color the <h2> will be */
h2 {
color: teal;
}
h2 {
color: coral;
}
- What colour does the
<h2>render in? Why? - Now swap the order of the two rules. What colour does it render in now?
- Without looking at the CSS, how would you use DevTools to discover which rule was "winning"?
Solution
1. The `` renders **coral** — because both rules have the same specificity (`0,0,1`), the one that appears later wins. 2. After swapping, it renders **teal** for the same reason. 3. In DevTools (Elements panel → Styles tab), the winning declaration is displayed normally. Losing declarations are shown with a strikethrough. The panel also shows the source file and line number, so you can see which rule is later in the file.
Medium Exercises (4–6)¶
Exercise 4¶
Difficulty: Medium Objective: Calculate specificity scores and predict the winning rule
For each HTML element below, calculate the specificity of every matching rule and state which color will be applied. Show your work as (A,B,C) scores.
<p id="intro" class="lead">Opening paragraph</p>
<a href="#" class="nav-link">Nav item</a>
<button type="submit" class="btn btn-primary">Submit</button>
/* Rules for the <p> */
p { color: black; }
.lead { color: gray; }
#intro { color: navy; }
#intro.lead { color: teal; }
/* Rules for the <a> */
a { color: blue; }
.nav-link { color: green; }
a.nav-link:hover { color: red; } /* Ignore this one — :hover is not currently active */
/* Rules for the <button> */
button { color: black; }
.btn { color: white; }
.btn.btn-primary { color: yellow; }
button.btn { color: orange; }
Solution
**``:** - `p` → `(0,0,1)` → black - `.lead` → `(0,1,0)` → gray - `#intro` → `(1,0,0)` → navy - `#intro.lead` → `(1,1,0)` → **teal** ← winner (highest B when A is tied at 1) **``** (`:hover` not active): - `a` → `(0,0,1)` → blue - `.nav-link` → `(0,1,0)` → **green** ← winner (higher B) **`
Exercise 5¶
Difficulty: Medium Objective: Observe and control CSS inheritance
Create the following HTML structure:
<div class="article">
<h2>Article Title</h2>
<p>Article paragraph with a <a href="#">link inside</a> it.</p>
<ul>
<li>List item one</li>
<li>List item two</li>
</ul>
</div>
Then answer and implement:
- Set
color: #1e40afandfont-family: Georgia, serifon.article. Which child elements inherit these values? - The link (
<a>) probably does not inherit the color. Why? Usecolor: inheritto fix it. - Set
border: 2px solid redon.article. Does it appear on the<h2>,<p>, or<li>elements? Why or why not? - Use
font: unseton the<h2>to reset its font to the browser default. What changes?
Solution
.article {
color: #1e40af;
font-family: Georgia, serif;
border: 2px solid red;
}
/* 1. h2, p, li all inherit color and font-family */
/* 2. Fix the link color */
.article a {
color: inherit; /* Now the link uses #1e40af instead of browser default blue */
}
/* 3. Border does NOT appear on children — border is a non-inherited property.
Only .article itself has the red border. */
/* 4. Reset h2 font */
.article h2 {
font: unset;
/* The h2 font-family, font-size, and font-weight all reset to their initial/inherited values.
Because font-family inherits and we unset it, it will inherit Georgia from .article.
font-size and font-weight may reset to their initial values (medium/normal). */
}
Exercise 6¶
Difficulty: Medium Objective: Debug a specificity conflict using DevTools
Given the following HTML and CSS:
<nav id="primary-nav" class="site-nav">
<a href="#" class="nav-link active">Home</a>
<a href="#" class="nav-link">About</a>
</nav>
a.nav-link {
color: #374151;
text-decoration: none;
}
.site-nav a {
color: #6b7280;
}
#primary-nav .active {
color: #2563eb;
font-weight: bold;
}
.nav-link.active {
color: hotpink; /* You want this to win */
}
- For the first
<a>(which has classesnav-linkandactive), calculate each rule's specificity and determine which color actually applies. - Without using
!importantor IDs, rewrite.nav-link.activeso it wins against#primary-nav .active.
Solution
**Specificity calculation for the first ``:** - `a.nav-link` → `(0,1,1)` → color: #374151 - `.site-nav a` → `(0,1,1)` → color: #6b7280 ← later than `a.nav-link`, so this wins over it - `#primary-nav .active` → `(1,1,0)` → color: #2563eb ← **WINS** (A=1 beats A=0) - `.nav-link.active` → `(0,2,0)` → color: hotpink ← loses to the ID rule The applied color is **#2563eb** (blue). **Fix without !important or ID:** To beat `#primary-nav .active` (which has A=1), we need our rule to also have A≥1, or... we can use `:is()` to trick specificity. Actually the only clean approaches without IDs are: Option A — restructure the HTML so the ID is not needed for this rule: Option B — use CSS cascade layers (Module 10 concept — acceptable to look up): The lesson: ID selectors in stylesheets make specificity management hard. This is why many CSS architectures (BEM, utility-first) avoid IDs entirely.Hard Exercises (7–8)¶
Exercise 7¶
Difficulty: Hard Objective: Build a complete styled page using cascade, specificity, and inheritance
Build a single HTML page that includes:
- A <header> with a site title and navigation (3 links)
- A <main> with a <section> containing an <h2>, two <p> elements, and a <blockquote>
- A <footer> with a copyright line
CSS requirements:
- Use only external CSS (no inline styles, no <style> tags)
- Set a global font using the <body> element (demonstrate inheritance)
- Use at least one class selector, one compound selector, and one pseudo-class
- Make visited links a different color from unvisited links using :visited
- The <blockquote> should have a left border and italic text
Constraint: Do not use any CSS that you need !important to make work.
Solution hint
/* Global font inheritance */
body {
font-family: system-ui, -apple-system, sans-serif;
color: #374151;
line-height: 1.6;
margin: 0;
padding: 2rem;
}
/* Header */
header {
border-bottom: 1px solid #e5e7eb;
margin-bottom: 2rem;
padding-bottom: 1rem;
}
/* Navigation links — compound selector */
nav a {
color: #2563eb;
text-decoration: none;
margin-right: 1rem;
}
/* Pseudo-class for visited state */
nav a:visited {
color: #7c3aed;
}
nav a:hover {
text-decoration: underline;
}
/* Blockquote styling */
blockquote {
border-left: 4px solid #3b82f6;
margin: 1.5rem 0;
padding: 0.5rem 1rem;
font-style: italic;
color: #6b7280;
}
footer {
margin-top: 2rem;
font-size: 0.875rem;
color: #9ca3af;
}
Exercise 8¶
Difficulty: Hard Objective: Identify and fix three CSS bugs
The following CSS is broken. Each section has a deliberate bug. Identify the bug, explain why it is a bug, and write the fix.
/* Bug 1 */
.container {
wdith: 800px; /* Bug: ??? */
max-width: 100%;
}
/* Bug 2 */
h1, h2, h3 {
font-family: 'Helvetica Neue', Arial, sans-serif
font-weight: bold; /* Bug: ??? */
}
/* Bug 3 */
.button {
color: white;
background-color: blue;
}
#submit-button {
background-color: gray;
}
.button.primary {
background-color: green; /* Bug: this never wins for <button id="submit-button" class="button primary"> */
}
Solution
**Bug 1:** `wdith` is a typo — CSS silently ignores unknown properties. **Bug 2:** Missing semicolon after `font-family` declaration. CSS will ignore `font-family` and the parser will merge the two declarations into one broken value.h1, h2, h3 {
font-family: 'Helvetica Neue', Arial, sans-serif; /* Added semicolon */
font-weight: bold;
}
Expert Exercise (9)¶
Exercise 9¶
Difficulty: Expert Objective: Explain and demonstrate the full cascade for a complex element
Given this HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<style>
/* Internal stylesheet */
p { color: purple; }
</style>
<link rel="stylesheet" href="external.css">
</head>
<body>
<article id="post" class="featured">
<p style="color: green;" class="highlight">
This paragraph has four competing color declarations.
</p>
</article>
</body>
</html>
/* external.css */
p { color: red; }
.highlight { color: blue; }
#post p { color: orange; }
article.featured .highlight { color: pink; }
- List every declaration that applies to the
<p>element for thecolorproperty. - For each, state its origin, specificity score, and position relative to others.
- Step through the cascade algorithm (origin → specificity → order) and state the winning value.
- Write a short paragraph (3–5 sentences) explaining this result to a colleague who is new to CSS.
- Bonus: What single change to the external.css would make
color: bluewin without touching the HTML or using!important?
Solution
**Declarations for `color` on the ``:** | # | Declaration | Origin | Specificity | Notes | |---|-------------|--------|-------------|-------| | 1 | `color: purple` (internal `