Get Comfortable With CSS Selectors

Get Comfortable With CSS Selectors

·

22 min read

HTML and CSS to a front-end developer are like a knife and a fork to a chef. The more we get used to using HTML and CSS skills together, the better front-end developer we will become.

And the best way to learn how to use these skills together is to understand the different CSS Selectors.

This blog will look at the different types of CSS selectors and how we can use them to build efficient CSS code.

Prerequisite

To get the most out of this article, we need the following:

  • Basic understanding of HTML.
  • Visual studio code or any IDE of our choice to code along.

CSS Selectors

CSS selectors is the opening part of a CSS ruleset. It determines how we apply styles to HTML elements on a web page.

There are many different CSS selectors, each with its unique syntax. The syntax tells the browser which HTML elements to apply CSS property values to on the web page.

The element or elements targeted by a CSS selector are the subject of the selector.

We can select a subject based on its element type, class, ID name, or pseudo-state.

CSS selectors are case-sensitive. They must match element names and attribute values precisely.

A .coding class selector is not the same as .CODING

It is advisable to use small letters to avoid making mistakes.

The syntax for CSS Selector is:

selector {
   CSS-property: value;
}

Types of CSS Selectors

  • Basic CSS selectors.
  • Advanced CSS selectors.

BASIC CSS SELECTORS

Basic CSS selectors are the most common type of CSS selectors. They style specific elements on a website. In basic selectors, we have selectors such as:

  • CSS class Selectors
  • CSS ID Selectors
  • Element Type Selectors
  • CSS Universal Selectors

The CSS Class Selector

The CSS class selector identifies an element based on its class attribute. We use CSS class selectors to style many and any HTML elements.

To select elements with a specific class, write a period (.) character, followed by the class name.

The syntax for CSS Class Selector is:

.class-name {
   property: value;
}

Examples of CSS Class selector:

In the example below ⬇️ the <p> element has a class="text"

<p class="text">When will manchester united win a trophy again?</p>

To select the <p> element using the CSS class selector, we:

.text {
  text-align: center;
  color: orange;
  font-size: 20px;
}

All Html element with class="text" will align to the center, have orange text color and a font-size of 20px.

Remember we can use the CSS class selector to style many HTML elements, right?. Let us see how it works 🙂

We want both the <p> and the <button> element to have the same exact CSS style, so we give both the same class="code".

<h1>Football<h1>
<p class="code">When will manchester united win a trophy again?</p>
<h2>Rejoice</h2>
<button class="code">Submit</button>

I hope we noticed in the above example ⬆ that the elements <p> and <button> have the same class="code"? 🤔

.code {
    text-align: center;
    color: green;
    font-size: 18px;
}

The <p> and <button> in the example above ⬆ will have the same text color, font size, and align to the web page's center.

We can also specify that a class should affect only a specific HTML element

In the example below ⬇️ both the <p> and the <button> element have the same class="code".

<h1>Football<h1>
<p class="code">When will manchester united win a trophy again?</p>
<h2>Rejoice</h2>
<button class="code">Submit</button>

We want to style only the <p> element. How do we do that?

Note: Both the <p> and <button> have the same class name.

p.code {
    text-transform: capitalize;
    color: orange;
    font-size: 20px;
}

In the example above ⬆ only paragraph <p> elements with class="code" will be orange, and have a font-size of 20px. It won't affect the <button> element.

The CSS ID Selector

The CSS ID selector identifies an element based on its ID attribute. ID selectors are unique, and we should only use them once per page to select one unique HTML element.

To select an element with a specific ID, write a hash (#) character, followed by the element's ID.

The syntax for CSS ID Selector is:

#id-name {
   property: value;
}

Example of CSS Id Selector

In the example below ⬇ the <p> element has a id="coding"

<p id="coding">football is no longer fun</p>

To select the <p> element using the CSS ID selector, we:

#coding {
    text-align: center;
    color: red;
}

In the example above ⬆, the CSS rule will apply to the HTML element with id="coding".

Remember that the Id Class selector is a unique identifier. In an HTML document, we can't have more than one element with the same ID. We can only select one element.

Use ID selectors rarely and only on elements that need always to appear the same.

What Is the Difference Between CSS Class selectors and ID selectors?

We can repeat the same CSS class selector value across many Html elements, but we can only use an ID once.

