CSS Tutorial menu

CSS Pseudo-classes

A pseudo-class selects an element when it is in a special state or a special position, without adding any class in the HTML.

Syntax

Write a colon : and the name straight after a selector, with no space.

Example

css
selector:pseudo-class {
  property: value;
}

You already met :hover in the Selectors chapter. There are many more.

User Action Pseudo-classes

These react to what the user is doing with the mouse, finger or keyboard.

Pseudo-classMatches when
:hoverThe mouse pointer is over the element
:activeThe element is being pressed
:focusThe element has keyboard focus (for example, an input you clicked)
:focus-visibleIt has focus and the browser thinks a focus ring should show
:focus-withinThe element or anything inside it has focus

Example

html
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
.btn {
  background-color: #264de4;
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 6px;
}
.btn:hover  { background-color: #1d3bb3; }
.btn:active { transform: scale(0.95); }

form {
  padding: 12px;
  border: 2px solid #dddddd;
  margin-top: 16px;
}
form:focus-within { border-color: #264de4; }
input:focus { outline: 3px solid orange; }
</style>
</head>
<body>

<button class="btn">Press me</button>

<form>
  <label>Your name: <input type="text"></label>
</form>

</body>
</html>
Try it Yourself »

Click into the input. The input gets an orange outline, and the whole form gets a blue border because of :focus-within.

Form State Pseudo-classes

These help you style form fields based on their state.

Pseudo-classMatches
:checkedA ticked checkbox or selected radio button
:disabled / :enabledFields that are turned off or on
:required / :optionalFields with or without the required attribute
:valid / :invalidFields whose value passes or fails the rules
:user-invalidInvalid, but only after the user has changed the field
:placeholder-shownAn input that is still showing its placeholder

Example

html
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
input {
  padding: 8px;
  border: 2px solid #cccccc;
  border-radius: 4px;
  display: block;
  margin-bottom: 10px;
}
input:user-invalid { border-color: crimson; }
input:valid { border-color: seagreen; }
input:disabled { background-color: #eeeeee; }
input[type="checkbox"]:checked + span {
  font-weight: bold;
  color: seagreen;
}
</style>
</head>
<body>

<input type="email" placeholder="Email address" required>
<input type="text" value="Admission No: 2026-114" disabled>
<label><input type="checkbox"> <span>I agree to the rules</span></label>

</body>
</html>
Try it Yourself »

Type a wrong email and click outside the box to see the red border. :user-invalid waits until the user has touched the field, so the form does not shout at people before they start typing.

Position Pseudo-classes

These select an element by its place among its brothers and sisters (siblings).

Pseudo-classSelects
:first-childThe first child of its parent
:last-childThe last child
:only-childA child with no siblings
:nth-child(3)The 3rd child
:nth-child(odd) / :nth-child(even)Every odd or even child
:nth-child(3n)Every 3rd child: 3, 6, 9...
:nth-last-child(2)The 2nd child counting from the end
:first-of-typeThe first element of its tag type, like the first <p>

Example

html
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
li { padding: 8px; list-style: none; }
li:nth-child(even) { background-color: #eef2ff; }
li:first-child { font-weight: bold; color: #264de4; }
li:last-child { border-bottom: 2px solid #264de4; }
</style>
</head>
<body>

<ul>
  <li>Class 10 Results</li>
  <li>Ali - 1012 marks</li>
  <li>Sana - 998 marks</li>
  <li>Hamza - 975 marks</li>
  <li>Fatima - 960 marks</li>
</ul>

</body>
</html>
Try it Yourself »

The :not() Pseudo-class

:not() selects everything that does not match the selector inside it. A popular use is adding a line between items, but not after the last one:

Example

css
.menu li:not(:last-child) {
  border-bottom: 1px solid #dddddd;
}

Other Useful Ones

  • :root selects the <html> element; it is where CSS variables usually live
  • :empty selects elements with nothing inside them
  • :target selects the element whose id matches the #part in the URL
  • :visited styles links the user has already opened

You can combine pseudo-classes: a:not(.button):hover means "a link without the class button, while it is being hovered".

Exercise

Exercise

Which selector gives every second row of a table a background colour?

Learn CSS with a teacher

Join the Web Development course at Workownix, online or in Orangi Town, Karachi, and get a certificate.

See the course Ask on WhatsApp