CSS Pseudo-Classes 🎯
Select and style elements based on their state, position, and interaction using powerful CSS pseudo-classes.
What are Pseudo-Classes?
Pseudo-classes are keywords added to selectors that specify a special state of the selected elements. They allow you to style elements based on user interaction, element position, form states, and more.
🎮 Interactive States
:hover, :active, :focus for user interactions
📊 Structural Selection
:nth-child, :first-child for element position
✅ Form States
:valid, :invalid, :required for form validation
Interactive Pseudo-Classes
Common Interactive States:
:hover- When mouse is over element:active- When element is being activated/clicked:focus- When element has keyboard focus:visited- For links that have been visited:link- For unvisited links
Interactive Demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Interactive Pseudo-Classes Demo</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', sans-serif;
line-height: 1.6;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 2rem;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: white;
border-radius: 20px;
padding: 3rem;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
h1 {
color: #2d3748;
margin-bottom: 2rem;
text-align: center;
font-size: 2.5rem;
}
.demo-section {
background: #f8fafc;
padding: 2rem;
border-radius: 15px;
margin: 2rem 0;
border-left: 4px solid #667eea;
}
.code-example {
background: #2d3748;
color: #81e6d9;
padding: 1rem;
border-radius: 8px;
font-family: monospace;
margin: 1rem 0;
font-size: 0.9rem;
}
/* Interactive Demo Styles */
.interactive-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
margin: 2rem 0;
}
.demo-item {
background: white;
padding: 2rem;
border-radius: 12px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
text-align: center;
transition: all 0.3s ease;
}
/* :hover Pseudo-class */
.hover-demo {
background: #e3f2fd;
border: 2px solid #2196f3;
cursor: pointer;
}
.hover-demo:hover {
background: #bbdefb;
transform: translateY(-5px);
box-shadow: 0 8px 15px rgba(33, 150, 243, 0.3);
}
/* :active Pseudo-class */
.active-demo {
background: #ffe0b2;
border: 2px solid #ff9800;
cursor: pointer;
user-select: none;
}
.active-demo:active {
background: #ffcc80;
transform: scale(0.95);
}
/* :focus Pseudo-class */
.focus-demo {
background: #e8f5e8;
border: 2px solid #4caf50;
padding: 1rem;
outline: none;
}
.focus-demo:focus {
background: #c8e6c9;
border-color: #2e7d32;
box-shadow: 0 0 0 3px rgba(76, 175, 80, 0.3);
}
/* :nth-child Pseudo-class */
.nth-child-demo {
display: flex;
gap: 1rem;
flex-wrap: wrap;
justify-content: center;
}
.nth-child-demo div {
width: 50px;
height: 50px;
background: #f48fb1;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8px;
font-weight: bold;
color: white;
}
.nth-child-demo div:nth-child(odd) {
background: #7986cb;
}
.nth-child-demo div:nth-child(3n) {
transform: rotate(15deg);
}
.nth-child-demo div:nth-child(2n+1):hover {
background: #5c6bc0;
transform: scale(1.2);
}
/* :checked Pseudo-class */
.checkbox-demo {
display: flex;
gap: 2rem;
justify-content: center;
margin: 1rem 0;
}
.checkbox-demo input[type="checkbox"] {
display: none;
}
.checkbox-demo label {
padding: 1rem 2rem;
background: #f5f5f5;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s;
border: 2px solid #ddd;
}
.checkbox-demo input[type="checkbox"]:checked + label {
background: #4caf50;
color: white;
border-color: #2e7d32;
transform: scale(1.05);
}
/* :not() Pseudo-class */
.not-demo {
display: flex;
gap: 1rem;
justify-content: center;
flex-wrap: wrap;
}
.not-demo button {
padding: 0.8rem 1.5rem;
border: none;
border-radius: 6px;
background: #2196f3;
color: white;
cursor: pointer;
transition: all 0.3s;
}
.not-demo button:not(.special) {
background: #757575;
}
.not-demo button:hover:not(.special) {
background: #424242;
}
.not-demo button.special {
background: #ff9800;
}
.not-demo button.special:hover {
background: #f57c00;
transform: scale(1.1);
}
/* First and Last Child */
.first-last-demo {
display: flex;
gap: 1rem;
justify-content: center;
}
.first-last-demo p {
padding: 1rem;
background: #e1f5fe;
border-radius: 6px;
margin: 0.5rem;
}
.first-last-demo p:first-child {
background: #b3e5fc;
font-weight: bold;
}
.first-last-demo p:last-child {
background: #81d4fa;
font-style: italic;
}
.first-last-demo p:nth-child(2) {
background: #4fc3f7;
}
</style>
</head>
<body>
<div class="container">
<h1>🎯 CSS Pseudo-Classes Interactive Demo</h1>
<div class="demo-section">
<h2>:hover - Mouse Over Effect</h2>
<div class="code-example">
.element:hover {<br>
background: #bbdefb;<br>
transform: translateY(-5px);<br>
}
</div>
<div class="interactive-grid">
<div class="demo-item hover-demo">
<h3>Hover Over Me!</h3>
<p>Move your mouse over this box to see the :hover effect</p>
</div>
</div>
</div>
<div class="demo-section">
<h2>:active - Click Effect</h2>
<div class="code-example">
.element:active {<br>
transform: scale(0.95);<br>
background: #ffcc80;<br>
}
</div>
<div class="interactive-grid">
<div class="demo-item active-demo">
<h3>Click and Hold!</h3>
<p>Click and hold this box to see the :active effect</p>
</div>
</div>
</div>
<div class="demo-section">
<h2>:focus - Input Focus</h2>
<div class="code-example">
input:focus {<br>
box-shadow: 0 0 0 3px rgba(76, 175, 80, 0.3);<br>
border-color: #2e7d32;<br>
}
</div>
<div class="interactive-grid">
<div class="demo-item">
<h3>Focus on Input</h3>
<input type="text" class="focus-demo" placeholder="Click here to focus">
<p style="margin-top: 1rem;">Click the input field to see :focus effect</p>
</div>
</div>
</div>
<div class="demo-section">
<h2>:nth-child() - Pattern Selection</h2>
<div class="code-example">
div:nth-child(odd) { background: #7986cb; }<br>
div:nth-child(3n) { transform: rotate(15deg); }<br>
div:nth-child(2n+1):hover { transform: scale(1.2); }
</div>
<div class="demo-item">
<h3>Number Patterns</h3>
<div class="nth-child-demo">
<div>1</div><div>2</div><div>3</div><div>4</div><div>5</div>
<div>6</div><div>7</div><div>8</div><div>9</div><div>10</div>
</div>
<p>Odd numbers are blue, every 3rd is rotated, hover effects vary!</p>
</div>
</div>
<div class="demo-section">
<h2>:checked - Toggle States</h2>
<div class="code-example">
input[type="checkbox"]:checked + label {<br>
background: #4caf50;<br>
transform: scale(1.05);<br>
}
</div>
<div class="demo-item">
<h3>Toggle These Options</h3>
<div class="checkbox-demo">
<input type="checkbox" id="option1">
<label for="option1">Feature 1</label>
<input type="checkbox" id="option2">
<label for="option2">Feature 2</label>
<input type="checkbox" id="option3">
<label for="option3">Feature 3</label>
</div>
<p>Click the options to see :checked state changes</p>
</div>
</div>
<div class="demo-section">
<h2>:not() - Exclusion Selector</h2>
<div class="code-example">
button:not(.special) { background: #757575; }<br>
button.special { background: #ff9800; }
</div>
<div class="demo-item">
<h3>All Buttons Except Special</h3>
<div class="not-demo">
<button>Normal</button>
<button>Normal</button>
<button class="special">Special</button>
<button>Normal</button>
<button class="special">Special</button>
</div>
<p>The :not() selector excludes elements from being selected</p>
</div>
</div>
<div class="demo-section">
<h2>:first-child, :last-child</h2>
<div class="code-example">
p:first-child { background: #b3e5fc; }<br>
p:last-child { background: #81d4fa; }<br>
p:nth-child(2) { background: #4fc3f7; }
</div>
<div class="demo-item">
<h3>First and Last Elements</h3>
<div class="first-last-demo">
<p>First Child</p>
<p>Middle Child</p>
<p>Last Child</p>
</div>
<p>Different styles for first, middle, and last elements</p>
</div>
</div>
</div>
</body>
</html>Form Pseudo-Classes
Validation States
Use pseudo-classes to provide visual feedback for form validation without JavaScript.
Input States
Control how form elements appear in different states like disabled, read-only, or checked.
Form Validation Demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Form Pseudo-Classes Demo</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', sans-serif;
line-height: 1.6;
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
min-height: 100vh;
padding: 2rem;
}
.container {
max-width: 800px;
margin: 0 auto;
background: white;
border-radius: 20px;
padding: 3rem;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
h1 {
color: #2d3748;
margin-bottom: 2rem;
text-align: center;
font-size: 2.5rem;
}
.form-section {
background: #f8fafc;
padding: 2rem;
border-radius: 15px;
margin: 2rem 0;
border-left: 4px solid #4facfe;
}
.code-example {
background: #2d3748;
color: #81e6d9;
padding: 1rem;
border-radius: 8px;
font-family: monospace;
margin: 1rem 0;
font-size: 0.9rem;
}
/* Form Styles */
.form-group {
margin-bottom: 1.5rem;
}
label {
display: block;
margin-bottom: 0.5rem;
font-weight: 600;
color: #2d3748;
}
input, select, textarea {
width: 100%;
padding: 0.8rem;
border: 2px solid #e2e8f0;
border-radius: 8px;
font-size: 1rem;
transition: all 0.3s ease;
}
/* :required and :optional */
input:required {
border-left: 4px solid #e53e3e;
background: #fed7d7;
}
input:optional {
border-left: 4px solid #38a169;
background: #f0fff4;
}
/* :valid and :invalid */
input:valid {
border-color: #38a169;
background: #f0fff4;
}
input:invalid {
border-color: #e53e3e;
background: #fed7d7;
}
input:focus:invalid {
box-shadow: 0 0 0 3px rgba(229, 62, 62, 0.3);
}
input:focus:valid {
box-shadow: 0 0 0 3px rgba(56, 161, 105, 0.3);
}
/* :in-range and :out-of-range */
input[type="number"]:in-range {
border-color: #3182ce;
background: #ebf8ff;
}
input[type="number"]:out-of-range {
border-color: #d69e2e;
background: #fefcbf;
}
/* :disabled and :enabled */
input:disabled {
background: #f7fafc;
color: #a0aec0;
cursor: not-allowed;
}
input:enabled {
background: white;
}
/* :read-only and :read-write */
input:read-only {
background: #f7fafc;
color: #718096;
}
input:read-write {
background: white;
color: #2d3748;
}
/* Checkbox and Radio Styles */
.checkbox-group, .radio-group {
display: flex;
gap: 2rem;
margin: 1rem 0;
}
input[type="checkbox"], input[type="radio"] {
width: auto;
margin-right: 0.5rem;
}
/* :checked styles for custom checkboxes */
.custom-checkbox {
position: relative;
padding-left: 2rem;
cursor: pointer;
}
.custom-checkbox input {
display: none;
}
.custom-checkbox .checkmark {
position: absolute;
left: 0;
top: 0;
height: 1.2rem;
width: 1.2rem;
background: #e2e8f0;
border-radius: 4px;
transition: all 0.3s;
}
.custom-checkbox input:checked + .checkmark {
background: #4facfe;
}
.custom-checkbox input:checked + .checkmark::after {
content: "✓";
color: white;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
/* Submit Button */
.submit-btn {
background: #4facfe;
color: white;
padding: 1rem 2rem;
border: none;
border-radius: 8px;
font-size: 1.1rem;
cursor: pointer;
transition: all 0.3s;
width: 100%;
}
.submit-btn:hover {
background: #3a8bd6;
transform: translateY(-2px);
}
.submit-btn:active {
transform: translateY(0);
}
.submit-btn:disabled {
background: #a0aec0;
cursor: not-allowed;
transform: none;
}
/* Focus styles for accessibility */
*:focus {
outline: 2px solid #4facfe;
outline-offset: 2px;
}
/* Demo info boxes */
.demo-info {
background: #e3f2fd;
padding: 1rem;
border-radius: 8px;
margin: 1rem 0;
border-left: 4px solid #2196f3;
}
</style>
</head>
<body>
<div class="container">
<h1>📝 Form Pseudo-Classes Demo</h1>
<div class="form-section">
<h2>Form Validation States</h2>
<div class="code-example">
input:required { border-left: 4px solid red; }<br>
input:valid { border-color: green; }<br>
input:invalid { border-color: red; }
</div>
<form>
<div class="form-group">
<label for="email">Email Address *</label>
<input type="email" id="email" required placeholder="Enter valid email">
<div class="demo-info">
<strong>:required</strong> - Red border for required fields<br>
<strong>:valid/:invalid</strong> - Green/Red based on validation
</div>
</div>
<div class="form-group">
<label for="phone">Phone Number (Optional)</label>
<input type="tel" id="phone" placeholder="Optional field">
<div class="demo-info">
<strong>:optional</strong> - Green border for optional fields
</div>
</div>
<div class="form-group">
<label for="age">Age (10-100)</label>
<input type="number" id="age" min="10" max="100" value="25" required>
<div class="demo-info">
<strong>:in-range/:out-of-range</strong> - Different styles for valid/invalid ranges
</div>
</div>
<div class="form-group">
<label for="username">Username</label>
<input type="text" id="username" required pattern="[A-Za-z]{3,}">
<div class="demo-info">
<strong>pattern attribute</strong> - Uses regex validation with :valid/:invalid
</div>
</div>
<div class="form-group">
<label for="readonly">Read-only Field</label>
<input type="text" id="readonly" value="This field is read-only" readonly>
<div class="demo-info">
<strong>:read-only</strong> - Different styling for non-editable fields
</div>
</div>
<div class="form-group">
<label>Custom Checkboxes</label>
<div class="checkbox-group">
<label class="custom-checkbox">
<input type="checkbox" checked>
<span class="checkmark"></span>
Option 1
</label>
<label class="custom-checkbox">
<input type="checkbox">
<span class="checkmark"></span>
Option 2
</label>
</div>
<div class="demo-info">
<strong>:checked</strong> - Custom styles for checked state
</div>
</div>
<div class="form-group">
<label for="disabled">Disabled Field</label>
<input type="text" id="disabled" value="This field is disabled" disabled>
<div class="demo-info">
<strong>:disabled</strong> - Grayed out and non-interactive
</div>
</div>
<button type="submit" class="submit-btn">Submit Form</button>
</form>
</div>
<div class="form-section">
<h2>Interactive Demo Instructions</h2>
<div class="demo-info">
<p><strong>Try these interactions:</strong></p>
<ul>
<li>Enter invalid email to see :invalid state</li>
<li>Enter valid email to see :valid state</li>
<li>Type less than 3 characters in username</li>
<li>Enter age outside 10-100 range</li>
<li>Click checkboxes to see :checked state</li>
<li>Try focusing on different fields</li>
</ul>
</div>
</div>
</div>
</body>
</html>Advanced Pseudo-Classes
Structural & URL-based Selection
Advanced pseudo-classes allow selection based on element position, content, and even URL fragments.
Advanced Techniques Demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Advanced Pseudo-Classes Demo</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', sans-serif;
line-height: 1.6;
background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%);
min-height: 100vh;
padding: 2rem;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: white;
border-radius: 20px;
padding: 3rem;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
h1 {
color: #2d3748;
margin-bottom: 2rem;
text-align: center;
font-size: 2.5rem;
}
.demo-section {
background: #f8fafc;
padding: 2rem;
border-radius: 15px;
margin: 2rem 0;
border-left: 4px solid #ff9a9e;
}
.code-example {
background: #2d3748;
color: #81e6d9;
padding: 1rem;
border-radius: 8px;
font-family: monospace;
margin: 1rem 0;
font-size: 0.9rem;
}
/* :target Demo */
.target-demo {
margin: 2rem 0;
}
.target-nav {
display: flex;
gap: 1rem;
margin-bottom: 1rem;
}
.target-nav a {
padding: 0.5rem 1rem;
background: #e3f2fd;
border-radius: 6px;
text-decoration: none;
color: #1976d2;
transition: all 0.3s;
}
.target-content div {
padding: 2rem;
margin: 1rem 0;
background: white;
border-radius: 8px;
border: 2px solid transparent;
display: none;
}
.target-content div:target {
display: block;
border-color: #1976d2;
background: #e3f2fd;
animation: fadeIn 0.5s ease;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
/* :empty Demo */
.empty-demo {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
margin: 1rem 0;
}
.empty-box {
padding: 2rem;
background: #f5f5f5;
border-radius: 8px;
text-align: center;
min-height: 100px;
border: 2px solid #ddd;
}
.empty-box:empty {
background: #ffebee;
border-color: #f44336;
position: relative;
}
.empty-box:empty::after {
content: "Empty!";
color: #f44336;
font-style: italic;
}
/* :lang() Demo */
.lang-demo {
margin: 2rem 0;
}
.lang-demo p:lang(en) {
background: #e3f2fd;
padding: 1rem;
border-left: 4px solid #2196f3;
}
.lang-demo p:lang(es) {
background: #e8f5e8;
padding: 1rem;
border-left: 4px solid #4caf50;
}
.lang-demo p:lang(fr) {
background: #f3e5f5;
padding: 1rem;
border-left: 4px solid #9c27b0;
}
/* Structural Pseudo-classes */
.structural-demo {
display: flex;
gap: 1rem;
flex-wrap: wrap;
justify-content: center;
margin: 2rem 0;
}
.structural-demo div {
padding: 1rem;
background: #f5f5f5;
border-radius: 6px;
min-width: 80px;
text-align: center;
}
.structural-demo div:first-of-type {
background: #bbdefb;
font-weight: bold;
}
.structural-demo div:last-of-type {
background: #c8e6c9;
font-style: italic;
}
.structural-demo div:nth-of-type(3n) {
transform: rotate(-5deg);
}
/* :root Demo */
:root {
--primary-color: #ff6b6b;
--secondary-color: #4ecdc4;
--spacing: 1rem;
}
.root-demo {
background: var(--primary-color);
color: white;
padding: var(--spacing);
border-radius: 8px;
margin: 1rem 0;
}
.root-demo:nth-child(even) {
background: var(--secondary-color);
}
/* Interactive Elements */
.interactive-demo {
margin: 2rem 0;
}
.interactive-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
}
.interactive-item {
padding: 1.5rem;
background: white;
border-radius: 8px;
border: 2px solid #e0e0e0;
transition: all 0.3s;
cursor: pointer;
}
.interactive-item:hover {
border-color: var(--primary-color);
transform: translateY(-2px);
}
.interactive-item:active {
transform: translateY(0);
}
/* Demo Controls */
.demo-controls {
background: #fff3e0;
padding: 1rem;
border-radius: 8px;
margin: 1rem 0;
border-left: 4px solid #ff9800;
}
</style>
</head>
<body>
<div class="container">
<h1>🚀 Advanced Pseudo-Classes Demo</h1>
<div class="demo-section">
<h2>:target - URL Fragment Navigation</h2>
<div class="code-example">
div:target {<br>
display: block;<br>
border-color: #1976d2;<br>
animation: fadeIn 0.5s ease;<br>
}
</div>
<div class="target-demo">
<div class="target-nav">
<a href="#tab1">Tab 1</a>
<a href="#tab2">Tab 2</a>
<a href="#tab3">Tab 3</a>
</div>
<div class="target-content">
<div id="tab1">
<h3>Tab 1 Content</h3>
<p>This content is shown because #tab1 is in the URL</p>
</div>
<div id="tab2">
<h3>Tab 2 Content</h3>
<p>Click the tabs above to change the URL fragment</p>
</div>
<div id="tab3">
<h3>Tab 3 Content</h3>
<p>:target selects the element with ID matching URL fragment</p>
</div>
</div>
</div>
</div>
<div class="demo-section">
<h2>:empty - Empty Element Detection</h2>
<div class="code-example">
.element:empty {<br>
background: #ffebee;<br>
border-color: #f44336;<br>
}<br>
.element:empty::after {<br>
content: "Empty!";<br>
}
</div>
<div class="empty-demo">
<div class="empty-box">I have content</div>
<div class="empty-box"></div>
<div class="empty-box">Another box with text</div>
<div class="empty-box"><!-- This comment doesn't count as content --></div>
</div>
<p>:empty selects elements with no children (including text nodes)</p>
</div>
<div class="demo-section">
<h2>:lang() - Language Specific Styles</h2>
<div class="code-example">
p:lang(en) { background: #e3f2fd; }<br>
p:lang(es) { background: #e8f5e8; }<br>
p:lang(fr) { background: #f3e5f5; }
</div>
<div class="lang-demo">
<p lang="en">This is an English paragraph with specific styling.</p>
<p lang="es">Este es un párrafo en español con estilo específico.</p>
<p lang="fr">Ceci est un paragraphe en français avec un style spécifique.</p>
</div>
</div>
<div class="demo-section">
<h2>Structural Pseudo-classes</h2>
<div class="code-example">
div:first-of-type { background: #bbdefb; }<br>
div:last-of-type { background: #c8e6c9; }<br>
div:nth-of-type(3n) { transform: rotate(-5deg); }
</div>
<div class="structural-demo">
<div>First</div>
<div>Second</div>
<div>Third</div>
<div>Fourth</div>
<div>Fifth</div>
<div>Sixth</div>
<div>Seventh</div>
<div>Eighth</div>
</div>
</div>
<div class="demo-section">
<h2>:root - CSS Variables Scope</h2>
<div class="code-example">
:root {<br>
--primary-color: #ff6b6b;<br>
--secondary-color: #4ecdc4;<br>
--spacing: 1rem;<br>
}<br><br>
.element {<br>
background: var(--primary-color);<br>
padding: var(--spacing);<br>
}
</div>
<div class="root-demo">Primary Color from :root</div>
<div class="root-demo">Secondary Color (even child)</div>
<div class="root-demo">Primary Color again</div>
</div>
<div class="demo-controls">
<h3>💡 Pro Tips</h3>
<ul>
<li>Use :target for single-page applications without JavaScript</li>
<li>:empty is great for dynamic content that might be empty</li>
<li>:lang() helps with internationalization and accessibility</li>
<li>Structural pseudo-classes work based on element type</li>
<li>:root is perfect for CSS custom properties (variables)</li>
</ul>
</div>
</div>
</body>
</html>Practical Real-World Examples
📋 Navigation Menus
Interactive nav states with hover and active effects
📊 Data Tables
Zebra striping and row hover effects
✅ Form Validation
Real-time validation feedback
Practical Implementation
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Practical Pseudo-Classes Examples</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', sans-serif;
line-height: 1.6;
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
min-height: 100vh;
padding: 2rem;
}
.container {
max-width: 1400px;
margin: 0 auto;
}
h1 {
color: #2d3748;
margin-bottom: 2rem;
text-align: center;
font-size: 2.5rem;
}
/* Navigation Menu */
.nav-menu {
background: white;
border-radius: 15px;
padding: 2rem;
margin: 2rem 0;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
.nav-list {
list-style: none;
display: flex;
gap: 0;
background: #f8fafc;
border-radius: 10px;
overflow: hidden;
}
.nav-list li {
flex: 1;
}
.nav-list a {
display: block;
padding: 1rem 2rem;
text-decoration: none;
color: #4a5568;
text-align: center;
transition: all 0.3s;
border-bottom: 3px solid transparent;
}
.nav-list a:hover {
background: #e2e8f0;
color: #2d3748;
}
.nav-list a:active {
background: #cbd5e0;
transform: scale(0.98);
}
.nav-list a:focus {
outline: 2px solid #667eea;
outline-offset: -2px;
}
/* Current page indicator */
.nav-list a[aria-current="page"] {
background: #667eea;
color: white;
border-bottom-color: #4c51bf;
}
/* Table Styles */
.data-table {
width: 100%;
background: white;
border-radius: 15px;
overflow: hidden;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
margin: 2rem 0;
}
.data-table table {
width: 100%;
border-collapse: collapse;
}
.data-table th {
background: #667eea;
color: white;
padding: 1rem;
text-align: left;
}
.data-table td {
padding: 1rem;
border-bottom: 1px solid #e2e8f0;
}
.data-table tr:nth-child(even) {
background: #f8fafc;
}
.data-table tr:hover {
background: #e2e8f0;
transform: scale(1.01);
transition: all 0.2s;
}
.data-table tr:last-child td {
border-bottom: none;
}
/* Card Grid */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
margin: 2rem 0;
}
.card {
background: white;
border-radius: 15px;
padding: 2rem;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
transition: all 0.3s;
border: 2px solid transparent;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
border-color: #667eea;
}
.card:active {
transform: translateY(-2px);
}
.card:nth-child(3n+1) {
border-left: 4px solid #667eea;
}
.card:nth-child(3n+2) {
border-left: 4px solid #4ecdc4;
}
.card:nth-child(3n+3) {
border-left: 4px solid #ff6b6b;
}
/* Button Group */
.button-group {
display: flex;
gap: 1rem;
margin: 2rem 0;
flex-wrap: wrap;
}
.btn {
padding: 1rem 2rem;
border: none;
border-radius: 8px;
font-size: 1rem;
cursor: pointer;
transition: all 0.3s;
position: relative;
overflow: hidden;
}
.btn-primary {
background: #667eea;
color: white;
}
.btn-primary:hover {
background: #5a67d8;
transform: translateY(-2px);
}
.btn-primary:active {
transform: translateY(0);
}
.btn-primary:focus {
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.3);
}
.btn-secondary {
background: #e2e8f0;
color: #4a5568;
}
.btn-secondary:hover:not(:disabled) {
background: #cbd5e0;
}
.btn:disabled {
background: #a0aec0;
cursor: not-allowed;
transform: none !important;
}
/* Form Validation */
.form-container {
background: white;
border-radius: 15px;
padding: 2rem;
margin: 2rem 0;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
.form-group {
margin-bottom: 1.5rem;
}
.form-group input {
width: 100%;
padding: 1rem;
border: 2px solid #e2e8f0;
border-radius: 8px;
font-size: 1rem;
transition: all 0.3s;
}
.form-group input:focus {
border-color: #667eea;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
.form-group input:invalid {
border-color: #e53e3e;
}
.form-group input:valid {
border-color: #38a169;
}
/* Progress Indicator */
.progress-steps {
display: flex;
margin: 2rem 0;
background: white;
border-radius: 15px;
padding: 2rem;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
.step {
flex: 1;
text-align: center;
padding: 1rem;
position: relative;
}
.step:not(:last-child)::after {
content: '';
position: absolute;
top: 50%;
right: 0;
width: 50%;
height: 2px;
background: #e2e8f0;
z-index: 1;
}
.step.active {
color: #667eea;
font-weight: bold;
}
.step.active::before {
content: '✓';
background: #667eea;
color: white;
width: 30px;
height: 30px;
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
margin-bottom: 0.5rem;
}
.step:not(.active)::before {
content: counter(step);
background: #e2e8f0;
color: #a0aec0;
width: 30px;
height: 30px;
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
margin-bottom: 0.5rem;
}
.progress-steps {
counter-reset: step;
}
.step {
counter-increment: step;
}
</style>
</head>
<body>
<div class="container">
<h1>💼 Practical Pseudo-Classes Examples</h1>
<!-- Navigation Menu -->
<nav class="nav-menu">
<h2>📋 Navigation Menu with States</h2>
<ul class="nav-list">
<li><a href="#" aria-current="page">Dashboard</a></li>
<li><a href="#">Projects</a></li>
<li><a href="#">Team</a></li>
<li><a href="#">Calendar</a></li>
<li><a href="#">Reports</a></li>
</ul>
<p style="margin-top: 1rem; color: #666;">
Uses: :hover, :active, :focus, and attribute selectors for current page
</p>
</nav>
<!-- Data Table -->
<div class="data-table">
<h2>📊 Data Table with Zebra Striping</h2>
<table>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr>
<td>John Doe</td>
<td>john@example.com</td>
<td>Active</td>
<td>
<button class="btn btn-primary" style="padding: 0.5rem 1rem; font-size: 0.9rem;">Edit</button>
</td>
</tr>
<tr>
<td>Jane Smith</td>
<td>jane@example.com</td>
<td>Inactive</td>
<td>
<button class="btn btn-primary" style="padding: 0.5rem 1rem; font-size: 0.9rem;">Edit</button>
</td>
</tr>
<tr>
<td>Mike Johnson</td>
<td>mike@example.com</td>
<td>Active</td>
<td>
<button class="btn btn-primary" style="padding: 0.5rem 1rem; font-size: 0.9rem;">Edit</button>
</td>
</tr>
<tr>
<td>Sarah Wilson</td>
<td>sarah@example.com</td>
<td>Pending</td>
<td>
<button class="btn btn-primary" style="padding: 0.5rem 1rem; font-size: 0.9rem;">Edit</button>
</td>
</tr>
</tbody>
</table>
<p style="padding: 1rem; color: #666;">
Uses: :nth-child(even), :hover, :last-child for table styling
</p>
</div>
<!-- Card Grid -->
<div>
<h2>🎴 Interactive Card Grid</h2>
<div class="card-grid">
<div class="card">
<h3>Web Development</h3>
<p>Build modern web applications with latest technologies</p>
</div>
<div class="card">
<h3>UI/UX Design</h3>
<p>Create beautiful and user-friendly interfaces</p>
</div>
<div class="card">
<h3>Mobile Apps</h3>
<p>Develop cross-platform mobile applications</p>
</div>
<div class="card">
<h3>Cloud Solutions</h3>
<p>Scalable cloud infrastructure and deployment</p>
</div>
<div class="card">
<h3>Data Analytics</h3>
<p>Turn data into actionable insights</p>
</div>
<div class="card">
<h3>AI & Machine Learning</h3>
<p>Intelligent solutions for complex problems</p>
</div>
</div>
<p style="text-align: center; color: #666;">
Uses: :hover, :active, :nth-child() for varied border colors
</p>
</div>
<!-- Button Group -->
<div class="form-container">
<h2>🔘 Button States & Interactions</h2>
<div class="button-group">
<button class="btn btn-primary">Primary Action</button>
<button class="btn btn-secondary">Secondary Action</button>
<button class="btn btn-primary" disabled>Disabled Button</button>
<button class="btn btn-secondary">Another Button</button>
</div>
<p style="color: #666;">
Uses: :hover, :active, :focus, :disabled for button states
</p>
</div>
<!-- Form Validation -->
<div class="form-container">
<h2>📝 Smart Form Validation</h2>
<form>
<div class="form-group">
<label>Email Address *</label>
<input type="email" required placeholder="Enter valid email">
</div>
<div class="form-group">
<label>Password *</label>
<input type="password" required minlength="6" placeholder="Minimum 6 characters">
</div>
<div class="form-group">
<label>Phone Number (Optional)</label>
<input type="tel" placeholder="Optional field">
</div>
<button class="btn btn-primary" type="submit">Create Account</button>
</form>
<p style="color: #666; margin-top: 1rem;">
Uses: :required, :optional, :valid, :invalid, :focus for form validation
</p>
</div>
<!-- Progress Steps -->
<div class="progress-steps">
<div class="step active">Sign Up</div>
<div class="step active">Profile</div>
<div class="step">Preferences</div>
<div class="step">Confirmation</div>
</div>
<p style="text-align: center; color: #666;">
Uses: :not(), :before, counters for progress indicators
</p>
</div>
</body>
</html>Best Practices & Common Patterns
✅ Do This
- Use
:focusfor accessibility - Combine pseudo-classes like
:hover:focus - Use
:nth-childfor complex patterns - Test with keyboard navigation
- Use
:not()for exclusion patterns - Provide fallbacks for older browsers
❌ Avoid This
- Overusing complex
:nth-childformulas - Forgetting to style
:focusstates - Using
:hoveron non-interactive elements - Ignoring touch device limitations
- Creating inaccessible color contrasts
- Overcomplicating with too many states
🎯 Pseudo-Class Specificity
Order Matters:
:link→:visited:hover→:active:focusshould be considered
Specificity Weight:
- Pseudo-classes: 0,1,0
- Same as class selectors
- Less than ID selectors
Browser Support & Compatibility
Modern Pseudo-Class Support
Ready to Master Pseudo-Classes? 🎯
Experiment with our interactive examples and discover the power of CSS pseudo-classes. Create dynamic, accessible, and engaging user interfaces with pure CSS!