Element Type Selectors

Element Type Selectors are the most common basic CSS selectors. They select HTML elements based on the element name.

The syntax for Element Type Selector is:

element {
   property: value;
}

Example of Element Type Selectors:

p {
   text-align: center;
   font-size: 20px;
   color: red;
}

In the above ⬆ example, all paragraph <p> elements will align to the center, have a font size of 20px, and text color red.

The CSS Universal Selector

We use the universal selector (*) to select all HTML elements on the same web page.

Every HTML element, from the <header> to the <footer>, follows the universal selector's style.

The asterisk (*) character represents Universal selectors.

The syntax for Universal Selector is:

* {
   CSS-Property: value;
}

Example of CSS Universal Selector

* {
   text-align: center;
   text-transform: Uppercase;
}

Every element on the web page will align to the center of the page and have uppercase letters.

The CSS Grouping Selector

CSS grouping selectors select all the HTML elements with the same style definitions.

CSS grouping selectors save time and help us write more specific codes.

We may want to apply the same styles to several Html components at times. For example, all your <h1>, <h2>, and <h3> elements should have a red background, a font-weight of 700 and a font-size of 28px.

One approach is to style each HTML element in our CSS stylesheet, <h1>, <h2> and <h3> as different selectors. There's nothing wrong with this, but we'll get a CSS stylesheet full of repeated declarations if we do it.

A better solution is to use one CSS ruleset with many declarations separated by a comma (,).

Let us take a close look at the CSS codes below ⬇️. We'll see that the <h1>, <h2>, and <h3> elements all have the same CSS style.

h1 {
  background-color: red;
   color: white;
   font-weight: 700;
   font-size: 28px;
   text-align: center;  
}

h2 {
   background-color: red;
   color: white;
   font-weight: 700;
   font-size: 28px;
   text-align: center;
}

h3 {
   background-color: red;
   color: white;
   font-weight: 700;
   font-size: 28px;
   text-align: center;
}

In the example above ⬆️, we gave <h1>, <h2>, <h3> the same CSS style. Will it work that way? Yes, it will work, but it will be better to group the selectors to avoid repetition and make our codes easier to read.

To group selectors, we separate each selector with a comma(,).

Let's group the above CSS codes with a Comma (,) 😄

h1, h2, h3 {
   background-color: red;
   color: white;
   font-weight: 700;
   font-size: 28px;
   text-align: center;
}
  • It's possible for us to use comma(,) to group them together because <h1>, <h2>, <h3> have the same exact CSS styles.

  • The selectors don't have to match before we group them, as long as we give them the same CSS styling. For example, we can group <h1> with <button> with <p> as long as we give them the same styles.

  • We can also group a CSS Class selector with ID selectors if we want them to have the same CSS styling.

<h1 id="tech">Coding is life</h1>
<p class="future">Coding is fun</p>

To group the above Example:

#tech,
.future {
   font-size: 20px;
   color: red;
   text-transform: capitalize;
}

Note: We use the Comma(,) cause we want them to have the same CSS style.

What do we do when <h1>, <h2>, and <h3> have a few comparable CSS stylings but different font sizes and colors?

/*group the selectors cause they have the same styles*/
h1,
h2,
h3 {
   text-align: center;
   text-transform: uppercase;
}


/*apply individual styles to all 3 selectors*/
h1 {
   font-size: 30px;
   color: red;
}

h2 {
   font-size: 25px;
   color: orangered;
}


h3 {
   font-size: 20px;
   color: green;
}
  • h1, h2, and h3 all have text-align: center; text-transform: uppercase; so we grouped them.
  • font size and color are different from h1, h2, and h3, so we applied the font size and color to all three selectors.

I hope we understand basic CSS selectors? 😄.

Let us move on to Advanced CSS Selectors.

ADVANCED CSS SELECTORS

Advanced CSS selectors enable us to do more than what Basic CSS allows us to do.

In advanced CSS selectors, we have the following:

  • Combination Selectors.
  • Pseudo-class-selectors.
  • CSS Attribute Selectors.

COMBINATION SELECTORS

Combination Selectors select elements based on a specific relationship between them.

There are four types of combination selectors:

  • Descendant selectors.
  • Child selectors.
  • Adjacent sibling selectors.
  • General sibling selectors.

