Register to get access to 15+ free programming courses with interactive exercises

Pseudo-classes Content layout fundamentals

Pseudo-classes are a cornerstone when it comes to using selectors. First, let's find out why such selectors are called pseudo. Pseudo-classes don't select an element directly. They specify the state of the element. We can show it using links as an example.

<a href="#">Usual hyperlink</a>

What can we say about this element? This is an HTML element with standard styles that can redirect the user. There are up to three things that can happen with links!

  1. You can hover over a link
  2. You can click on the link. In this case, the moment of clicking occurs when you press the main mouse button, but before you release it
  3. The browser automatically flags a link that we've already clicked

There is another event that the link can handle, a focus event. This happens when you navigate to a link using the keyboard.

Make all the events happen and see how the interaction changes:

  1. When you hover over the link, your cursor will change
  2. When you left-click on the link, it changes color
  3. When you let go, the link changes color again, indicating that the user has already clicked it
  4. Press the Tab key. This shows you the focus state, where borders appear around the link

As developers, can we do anything about this behavior? Of course! That's the power of pseudo-classes, they allow you to set styles not just for elements themselves, but also for their states or other conditions.

Pseudo-classes have a special syntax that makes them easy to distinguish from other selectors. They're written as selector:pseudo-class. Let's look at an example.

The :hover pseudo-class is used to style the element when the mouse hovers over something. Styles specified with such a selector will only be applied when the mouse hovers over an item, and they'll be removed when the mouse is moved off. Let's try styling the link on hover.

a:hover {
  color: #2196f3;
  text-decoration: none;
}

The most incredible thing is that you can combine the selectors you've already learned. What if hovering over an element changes it to a completely different one! Remember the adjacent and sibling selectors? Nothing is stopping you from combining them and making interesting new styles.

There are also pseudo-classes for other states.

  • :active - The style when the link has been clicked, but before moving to the page specified
  • :visited - The style for a previously visited link
  • :focus - The style during a focus event

Note that all of these pseudo-classes work for things other than links. Don't be afraid to experiment :)

Tree-structural pseudo-classes

Tree-structural pseudo-classes are those that add styles to an element depending on its location within HTML. This is a powerful tool that allows you to achieve complex styles without using a large number of classes.

The main tree-structural pseudo-class is :nth-child(condition). You can see that it's a whole function that takes a condition on which an item or items will be selected. Let's figure out what values it can take and what elements will be selected.

The easiest thing to do is to specify the specific item you want. To do this, you only need to give the item's numeric position. Note that elements must be descendants of the same parent and be selected using the same selector.

<section>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
  <p>Paragraph 3</p>
</section>
section p:nth-child(2) {
  color: #2196f3;
}

In addition to direct item selection, you can pass special sequences that will be able to select not one, but several items at once.

  • :nth-child(2n) - select every second element. 2, 4, 6, 8... The number can be any number. If you put 3n, every third element will be selected, and so on. This applies to all sequences
  • :nth-child(2n + 1) - select every second element, starting from the first one. 1, 3, 5, 7, 9...
  • :nth-child(even) - select all even elements. Same as :nth-child(2n)
  • :nth-child(odd) - select all odd elements. Same as :nth-child(2n + 1)

There's another, similar pseudo-class :nth-of-type(condition). Try replacing nth-child in the example above; the result will remain the same. But why do we need another pseudo-class with the same functionality?

Take a closer look. In the case of nth-child, the counting of <span> elements started with an even element. But 1 is an odd element. You'd be right in terms of mathematics, but not in terms of the logic of nth-child. It selected all <span> elements and took into account their position relative to other elements in the block. For this reason, elements 4 and 5 are odd, even though they're in a row. The logic is as follows:

  1. The first element inside the block is h2. It stands at an odd position relative to all elements inside the parent
  2. Elements 1 and 3 are even since the parent contains the second and fourth elements, respectively
  3. Elements 2 and 4 are odd because the parent contains the third and fifth elements
  4. The header "Second part of digits" is an even element inside the parent
  5. Element 5 is now odd, too because it comes after the even header

The nth-of-type pseudo-class recognizes not only the position of an element but also its type. In our case, there are no headers for this selector. Only <span> elements are selected, regardless of what other elements are inside the parent.

There isn't always a need to use such complex pseudo-classes. There are special pseudo-classes for some standard situations:

  • :first-child - selects the first element inside the parent
  • :last-child - selects the last element inside the parent
  • :first-of-type - selects the first element inside the parent, taking the element type into account
  • :last-of-type - selects the last element inside the parent, taking the element type into account
  • :only-child - selects an element if it's the only one inside the parent

Do it yourself

Take any of the previous lessons and, using pseudoclasses, add new styles. Try using different expressions within tree-structural pseudo-classes.


Аватары экспертов Хекслета

Are there any more questions? Ask them in the Discussion section.

The Hexlet support team or other students will answer you.

For full access to the course you need a professional subscription.

A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.

Get access
130
courses
1000
exercises
2000+
hours of theory
3200
tests

Sign up

Programming courses for beginners and experienced developers. Start training for free

  • 130 courses, 2000+ hours of theory
  • 1000 practical tasks in a browser
  • 360 000 students
By sending the form, you agree to Personal Policy and Service Conditions

Our graduates work in companies:

<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.bookmate">Bookmate</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.healthsamurai">Healthsamurai</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.dualboot">Dualboot</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.abbyy">Abbyy</span>

Use Hexlet to the fullest extent!

  • Ask questions about the lesson
  • Test your knowledge in quizzes
  • Practice in your browser
  • Track your progress

Sign up or sign in

By sending the form, you agree to Personal Policy and Service Conditions

Toto Image

Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.