Pseudo-classes and pseudo-elements let CSS target things that are not always represented by a normal class. Pseudo-classes target state or position, while pseudo-elements target a part of an element or create virtual decorative content.
They are powerful because they keep HTML cleaner. You can style hover, focus, checked inputs, first list items, placeholder text, markers, and decorative icons without adding extra wrapper elements.
Add one worked example that compares the normal path with the boundary case for CSS Pseudo Classes Elements hover, before.
CSS Pseudo Classes Elements hover before should be studied as a practical CSS lesson, not as a label. Start by naming the input, the rule that changes the input, and the result a learner should be able to predict after reading the page.
In the css > pseudo-classes-and-elements page, the notes should connect the definition with a working scenario, a mistake that beginners actually make, and the exact check that proves the fix. That makes the topic useful for coding, debugging, and interview revision.
Pseudo-classes select elements based on their state or structural position. They use a single colon : prefix.
State pseudo-classes such as :hover, :focus-visible, and :disabled respond to interaction. Structural pseudo-classes such as :first-child and :nth-child() respond to where an element sits in the document.
/* === STATE PSEUDO-CLASSES === */
a:link { color: #3498db; }
a:visited { color: #9b59b6; }
a:hover { color: #2980b9; }
a:active { color: #e74c3c; }
a:focus { outline: 2px solid #3498db; }
input:focus { border-color: #3498db; box-shadow: 0 0 0 3px rgba(52,152,219,0.2); }
input:disabled { opacity: 0.5; cursor: not-allowed; }
input:checked { accent-color: #3498db; }
input:valid { border-color: #2ecc71; }
input:invalid { border-color: #e74c3c; }
input:required { border-left: 3px solid #e74c3c; }
input:placeholder-shown { background: #fffde7; }
/* === STRUCTURAL PSEUDO-CLASSES === */
li:first-child { font-weight: bold; }
li:last-child { border-bottom: none; }
li:nth-child(2) { background: #f0f0f0; }
li:nth-child(odd) { background: #fff; }
li:nth-child(even) { background: #f9f9f9; }
li:nth-child(3n) { color: red; } /* every 3rd */
li:nth-child(3n+1) { color: blue; } /* 1st, 4th, 7th... */
p:first-of-type { font-size: 1.1em; }
p:last-of-type { margin-bottom: 0; }
p:only-child { text-align: center; }
p:empty { display: none; }
/* === LOGICAL PSEUDO-CLASSES === */
/* :not() - exclude elements */
li:not(:last-child) { border-bottom: 1px solid #eee; }
input:not([type="submit"]):not([type="reset"]) { border: 1px solid #ccc; }
/* :is() - match any in list (takes highest specificity) */
:is(h1, h2, h3, h4) { font-family: 'Georgia', serif; }
/* :where() - same as :is() but ZERO specificity */
:where(h1, h2, h3) { margin-top: 0; }
/* :has() - parent selector (CSS4) */
.card:has(img) { padding: 0; } /* card with image: no padding */
form:has(input:invalid) .submit-btn { opacity: 0.5; }
/* :focus-within - parent when child is focused */
.form-group:focus-within label { color: #3498db; }
Pseudo-elements style a specific part of an element or insert virtual content. They use a double colon :: prefix.
Generated content from ::before and ::after should normally be decorative. If the content is essential for understanding the page, put it in the HTML so assistive technology and copy/paste behavior remain reliable.
/* ::before - insert content before element */
.required::before {
content: "* ";
color: red;
}
/* ::after - insert content after element */
.price::after {
content: " USD";
font-size: 0.8em;
color: gray;
}
/* Decorative elements with ::before/::after */
.section-title::after {
content: '';
display: block;
width: 60px;
height: 3px;
background: #3498db;
margin-top: 8px;
}
/* ::first-letter - drop cap */
article p:first-of-type::first-letter {
font-size: 3em;
font-weight: bold;
float: left;
line-height: 0.8;
margin: 0 8px 0 0;
color: #3498db;
}
/* ::first-line */
p::first-line {
font-weight: bold;
color: #2c3e50;
}
/* ::selection - selected text */
::selection {
background-color: #3498db;
color: white;
}
/* ::placeholder */
input::placeholder {
color: #aaa;
font-style: italic;
}
/* ::marker - list item marker */
li::marker {
color: #3498db;
font-size: 1.2em;
}
/* ::backdrop - behind fullscreen elements */
dialog::backdrop {
background: rgba(0, 0, 0, 0.5);
}
CSS Pseudo Classes Elements hover before matters in CSS because it changes how a program is written, tested, or debugged. The page should explain the normal flow first: what the developer writes, what the runtime or platform does, and what result should appear.
When teaching CSS Pseudo Classes Elements hover before, avoid stopping at syntax. Show the surrounding decision: why this feature is chosen, what problem it removes, and what would become harder if the feature were not used.
.lesson-box {
display: block;
max-width: 42rem;
padding: 1rem;
}
.lesson-box:empty::before {
content: "CSS Pseudo Classes Elements hover before: add visible content";
}
Putting important labels only in ::before content.
Keep important text in the HTML and use pseudo-elements for decoration.
Using :nth-child() while expecting it to count only a specific tag type.
Use :nth-of-type() when the type matters.
Using :is() and being surprised by specificity.
Use :where() when you need the same grouping with zero specificity.
Memorizing CSS Pseudo Classes Elements hover before without the situation where it is useful.
Connect CSS Pseudo Classes Elements hover before to a concrete CSS task.
A pseudo-class selects an element state or position. A pseudo-element styles part of an element or generated content.
:focus-visible is usually better for custom keyboard focus styles because it avoids showing focus rings for many mouse interactions.
They need the content property, even if it is an empty string.
Modern browsers support it well, but check your project browser requirements before relying on it heavily.
Explore 500+ free tutorials across 20+ languages and frameworks.