CSS selectors rely on the HTML Family Tree. We also call the HTML family tree the HTML document tree. It's vital to grasp the relationships between HTML elements before going further.

The family tree consists of descendants, parents, children, and sibling elements.

  • A parent element contains other elements.

  • The child element is an element immediately contained by another element.

  • A sibling is an element that shares the same parent with another element.

<div>
   <img src="" alt="">

   <article>
       <h1>coding is life</h1>
       <p>Code everyday</p>
    </article>

       <aside>
             <h2>Make out time to take care of yourself as a developer</h2>
              <p>It's okay to read something else other than a coding book</p>
       </aside>

</div>

In the example above:

  • The <div> is the parent.

  • The <img> in line 2, <article> in line 3 and the <aside> element in line 7 are the children of the <div>.

  • The <article> element in line 3 is the parent of the <h1> in line 4 and the <p> element in line 5.

  • The <h1> in line 4 and the <p> element in line 5 are siblings with the same parent <article> element.

  • The <h1> in line 4 and the <p> element in line 5 are the children of the <article> and the grandchildren of the <div> element

  • The <aside> element in line 7 is the parent of the <h2> in line 8 and the <p> element in line 9.

Let us look at each of these selectors one by one, using examples to help us grasp how they function 😄.

Descendant Combinator Selectors

Descendant Combinator selectors match all elements that are descendants of a specified element.

Descendant Combinator selectors select the children, grand-children, e.tc, when used.

To select Descendants, use multiple selectors separated by spaces.

The syntax for Descendant Combinator Selector is:

selector1  selector2 {
   property: value;
}

Example 0f Descendant Combinator selector:

<h2>Coding is Fun</h2>

   <article>

       <h2>Cess - The Frontend Web developer</h2>
       <p>I will be working as a full-time frontend web developer by this time next year</p>
<div>
     <h2>Coding is life</h2>
     <p>I prefer using CSS flexbox to Grid</p>
</div>

</article>

In the above example:

  • <h2> element in line 1 is outside the <article> element

  • <h2> in line 3, <p> in line 4 and <div> elements in line 5 are the children of the <article> element

  • <h2> in line 6 and <p> element in line 7 are the children of the <div> element in line 5, which makes them the grandchildren of the <article> element

Remember Descendant selector selects both the children and the grand-children when used.

let us style all the <h2> inside the article element using the Descendant selector:

article h2 {
    text-align: center;
    color: orange;
    font-size: 20px;
}

The above ⬆️ example selects all <h2>' elements within the <article>' element because they are within the <h2>' element.

Child Combinator Selectors

Child selectors match an element that is an immediate child of another element.

The Child Combinator Selectors select only the child elements.

The child combinator selector does not select the grandchildren elements like the Descendant selector.

We use the greater-than sign (>) character to represent a child selector.

Place the greater than sign (>) between the parent and child element.

The syntax for Child Combinator Selector is:

Parent-selector > Child-selector {
    property: value;
}

Example 0f Child Combinator selector:

 <h2>Coding is Fun</h2>

  <article>

     <h2>Cess - The Frontend Web developer</h2>
      <p>I will be working as a full-time frontend web developer by this time next year</p>

      <div>
       <h2>Coding is life</h2>
       <p>I prefer using CSS flexbox to Grid</p>
        </div>
  </article>

Styling the above ⬆️ Html code:

article > h2 {
    text-align: center;
    color: orange;
    font-size: 20px;
}
  • The above ⬆️ example will target only the <h2> element in line 3 cause it falls within the <article> element.

  • It will ignore any <h2> outside of the <article> or contained inside another element.

What is the difference between a Descendant Combinator Selector and Child Combinator Selector?

The child combinator selector ( > ) targets an element that is a child of its parent. It does not target descendants beyond the children.

The descendant combinator selects all the children or grandchildren of a given element.

Adjacent sibling selectors

The Adjacent sibling selects an element directly after another specific element.

Sibling elements must have the same parents. They must be immediately following each other.

The plus (+) character represents adjacent sibling selectors.

The syntax for Adjacent sibling selector is:

first-sibling-selector + second-sibling-selector {
    property: value;
}

The way we read this combinator is from right to left.

  • The first sibling element comes first.

  • The second sibling element comes second and is the targeted element. The targeted element is the element you intend to style.

