CSS Tips & Tricks contd
🎭 CSS Pseudo-elements Explained
🔹 What Are Pseudo-elements?
A pseudo-element lets you style specific parts of an element’s content — even parts that don’t exist in your HTML.
They act like virtual child elements created by CSS.
They start with a double colon :: (modern syntax).
Examples:
::before::after::first-line::first-letter::selection
🧩 Commonly Used Pseudo-elements
1️⃣ ::before
Creates a virtual element before the content of an element.
.button::before {
content: "🔥 ";
}
➡️ Adds a fire emoji before every .button text.
Note: You must set content (even an empty string) for it to appear.
2️⃣ ::after
Creates a virtual element after the content.
.button::after {
content: " →";
}
Useful for decorative icons, animations, or stylistic accents.
3️⃣ ::first-line
Styles only the first line of a block element.
p::first-line {
font-weight: bold;
color: #444;
}
4️⃣ ::first-letter
Targets just the first character.
p::first-letter {
font-size: 2rem;
font-weight: bold;
color: #f57c00;
}
Creates that magazine-style drop cap look 📰
5️⃣ ::selection
Styles the text highlight color (when the user selects text).
::selection {
background: #000;
color: #fff;
}
➡️ Works for all selectable text. You can limit it to specific elements:
p::selection {
background: #ff0;
color: #000;
}
🎨 Advanced Example — Decorative Labels
.card {
position: relative;
padding: 1rem;
border: 1px solid #ddd;
}
.card::before {
content: "TIP";
position: absolute;
top: -10px;
left: 10px;
background: #4caf50;
color: white;
font-size: 0.75rem;
padding: 2px 6px;
border-radius: 4px;
}
💡 This adds a small “TIP” label without extra HTML markup.
⚙️ Combine with Transitions & Animations
Pseudo-elements are perfect for hover effects, underlines, or animated overlays.
.link {
position: relative;
text-decoration: none;
}
.link::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 0%;
height: 2px;
background: #007bff;
transition: width 0.3s;
}
.link:hover::after {
width: 100%;
}
➡️ Smooth animated underline effect without extra <span> tags.
🧠 Remember
::beforeand::afteronly work on elements that can contain content (not on<img>,<input>, etc.).They are inline by default but can be styled with
display: block,position: absolute, etc.The older syntax
:beforeand:afterstill work for backward compatibility.
🪄 Bonus: Tailwind Trick (Custom Layer)
While Tailwind doesn’t directly style pseudo-elements, you can use its plugin system or custom CSS layers:
@layer utilities {
.before-line::before {
content: "";
position: absolute;
width: 100%;
height: 2px;
background: currentColor;
}
}
🧰 Summary Table
| Pseudo-element | Purpose |
::before | Insert content before an element |
::after | Insert content after an element |
::first-line | Style only the first line |
::first-letter | Style only the first letter |
::selection | Customize text highlight |
::backdrop | Style backdrop in <dialog> or fullscreen mode |
Perfect 👏 Jeevan — now we’re getting into pseudo-classes, the sibling concept to pseudo-elements.
Where pseudo-elements create virtual elements,
pseudo-classes target existing elements in specific states — like hover, focus, checked, nth-child, etc.
Here’s a clear breakdown — plus a ready-to-paste Hashnode Markdown section that fits seamlessly into your ongoing “CSS Tips & Tricks” article.
🧩 CSS Pseudo-classes Explained
🔹 What Are Pseudo-classes?
A pseudo-class is a keyword added to selectors that specifies a special state of an element.
They start with a single colon : (unlike pseudo-elements ::).
Examples:
:hover:focus:first-child:checked:disabled
🎯 Basic Syntax
selector:pseudo-class {
property: value;
}
🌈 Common Pseudo-classes
1️⃣ :hover
Applies styles when the user hovers over an element.
button:hover {
background: #1e90ff;
color: white;
}
💡 Tip: Great for interactive feedback.
2️⃣ :focus
Triggers when an element (like an input) is focused — clicked or tabbed into.
input:focus {
border-color: #007bff;
outline: none;
box-shadow: 0 0 4px #007bff;
}
3️⃣ :active
Applies when an element is being clicked or pressed.
button:active {
transform: scale(0.98);
}
4️⃣ :checked
Used for checkboxes, radio buttons, and switches.
input[type="checkbox"]:checked {
accent-color: #4caf50;
}
5️⃣ :disabled
Targets form elements that are disabled.
button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
6️⃣ :first-child & :last-child
Select elements that are the first or last child within a parent.
.list-item:first-child {
font-weight: bold;
}
.list-item:last-child {
color: crimson;
}
7️⃣ :nth-child()
Selects elements based on their order (useful in grids and lists).
li:nth-child(2) {
color: #ff9800; /* Second item */
}
li:nth-child(odd) {
background: #f9f9f9;
}
8️⃣ :not()
Excludes elements that match a selector.
button:not(.primary) {
background: #ddd;
}
9️⃣ :empty
Matches elements with no children (no text, no elements).
div:empty {
display: none;
}
🔟 :root
Targets the root element (<html>). Commonly used for global variables.
:root {
--brand-color: #0d6efd;
--text-dark: #222;
}
💫 Advanced UI Selectors
| Pseudo-class | Description | Example |
:focus-within | When an element or any child has focus | .form:focus-within { border-color: blue; } |
:has() | Selects parent based on child condition (CSS4+) | .card:has(img:hover) |
:target | When element is targeted by a fragment (#section) | #section1:target { background: yellow; } |
:nth-of-type() | Matches based on element type | p:nth-of-type(2) |
:only-child | When an element has no siblings | .item:only-child { color: red; } |
🧠 Pseudo-class vs Pseudo-element
| Type | Syntax | What it Targets | Example |
| Pseudo-class | : | Existing element state | :hover, :focus, :checked |
| Pseudo-element | :: | Virtual part of element | ::before, ::after, ::first-letter |
🪄 Bonus: Tailwind Equivalents
Tailwind handles pseudo-classes via variants:
<button class="bg-blue-500 hover:bg-blue-700 focus:ring-2 active:scale-95">
Hover me
</button>
| CSS Pseudo-class | Tailwind Variant |
:hover | hover: |
:focus | focus: |
:active | active: |
:disabled | disabled: |
:checked | checked: |
:focus-within | focus-within: |
:first-child | first: |
:last-child | last: |
:odd / :even | odd: / even: |
:not() | not-*: (via plugin) |
⚙️ Example: Animated Button with Pseudo-classes
.button {
background: #007bff;
color: #fff;
padding: 0.75rem 1.5rem;
border: none;
border-radius: 4px;
transition: all 0.2s ease;
}
.button:hover {
background: #0056b3;
}
.button:active {
transform: scale(0.96);
}
.button:focus {
outline: 2px solid #80bdff;
outline-offset: 2px;
}
Result 👉 Interactive button with hover, focus, and active states — all via pseudo-classes.