Page Content

Tutorials

What are the pseudo classes in CSS?

Understanding Pseudo-classes

Pseudo classes in CSS is used to target items in a specific state. In this state, user interaction, such as hovering over an element or focusing on it, is based on the element’s position within the document structure. Pseudo-classes always begin with a single colon (:). They extend existing selectors to apply styles based on dynamic states or the element’s role in the document tree. Pseudo-classes have the same specificity as a class selector (0,1,0).

It’s important to differentiate pseudo-classes from pseudo-elements. A pseudo-element is like an element but not really one, allowing you to style specific parts of an element (e.g., the first letter or line). Pseudo-elements are created using a double colon (::) in CSS3 (e.g., ::before, ::after), although older pseudo-elements like :first-letter and :first-line can still be written with a single colon for backward compatibility. At the risk of oversimplification, a pseudo-selector (pseudo-class) selects a subpart of the original thing it is selecting.

Types of pseudo classes in CSS

The basic syntax for using a pseudo-class is selector:pseudo-class { property: value; }.

:hover:

This pseudo-class applies styles when the user’s pointing device (like a mouse cursor) is hovering over an element, but the element is not being activated. It’s commonly used to provide visual feedback on interactive elements like links and buttons. Note that :hover events might not work on touch screen devices.

a {
  color: blue;
}
a:hover {
  color: red; /* Link text turns red on hover */
  text-decoration: underline;
}
<a href="#">Hover over me</a>

:focus:

This pseudo-class applies styles to an element that has received focus. Focus can be given by the user’s keyboard navigation (e.g., using the Tab key), mouse events, or other forms of input. It’s important for accessibility, allowing users navigating with a keyboard to see which element is currently selected.

input[type="text"] {
  border: 1px solid #ccc;
  padding: 5px;
}
input[type="text"]:focus {
  border-color: blue; /* Input border turns blue when focused */
  box-shadow: 0 0 5px blue;
}
<input type="text" placeholder="Enter text">

:active:

 This pseudo-class applies styles to an element that is being activated by the user (e.g., the moment a mouse button is pressed down on a link or button). It represents the brief period when an element is actively being interacted with.

button {
  background-color: #f0f0f0;
  border: 1px solid #ccc;
  padding: 10px 20px;
}
button:active {
  background-color: #ccc; /* Button background darkens when active */
  box-shadow: inset 0 0 5px black;
}
<button>Click Me</button>

:nth-child(n):

This is a structural pseudo-class that selects an element that is the nth child of its parent element. The n can be a number, a keyword (odd, even), or a formula (e.g., 2n, 3n+1, -n+3). It’s a powerful tool for styling elements based on their position within their parent.

ul li {
  list-style-type: none;
  padding: 5px;
}
ul li:nth-child(odd) {
  background-color: #f0f0f0; /* Styles every odd list item */
}
ul li:nth-child(even) {
  background-color: #e0e0e0; /* Styles every even list item */
}
ol li:nth-child(3n) {
  font-weight: bold; /* Styles every third ordered list item */
}
<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li>Item 5</li>
</ul>
<ol>
  <li>Step 1</li>
  <li>Step 2</li>
  <li>Step 3</li>
  <li>Step 4</li>
  <li>Step 5</li>
  <li>Step 6</li>
</ol>

:last-child:

This is a structural pseudo-class that selects the last child element within its parent. It’s useful for applying specific styles to the final item in a list or a container. It’s the same as :nth-last-child(1).

ul li {
  padding: 5px;
  border-bottom: 1px solid #ccc;
}
ul li:last-child {
  border-bottom: none; /* Removes the bottom border from the last list item */
}
<ul>
  <li>Item A</li>
  <li>Item B</li>
  <li>Item C</li>
</ul>

:not() Pseudo-class

The :not() pseudo-class is a nullification pseudo-class selector. It is used to select all elements that do not match the selector specified within the parentheses. The selector inside the parentheses must be a simple selector; it can refer to the element itself but cannot be used to exclude families, and it should not contain another nullification selector. However, you can chain multiple :not() selectors together.

The basic syntax is selector:not(exception). This will select all elements that match the selector but do not match the exception selector inside the parentheses.

code example:

<div class="a-div"></div>
<div class="a-div"></div>
<div class="a-div"></div>
<div class="a-div not-me"></div>
<div class="a-div"></div>
div {
  display: inline-block;
  height: 2rem;
  width: 2rem;
  background-color: blue;
}
.a-div:not(.not-me) {
  background-color: orange; /* All .a-div elements that do not have the .not-me class will be orange */
  border-radius: 50%;
}

In this example, all div elements with the class .a-div will have an orange background and rounded corners, except for the div that also has the class .not-me. This proves how :not(.not-me) excludes elements with the class .not-me from the selection.

Another example shows how to target all <input> elements that are not disabled and don’t have the class .example:

<form>
  Phone: <input type="tel" class="example">
  E-mail: <input type="email" disabled="disabled">
  Password: <input type="password">
</form>
input:not([disabled]):not(.example){
  background-color: #ccc; /* Targets input elements that are not disabled and do not have the class .example */
}

This CSS rule uses :not([disabled]) to exclude disabled input elements and :not(.example) to exclude input elements with the class .example, applying the background color to the remaining input fields.

The :not() pseudo-class is considered a CSS3 selector. Some older browsers, like Internet Explorer before version 9, limited support for structural pseudo-classes like :not().

:empty() Pseudo-class

The :empty() pseudo-class selects an element that has no children at all. This includes no child elements and no text nodes. Therefore, an element containing even whitespace is not considered empty by this selector.

Consider the following HTML:

<div class="thing"></div>
And the CSS:
.thing {
  padding: 1rem;
  background-color: violet;
}
.thing:empty {
  display: none; /* Hides the div if it has no content */
}

In this case, the div with the class .thing is initially empty. The first CSS rule gives it padding and a background color. The second rule, using :empty, will set the display property to none for any .thing element that has no content, effectively hiding it. This is useful for situations where content is dynamically inserted into an element, and you want to hide the element if no content is present.

Another example shows how :empty would only target the first td element in this markup:

<table>
  <tr>
    <td></td>
    <td>Lorem ipsum</td>
    <td><span></span></td>
  </tr>
</table>
td:empty {
  background-color: red; /* Only the first td will have a red background */
}

The first <td> has no children, so it’s considered empty. The second <td> contains a text node, and the third <td> contains a <span> element, so they are not considered empty.

The :empty selector is also considered a CSS3 selector, and similar to :not(), older versions of Internet Explorer had limited support for it. CSS Selectors Level 4 might introduce :blank, which would also match elements containing only whitespace.

CSS3 Structural Pseudo-classes

CSS3 expanded the capabilities of structural pseudo-classes. These selectors allow you to target elements based on their position in the Document Object Model (DOM) tree, without needing to add extra classes or IDs in your HTML. This promotes a cleaner separation between content and presentation.

Besides :nth-child() and :last-child(), other important CSS3 structural pseudo-classes include:

  • :first-child: Selects an element that is the first child of its parent. For example, ul li:first-child would target the first list item in any unordered list. It’s similar to :nth-child(1).
  • :nth-last-child(n): Selects an element that is the nth child from the end of its parent. For example, ul li:nth-last-child(2) would select the second-to-last list item.
  • :first-of-type: Selects the first element of a specific type among its siblings. For instance, in a div containing several p and span elements, p:first-of-type would select the very first <p> element.
  • :last-of-type: Selects the last element of a specific type among its siblings. Using the previous example, p:last-of-type would select the last <p> element within the div.
  • :nth-of-type(n): Selects the nth element of a specific type among its siblings. For example, p:nth-of-type(2) would select the second <p> element within its parent.
  • :nth-last-of-type(n): Selects the nth element of a specific type among its siblings, counting backwards from the end.
  • :only-child: Selects an element that is the only child of its parent. This is equivalent to :first-child:last-child or :nth-child(1):nth-last-child(1) but with lower specificity.
  • :only-of-type: Selects an element that is the only child of its parent that is of that specific type.
  • :empty: Selects an element that has no children at all (no child elements or text nodes).
  • :not(selector): Selects all elements that do not match the specified selector. For example, li:not(.internal) would select all list items that do not have the class “internal”.

structural pseudo-classes offer to style content based on its position and type within the HTML structure, enhancing the power and flexibility of CSS. Browser support for CSS3 selectors, including structural pseudo-classes, has generally been good, although older versions of Internet Explorer (like IE8 and earlier) had limited support.

CSS3 Topics

Index