Example 0f Adjacent sibling selector:

  <h2>Coding is Fun</h2>

 <article>

       <h2>Cess - The Frontend Web developer</h2>
       <p>I will be working as a full-time frontend web developer by this time next year</p>

       <div>
          <h2>Coding is life</h2>
       </div>
 </article>

Styling the above ⬆️ Html code:

h2 + P {
     text-align: center;
     color: orange;
     font-size: 20px;
}

The above ⬆️ example will target only the <p> element in line 4. It is precisely after the <h2> element, sharing the same parent element.

Remember, the Adjacent sibling selects the second sibling when it appears right after the first sibling element, and they share the same parent.

General sibling selectors

General sibling selectors select the elements that follow and share the same parent.

It is not necessary that the second element immediately follows the first element.

The tilde (~) character represents general sibling selectors.

The syntax for the General sibling selector is:

first-sibling-selector ~ second-sibling-selector {
   property: value;
}
  • The first sibling element comes first.

  • The second sibling element comes second and is the targeted element. The targeted element is the element you intend to style.

Example 0f General sibling selector:

 <h2>Coding is Fun</h2>

  <article>

       <h2>Cess - The Frontend Web developer</h2>
        <img src="...." alt="...">
        <p>I will be working as a full-time frontend web developer by this time next year</p>

         <div>
            <h2>Coding is life</h2>
         </div>
  </article>

Styling the above ⬆️ Html code:

h2 ~ p {
     text-align: center;
     color: orange;
     font-size: 20px;
}

The above ⬆️ example will target only the <p> element in line 5. It is precisely after the <h2> element in line 3, and they share the same parent element.

General sibling selector will operate when both sibling elements have the same parent.

As long as the siblings have the same parent, it doesn't matter if they are born immediately after each other.

CSS ATTRIBUTE SELECTORS

Attribute selectors select all elements that have a given attribute or attribute value.

An attribute is a piece of the markup language used to change how an HTML element behaves or displays.

You include attributes in an HTML element's opening tag.

Example

<a href="https://www.twitter.com/cessss_" target="_blank">Connect with me on twitter</a>

