0. Level 0: What is CSS?
HTML creates the structure of a page. CSS controls the look of the page.
HTML
HTML says what exists on the page.
<h1>Learn CSS</h1>
<p>CSS makes pages beautiful.</p>
CSS
CSS says how those things should look.
h1 {
color: orange;
}
p {
color: #333;
}
CSS is like the dress, decoration, lighting, spacing, and animation system of a webpage.
1. What is a selector?
A CSS selector selects something from HTML.
<h1>Programmers Picnic</h1>
<p class="intro">Learn step by step.</p>
<button id="startBtn">Start</button>
h1 {
color: orange;
}
.intro {
color: brown;
}
#startBtn {
background: orange;
}
| Selector | Meaning | Example |
|---|---|---|
h1 |
Selects all h1 tags | h1 { color: orange; } |
.intro |
Selects class intro | .intro { color: brown; } |
#startBtn |
Selects id startBtn | #startBtn { background: orange; } |
:hover |
Selects a state | button:hover { ... } |
::before |
Selects a virtual part before content | h1::before { ... } |
2. What is :root?
:root means the top-level element of the webpage. In normal HTML pages, it usually means the
<html> element.
:root {
--primary: #d97706;
--background: #fff7ed;
--text: #241407;
}
The most common use of :root is to store CSS variables.
:root uses one colon because it is a pseudo-class, not a pseudo-element.
3. CSS Variables
CSS variables are reusable values. You define them once and use them many times.
:root {
--bg: #fff7ed;
--card: #ffffff;
--primary: #d97706;
--text: #241407;
--radius: 22px;
}
body {
background: var(--bg);
color: var(--text);
}
.card {
background: var(--card);
border-radius: var(--radius);
}
button {
background: var(--primary);
}
Change the value in one place and the whole design changes everywhere.
Why professionals use CSS variables
- Easy theme control
- Dark mode and light mode
- Consistent colors
- Consistent spacing
- Better maintainability
4. Pseudo-classes use one colon
A pseudo-class selects an element in a special state or condition.
button:hover {
background: black;
}
input:focus {
border-color: orange;
}
li:first-child {
font-weight: bold;
}
li:last-child {
color: red;
}
li:nth-child(even) {
background: #fff7ed;
}
| Pseudo-class | Meaning |
|---|---|
:hover |
When mouse is over the element |
:focus |
When input or button is focused |
:first-child |
Selects the first child |
:last-child |
Selects the last child |
:nth-child() |
Selects by position or pattern |
:root |
Selects the root element |
5. Pseudo-elements use double colon
A pseudo-element selects a special part of an element or creates a virtual part of an element.
h1::before {
content: "Start ";
}
h1::after {
content: " End";
}
p::first-letter {
font-size: 48px;
}
p::first-line {
font-weight: bold;
}
In the demo above, the HTML contains only Real Text. The words before and after are added by CSS.
6. Deep lesson: ::before and ::after
::before creates a virtual element before the actual content.
::after creates a virtual element after the actual content.
<h2 class="lesson-title">CSS Lesson</h2>
.lesson-title::before {
content: "Start: ";
color: orange;
}
.lesson-title::after {
content: " Done!";
color: green;
}
Visual example
.underline-demo::after {
content: "";
display: block;
height: 6px;
width: 100%;
background: orange;
border-radius: 999px;
margin-top: 8px;
}
Badge example
Python Beginner Course
This card has a badge created by ::before. No extra HTML was needed for the badge.
.badge-demo {
position: relative;
}
.badge-demo::before {
content: "Featured";
position: absolute;
top: 14px;
right: 14px;
background: orange;
color: white;
padding: 5px 10px;
border-radius: 999px;
}
7. The content property
For ::before and ::after, the content property is extremely important.
Without it, the pseudo-element usually will not appear.
No content
.box::after {
width: 100px;
height: 5px;
background: orange;
}
With content
.box::after {
content: "";
display: block;
width: 100px;
height: 5px;
background: orange;
}
Different types of content
| Code | Meaning |
|---|---|
content: ""; |
Empty content, useful for shapes and decorations |
content: "New"; |
Text content |
content: "→"; |
Symbol content |
content: attr(data-tip); |
Content from an HTML attribute |
content: counter(item); |
Content from CSS counters |
8. Professional uses of ::before and ::after
Icons
Add symbols before links, buttons, or list items.
a::before {
content: "🔗 ";
}
Underline
Create modern animated underlines.
h2::after {
content: "";
display: block;
height: 4px;
}
Badges
Add labels like New, Featured, Popular.
.card::before {
content: "New";
}
Background layers
Create decorative circles, gradients, and glows.
.hero::before {
content: "";
position: absolute;
}
Tooltips
Show small help text on hover.
.help::after {
content: attr(data-tip);
}
Watermarks
Add faint background text.
.card::after {
content: "CSS";
}
10. Live examples of important :: pseudo-elements
::first-letter
Cascading Style Sheets can turn plain writing into a professional article layout. The first letter here is designed using CSS only.
.first-letter-demo::first-letter {
font-size: 3.4rem;
float: left;
padding-right: 8px;
color: orange;
font-weight: 900;
}
::first-line
This paragraph has a first line that looks different from the rest of the paragraph. Resize the browser and observe that the first visible line can change.
.first-line-demo::first-line {
color: orange;
font-weight: 900;
}
::marker
- CSS variables
- Pseudo-classes
- Pseudo-elements
li::marker {
color: orange;
font-size: 1.3em;
content: "★ ";
}
11. Form pseudo-elements
::placeholder
input::placeholder {
color: orange;
opacity: 0.7;
}
::file-selector-button
input[type="file"]::file-selector-button {
border: 0;
padding: 10px 14px;
margin-right: 12px;
border-radius: 999px;
background: orange;
color: white;
font-weight: 800;
}
12. Tooltip using ::after and attr()
Move your mouse over this button:
Hover me
<span class="tooltip-demo" data-tip="This text comes from data-tip">
Hover me
</span>
.tooltip-demo {
position: relative;
}
.tooltip-demo::after {
content: attr(data-tip);
position: absolute;
left: 50%;
bottom: 135%;
transform: translateX(-50%);
background: #111827;
color: white;
padding: 8px 12px;
border-radius: 10px;
white-space: nowrap;
opacity: 0;
}
.tooltip-demo:hover::after {
opacity: 1;
}
13. Dialog and ::backdrop
::backdrop styles the area behind a dialog box.
dialog::backdrop {
background: rgba(36, 20, 7, 0.55);
backdrop-filter: blur(5px);
}
14. Common mistakes
Mistake 1: Forgetting content
Bad
.box::after {
display: block;
width: 100px;
height: 5px;
background: orange;
}
Good
.box::after {
content: "";
display: block;
width: 100px;
height: 5px;
background: orange;
}
Mistake 2: Forgetting position: relative
Bad
.card::before {
content: "";
position: absolute;
top: 0;
right: 0;
}
Good
.card {
position: relative;
}
.card::before {
content: "";
position: absolute;
top: 0;
right: 0;
}
Mistake 3: Expecting ::before and ::after on every tag
Pseudo-elements may not work reliably on replaced elements like img, input, and
br.
::before or ::after
to the wrapper.
<div class="image-wrap">
<img src="photo.jpg" alt="Photo">
</div>
.image-wrap {
position: relative;
}
.image-wrap::after {
content: "";
position: absolute;
inset: 0;
border: 4px solid orange;
}
15. Mini projects
Project 1: Heading underline
<h2 class="heading">Learn Python</h2>
.heading::after {
content: "";
display: block;
width: 90px;
height: 5px;
background: orange;
border-radius: 999px;
margin-top: 10px;
}
Project 2: Button arrow
<a class="arrow-btn" href="#">Start Learning</a>
.arrow-btn::after {
content: " →";
}
Project 3: Course card badge
<div class="course-card">
<h2>AI Beginner Course</h2>
<p>Start from zero.</p>
</div>
.course-card {
position: relative;
}
.course-card::before {
content: "New";
position: absolute;
top: 12px;
right: 12px;
background: orange;
color: white;
padding: 5px 10px;
border-radius: 999px;
}
16. Final memory map
| Selector | Colon type | Meaning |
|---|---|---|
:root |
Single colon | Root element, usually used for CSS variables |
:hover |
Single colon | Mouse is over the element |
:focus |
Single colon | Element is focused |
:nth-child() |
Single colon | Selects children by position or pattern |
::before |
Double colon | Creates virtual content before |
::after |
Double colon | Creates virtual content after |
::first-letter |
Double colon | Styles first letter |
::first-line |
Double colon | Styles first visible line |
::selection |
Double colon | Styles selected text |
::marker |
Double colon | Styles list marker |
::placeholder |
Double colon | Styles placeholder text |
::file-selector-button |
Double colon | Styles file input button |
::backdrop |
Double colon | Styles background behind dialog/fullscreen |
17. Practice assignments
- Create a page theme using
:rootvariables. - Create a heading underline using
::after. - Create a card badge using
::before. - Create a list with check marks using
li::before. - Create an input with styled
::placeholder. - Create a file upload button using
::file-selector-button. - Create a tooltip using
attr(data-tip)and::after. - Create a quote paragraph using
::first-letter. - Create custom bullet points using
::marker. - Create a dialog with styled
::backdrop.