Programmer Typing New Lines of HTML Code. Laptop and Hand Closeup
As one of Indianapolis’ top web development companies, it is important for us to understand technology and its benefits. We consistently look for new tools and best practices to improve our development process so that we can deliver the best websites possible to our clients. In this article, we’re going to explore one of those tools: CSS selectors.

Understanding CSS selectors is crucial to the web development process. They can help you target website elements in new ways, leading to cleaner, more flexible styles. As a result, your website will be easier to update and maintain.

So, what is a CSS selector? If you’ve ever written any CSS, you’ve probably used them! Take a look at the example below:

h1 {
  color: black;
 }

The entire piece is referred to as a CSS rule, and in this example, the “h1” is the selector.

There are many selector types, from the basics like tags and classes, to more advanced options like attribute selectors and pseudo classes. These different selector types can be used to achieve a variety of effects on the web. Let’s take a closer look at some popular selectors and how you can put them to use!

Type selectors

Type selectors are one of the most basic selectors, and can target specific elements on a page by using an element’s tag name.

Example 1

We want to change the color of all h3 elements on our website to red:

h3 {
  color: red;
 }

Example 2

We want to add some padding to all div tags on our website:

div {
  padding: 10px;
 }

Class & ID selectors

Class and ID selectors are also very common selectors. Using a class or ID name as a selector targets any element that has a matching class or ID. For class selectors, a period must be placed before the class name in the CSS. For ID selectors, a number sign must be placed before the ID name in the CSS.

It is possible to select an element with multiple classes or IDs as well. This can be done by placing the selectors one after another with no spaces in between.

Example 1

We want to add a border to any element with the ID of highlight on our page.
HTML:
<div id="highlight">
  This is section 1.
 </div>
 

 <div id="not-highlight">
  This is section 2.
 </div>
CSS:
#highlight {
  border: 1px solid black;
 }

In this case, section 1 would have a border, but section 2 would not.

Example 2

We want to add a border to any element that has the class of highlight, but a red border to any element with the class of both highlight and red.
HTML:
<div class="highlight red">
  This is section 1.
 </div>
 

 <div class="highlight">
  This is section 2.
 </div>
CSS:
.highlight {
  border: 1px solid black;
 }
 .highlight.red {
  border: 1px solid red;
 }

In this case, section 1 would have a red border, and section 2 would have a black border.

Descendant, child, & sibling selectors

You can use different combinations of selectors to target elements more specifically. For example, these types of selectors can come in handy when you don’t have much control over the HTML code on a page. If you can’t edit the HTML to add in a class or ID to target an element, you may be able to do it with a combination of selectors instead.

Descendant selectors target elements that are descendants of another element. This is done by adding spaces between element names.

Example

We want to change the text color to orange for all h1 elements that are inside of a div with the class of title.
HTML:
<div class="title">
  <h1>Heading</h1>
  <div class="section">
  <h1>Heading</h1>
  </div>
 </div>
CSS:
.title h1 {
  color: orange;
 }

In this example, both the of h1 elements would be orange, since they both are descendants of the div with the class of title.

Child selectors can be used to select child elements. This is done using the “>” symbol.

Example

We want to change the text color to orange for all h1 elements that are direct children of a div with the class of title.
HTML:
<div class="title">
  <h1>Heading</h1>
  <div class="section">
  <h1>Heading</h1>
  </div>
 </div>
CSS:
.title > h1 {
  color: orange;
 }

In this case, only the first h1 element would be orange since it is a child element of the div with the class of title. The second h1 element would be a child element of the div with the class of section instead.

General sibling selectors target elements that share the same parent element. This is achieved by placing a tilde (~) character between two element names, in which the first element comes before the second element on the page.

Example

We want to change the background of paragraphs under a title element, but only in the div with the class of section.
HTML:
<h1 class="title">Title heading 1</h1>
 <p>This is paragraph a.</p>
 <div class="section">
  <p>This is paragraph 1.</p>
  <h1 class="title">Title heading 2</h1>
  <p>This is paragraph 2.</p>
  <p>This is paragraph 3.</p>
 </div>