In the example above target="_blank" is an attribute of the anchor tag`

The syntax for Attribute Selector is:

selector[attribute] {
    property: value;
}

There are seven types of Attribute selectors:

  • Present Attribute Selector
  • Equals Attribute Selector
  • Begins With Attribute Selector (^)
  • Ends With Attribute Selector ($)
  • Contains Attribute Selector (*)
  • Attribute Spaced Attribute Selector (~)
  • Hyphen Attribute Selector (|)

Present Attribute Selector

Present attribute selector select elements with a specified attribute.

The syntax for Present Attribute Selector is:

selector[attribute] {
    property: value;
}

Example 0f Present attribute selector:

<a href="#" target="_blank">Code everyday</a>

Styling the above ⬆️ Html code:

a[target] {
    color: orange;
    font-size: 20px;
}

The CSS styles above ⬆️ will work on any <a> element with a "target" attribute.

The styles will not apply to all other anchors <a> elements that don't have a target attribute.

Equals Attribute Selector

Equals attribute selectors select elements with a specified attribute and value.

The equals (=) character represents Equals attribute selectors.

The syntax for Equals Attribute Selector is:

selector[attribute="value"] {
   property: value;
}

Example 0f Equals attribute selector:

<a href="www.codecademy.com" target="_blank">Code everyday</a>

Styling the above ⬆️ Html code:

a[href="www.codecademy.com"] {
    color: orange;
    font-size: 20px;
}

The example above ⬆️ will find any <a>' element with a 'href' attribute set to "www.codecademy.com" and apply the CSS styles to it.

Begins With Attribute Selector

Begins with selector select elements whose attribute value begins with a specific value.

We don't have to write down the whole word of the value we specify when using Begins with selector.

The circumflex accent (^) character represents Begins with selector.

The syntax for Begins with selector is:

selector[attribute^="value"] {
   property: value;
}

Example 0f Begins with attribute selector:

<a href="https://www.codecademy.com" target="_blank">Code everyday</a>

Styling the above ⬆️ Html code:

a[href^="https://"] {
    color: orange;
    font-size: 20px;
}

The example above ⬆️ will find any <a> element with a href attribute that starts with "https://" and apply the CSS styles.

Ends With Attribute Selector

Ends with selector select elements whose attribute value ends with a specific value.

Ends with selector is the opposite of the begins with selector.

We don't have to write down the whole word of the value we specify when using Ends with selector.

The dollar sign ($) character represents Ends with selector.

The syntax for Ends with selector is:

selector[attribute$="value"] {
   property: value;
}

Example 0f Ends with attribute selector:

<p>Visit <a href="https://www.codecademy.com/docs/menu.pdf">Code documentation</a></p>

Styling the above ⬆️ Html code:

a[href$=".pdf"] {
    color: orange;
    font-size: 20px;
}

The example above ⬆️ will find any <a>' element with a ''href'' attribute that ends with ".pdf" and apply the CSS styles.

Attribute spaced Selector

Attribute spaced Selector is also called white space attribute selector.

It matches any element whose attribute value is a list of space-separated values. One of the values we use will be equal to any value in the space-separated values.

By space-seperated values, we mean attribute values like class="fun coding"

The tilde (~) character represents the attribute spaced selector.

The syntax for Attribute spaced selector is:

selector[attribute~="value"] {
   property: value;
}

Example 0f Attribute spaced selector:

<a href="#" rel="tag nofollow">Code documentation</a>

Styling the above ⬆️ Html code:

a[rel~="tag"] {
     color: orange;
     font-size: 20px;
}

The example above ⬆️ will find any <a>' element with a ''rel'' attribute with a value of "tag" and apply the CSS styles to it.

Contains Attribute Selector

Contains attribute selector select elements whose attribute value contains a specified value.

The asterisk (*) character represents Contains Attribute selector.

The syntax for Contains Attribute selector is:

selector[attribute*="value"] {
   property: value;
}

Example 0f Contains Attribute selector:

<a href="/signin.com">Code documentation</a>

Styling the above ⬆️ Html code:

a[href*="signin"] {
     color: orange;
     font-size: 20px;
}

The CSS styles will work on any <a> element with a "href" attribute that contains a value of "signin".

Hyphen Attribute Selector

Hyphen attribute-selector select elements with the specified attribute starting with the specified value.

It selects all elements whose attribute has a hyphen-seperated list of values.

The value has to be a whole word, either alone, like class="top", or followed by a hyphen( - ), like class="top-text"!

The vertical line (|) character represents Hyphen Attribute Selector

The syntax for Hyphen Attribute Selector is:

selector[attribute|="value"] {
   property: value;
}

Example 0f Hyphen Attribute selector:

<a href="#" lang="en-US">Code documentation</a>

Styling the above ⬆️ Html code:

a[lang|="en"] {
     color: orange;
     font-size: 20px;
}

The CSS styles will work on any <a> element with a "lang" attribute that contains a value of "en".

It matches the elements with the lang attribute with the values en en-US en-GB and so on but not US-en, GB-en.

PSEUDO SELECTORS

There are two types of pseudo-selectors:

  • Pseudo Class Selectors.
  • Pseudo Element Selectors.

PSEUDO CLASS SELECTORS

A pseudo-class is used to define a unique state of an element.

For example:

  • style an element when a user mouses over it.
  • style visited and unvisited links.
  • style an element when it focus. w3schools

Pseudo-class names are not case-sensitive.

:Hover is the same as :hover. We should use small letters when writing selectors.

The colon (:) character represents Pseudo class selectors.

The syntax for Pseudo class selector is:

selector:pseudo-class {
   property: value;
}

There are three main types of Pseudo-class selectors:

  • User Action Pseudo-classes.
  • link Pseudo-classes.
  • Structural And Positional Pseudo-classes.

USER ACTION PSEUDO-CLASSES

User Action Pseudo-classes work when the user interacts with your web page.

The most used User Action Pseudo-classes are:

  • :hover
  • :active
  • :focus

:hover

:hover works when the user moves their cursor over an element but does not select it.

The syntax for :hover selector is:

selector:hover {
    property: value;
}

In the example above, the color of the link will change to red when you hover over the link.

:Active

We use the :active selector to select and style active links.

A link becomes active when you click on it. The :active selector can be used on all elements, not only links.

The syntax for :active selector is:

selector:active {
    property: value;
}

:focus

The :focus selects an element that is being focused on by the user. "focused on by the user" means it accepts keyboard or any other user input.

It works on user input elements used in forms and is triggered when the user clicks on it.

The syntax for :focus selector is:

selector:focus {
   property: value;
}

The background color of the input field, when focused, changes to yellow in the example above ⬆️.

There are two link Pseudo-classes:

  • :link
  • :visited

Link Pseudo class selector selects a link that the user has not visited before.

The syntax for link selector is:

selector:link {
   property: value;
}

:visited

:visited selects a link that the user has clicked on.

Use them to control the colors of the links and whether they appear underlined or not.

The syntax for :visited selector is:

:visited {
   property: value;
}

:visited can be overridden by a link pseudo-class with equal specificity.

If two or more conflicting CSS rules point to the same element, the browser follows some rules to determine which one is most specific and, therefore, wins out.

Think of specificity as a score/rank that determines which style declarations are ultimately applied to an element. W3schools

It is advisable to use the LVHA rule in the exact order to style them.

LVHA stands for:

  • a:link
  • a:visited
  • a:hover
  • a:active
  • a:focus

Structural And Positional Pseudo-classes.

The most common structural and positional pseudo-classes you will likely come across are the following:

  • :first-child
  • :last-child
  • :Only-child

:first-child

The :first-child pseudo-class applies a style to the element's first child.

The syntax for :first-child selector is:

:first-child {
   property: value;
}

last-child

The :last-child pseudo-class applies a style to an element if it is the last child within its parent.

The syntax for :last-child selector is:

:last-child {
   property: value;
}

In the above example:

  • li:first-child selects line 1 cause is the first list item within the list.

  • li:last-child selects line 4 cause is the last item within the list.

:Only-child

The :only-child pseudo-class applies a style to an element if it is the only element within a parent.

The syntax for :only-child selector is:

:only-child {
   property: value;
}

Example

<ul>
   <li>The first child will be red</li>
</ul>

Styling the above ⬆️ Html code:

li:only-child {
   background-color: red;
   color: white;
   padding: .7em;
}

The above ⬆️ CSS styles will apply background-color: red; to the <li> element cause is the only child.

PSEUDO ELEMENTS

A CSS pseudo-element is a keyword added to a selector that lets us style a specific part of the selected element(s) MDN

The double-colon (::) represents pseudo-element selectors.

The syntax for Pseudo element selector is:

selector::pseudo-element {
   property: value;
}

Textual Pseudo-elements

The textual pseudo-elements consist of the:

  • ::first-letter pseudo-element
  • :first-line pseudo-element

::first-letter Pseudo-element

The ::first-letter applies a style to the first letter of the element.

The syntax for ::first-letter Pseudo element selector is:

selector::first-letter {
   property: value;
}

::first-line Pseudo-element

The ::first-line applies a style to the first line of the element.

The syntax for ::first-line Pseudo element selector is:

selector::first-line {
   property: value;
}

Both the ::first-line and the ::first-letter pseudo-element work only for block elements

Generated Content Pseudo-elements

The generated pseudo-element consist of the:

  • ::before pseudo-element
  • ::after pseudo-element

::before Pseudo-element

The ::before pseudo-element adds content before the HTML element.

The syntax for ::before Pseudo element selector is:

selector::before {
   property: value;
}

::after Pseudo-element

The ::after pseudo-element adds content after the HTML element.

The syntax for ::after Pseudo element selector is:

selector::first-line {
  property: value;
}

When using the ::after and ::before pseudo-elements we must use the content property to make your styles visible.

In the example above ⬆️, we added ' to before and after the <p> element. We can also add images using the content: URL("image_link.jpg")

Difference between pseudo-class and pseudo-element

The two main differences between a pseudo-class and pseudo-element are:

1. Pseudo-elements are preceded with two colons :: instead of one, although these days modern browsers are more forgiving and support both : and double :: colons for the pseudo-elements. It is best practice to use double colons ::

2. Pseudo-classes are all about the state, states like a visited link, a focused input field, an image that is being hovered upon, e.tc. While pseudo-elements are used to style sections or a particular part of an element, things like the first letter in a word, first-line e.tc.

CONCLUSION

I hope we enjoyed this post and that it helps us on our way to becoming better front-end developers.

If you found this article helpful, please like and share it 💙.

That's all for today! 😁 You reached the end of the article 😍.

RESOURCES

Check out some of these resources for a more in-depth look into CSS pseudo-classes and pseudo-elements: