Pseudo-classes let you apply styles based on an element's state or position. They are the reason you can have a button that changes color when you hover over it, or style every other row in a table differently.
:hover and :focus
These are the most common pseudo-classes. :hover applies when the mouse is
over an element. :focus applies when an element is selected, like when you
tab into an input field.
button:hover {
background-color: #3498db;
cursor: pointer;
}
input:focus {
border-color: #2ecc71;
outline: none;
box-shadow: 0 0 5px #2ecc71;
}
Always style :focus for accessibility โ keyboard users rely on it to navigate.
:first-child and :last-child
These target the first or last child inside a parent. No extra classes needed.
li:first-child {
font-weight: bold;
}
li:last-child {
border-bottom: none;
}
This is perfect for removing the bottom border from the last item in a list, or making the first item stand out.
:nth-child()
This one is incredibly versatile. You pass it a pattern, and it matches elements accordingly.
/* Every even child */
li:nth-child(even) {
background-color: #f5f5f5;
}
/* Every third child starting from the second */
li:nth-child(3n+2) {
color: red;
}
/* The second child specifically */
li:nth-child(2) {
font-size: 20px;
}
The n in an+b counts from 0, 1, 2, 3... So 3n+2
matches children 2, 5, 8, 11, and so on. It looks like math, but it is easy once you
try it a couple of times.
:not()
:not() excludes elements that match a selector. It is a negative filter.
/* Style all paragraphs except the one with class "no-style" */
p:not(.no-style) {
line-height: 1.8;
}
/* Style everything that is not a button */
button:not(.primary) {
background: #ccc;
}
:not() saves you from having to override styles later. Apply your default
styles, then exclude what does not need them.