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
:focus
for accessibility - Combine pseudo-classes like
:hover:focus
- Use
:nth-child
for complex patterns - Test with keyboard navigation
- Use
:not()
for exclusion patterns - Provide fallbacks for older browsers
❌ Avoid This
- Overusing complex
:nth-child
formulas - Forgetting to style
:focus
states - Using
:hover
on 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
:focus
should 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!