CSS:
.section .title ~ p {
  background: red;
 }

In this case, only paragraphs 2 and 3 in the div with the class of section would have a red background, since they are both siblings (share the same parent) of Title heading 2. Although paragraph 1 shares the same parent as well, it comes before the title instead of after it.

Adjacent sibling selectors target elements that share the same parent element but are also adjacent to each other. This is achieved by placing a plus sign between two element names, in which the first element comes before the second element on the page.

Example

We want to change the margin on paragraphs that are directly underneath title elements to not have quite as much space at the top as other paragraphs.
HTML:
<p>This is paragraph 0.</p>
 <h1 class="title">Title heading</h1>
 <p>This is paragraph 1.</p>
 <p>This is paragraph 2.</p>
 <p>This is paragraph 3.</p>
CSS:
p {
  margin: 10px 0;
 }
 .title + p {
  margin: 0 0 10px 0;
 }

In this case, paragraph 1 would not have any top margin, though the other paragraphs would remain the same.

Attribute selectors

Attribute selectors are one of the advanced selectors that can be used to gain control over your website. These selectors can be used to target an element’s attribute instead of just the element itself, using brackets following the selector name.

Example

We want to add a PDF icon to PDF links to differentiate them from normal links. This can be done using the “ends with” attribute selector.
CSS:
a[href$=".pdf"] {
  background: url("images/pdf.png") 100% 50% no-repeat;
  padding: 0 24px 0 0;
 }

This targets any link element whose URL ends with “.pdf”, allowing us to add our PDF icon at the end of the link name.

Pseudo-classes

Pseudo-classes are another type of advanced selector, and can be used to generate a variety of interesting effects on a website. They are unique in that they can be applied dynamically to elements based on things like user actions or element state. A pseudo-class is applied to the end of an element, with a colon following the pseudo-class name.

User action pseudo-classes

We can target elements in different states: hover, focus, and active.
CSS:
element_selector:hover {...}
 element_selector:focus {...}
 element_selector:active {...}

Structural pseudo-classes

There a variety of ways to target elements based on its position in the structure of a page. Here are some popular options:
:first-child & :last-child
These pseudo-classes can target the first or last child of an element. For example, you could target the first and last items of a list:

ul li:first-child {...}
 ul li:last-child {...}
:nth-child
This is a more complicated pseudo-class, but a very powerful one, that targets elements based on numbers or expression. Below is a basic example that will target every even numbered list item.

li:nth-child(even) {...}

Pseudo-elements

Pseudo elements are similar to pseudo-classes, but they differ in that they don’t target existing elements.

:first-letter & :first-line

The :first-letter and :first-line pseudo-elements can be used to control text within a parent element.
CSS:
p {
  font-size: 12px;
 }
 p.one:first-letter, p.two:first-line {
  font-size: 18px;
 }

In this example, the paragraph with the class of one and the first line of the paragraph with the class of two would be larger than the rest of the text in those paragraphs.

Generated content pseudo-elements

The :before and :after pseudo-elements can be used to add content to an element.

Example 1

We could use the :before pseudo-element to add “read more” in front of links to additional information:
CSS:
a.read-more:before {
  content: "Read more: ";
 }

Example 2

We could use the :after pseudo-element to add an email icon after email links.
CSS:
a[href^="mailto:"]:after {
  content: url('images/email.png');
 }

For some creative uses of pseudo-elements, check out the CSS Tricks article A Whole Bunch of Amazing Stuff Pseudo Elements Can Do.

Hopefully now you have a better understanding CSS selectors, and how powerful they can be. Try them out on your project, and see what you can accomplish! Check out this guide to Complex selectors for more information and examples. For the most current information on CSS selectors, check out the W3.org CSS selector specification.
Subscribe to our marketing blog for free resources