Selectors are really one of the most important concepts you can learn in web development. You can’t style anything on a web page without first using a selector to target the various items. In addition, you can also use CSS selectors in many other interesting ways in various programming languages. So for this tutorial we are going to learn all about CSS Selectors. We’ll look at the Simple selectors such as Type, Class, ID, Universal, and Attribute based. Then we’ll look at Combinators like the Descendant combinator, Child combinator, Adjacent Sibling combinator, and the General Sibling combinator. Finally we’ll take a look at how to use Pseudo Classes and Pseudo Elements.
Simple Selectors
Simple CSS Selectors are selectors that are most commonly used and cover a good amount of use cases. The simple CSS selectors include selecting by the HTML tag name, selecting by a specific ID, selecting with a class name, and selecting using various combinations of attributes. You can go pretty far with just these simple CSS selectors.
Type Selector
Also known as the Element Selector, the Type Selector targets all elements that match the given node name. This allows you to select all <p> elements or all <div> elements at one time.
element { css style properties }
Type Selector Example
p {
background-color: lightblue;
}
<body>
<div>
<p>This is a paragraph with some text in it.</p>
<div>I'm just one div in between two paragraph tags.</div>
<p>This is a different paragraph with text.</p>
</div>
</body>
ID Selector
The ID Selector selects the HTML element based on the value contained in its id
attribute. An ID Selector is used when you want to target one specific element on the web page.
#id_value { css style properties }
ID Selector Example
#coffee {
background-color: lightblue;
}
<body>
<div>
<p>This paragraph doesn't have any id attribute.</p>
<p id="coffee">This paragraph has an id of "coffee".</p>
</div>
</body>
Class Selector
Some say the Class Selector is the most useful of the available CSS Selectors. In fact, almost all modern CSS Frameworks allow you to style elements by simply applying a class name. It is helpful to have many elements on the same page that share a given class. This helps to allow the reuse of styles leading to less repetition in the CSS code.
.class_name { css style properties }
Class Selector Example
.awesome {
background-color: lightblue;
}
<body>
<div>
<p>This paragraph doesn't have any class.</p>
<p class="awesome">This paragraph has awesome class.</p>
<div class="foo bar awesome">This div has 3 classes. One of them is awesome.</<span class="hiddenGrammarError" pre=""><span class="hiddenGrammarError" pre=""><span class="hiddenGrammarError" pre=""><span class="hiddenGrammarError" pre=""><span class="hiddenGrammarError" pre="Then "><span class="hiddenGrammarError" pre="use ">div>
</div</span></span></span></span></span></span>>
</body>
Attribute Selectors
Square brackets are used to create an Attribute Selector in CSS. This selector selects tags based on the existence or value of an HTML attribute. There are several types of attribute selectors in CSS.
[attribute]
The [attribute] selector is used to target elements on the web page with the given attribute.
[attribute] { css style properties }
[attribute] Selector Example
[title] {
background-color: lightblue;
}
<body>
<a href="#" title="Happy Link">This link has a title attribute.</a>
<a href="#">This link has no title attribute.</a>
</body>
[attr=value]
The [attribute=value] selector is used to target elements on the web page with the given attribute and specified value.
[attribute=value] { css style properties }
[attribute=value] Selector Example
[href="https://google.com"] {
background-color: lightblue;
}
<body>
<a href="https://google.com">Google</a>
<a href="https://bing.com">Bing</a>
<a href="https://duckduckgo.com">Duck Duck Go</a>
</body>
[attribute~=value]
The [attribute~=value] selector is used to target elements that have an attribute value containing a specified word.
[attribute~=value] { css style properties }
[attribute~=value] Selector Example
[data~="hooray"] {
background-color: lightblue;
}
<body>
<div data="hip">This is hip.</div>
<div data="hip hop">This is hip hop.</div>
<div data="hip hop hooray">Hip hop hooray.</div>
</body>
[attribute|=value]
The [attribute|=value] selector targets elements with an attribute value that can be exactly as given or can begin with the value immediately followed by a hyphen.
[attribute|=value] { css style properties }
[attribute|=value] Selector Example
[class|="lg"] {
background-color: lightblue;
}
<body>
<div class="btn">Button</div>
<div class="lg-btn">Large Button</div>
<div class="sm-btn">Small Button</div>
</body>
[attribute^=value]
The [attribute^=value] has a caret (^) operator, which means “to start with”. This will target elements on the page where the given attribute starts with a specific value. For example you may be able to select all links on the page that are external vs internal, and make the background color light blue.
[attribute^=value] { css style properties }
[attribute^=value] Selector Example
a[href^="http://"] {
background-color: lightblue;
}
<body>
<a href="http://www.webdesignernews.com/">Web Design News (External Link)</a>
<a href="/design/web.html">Design Category (Internal Link)</a>
</body>
[attribute$=value]
This attribute selector makes use of the dollar sign which is the opposite of the prior example. While the caret means to start with, the $ symbol means “ends with”. A use case for this might be to target links on the page which link to a PDF document.
[attribute$=value] { css style properties }
[attribute$=value] Selector Example
a[href$=".pdf"] {
background-color: lightblue;
}
<body>
<a href="http://www.webdesignernews.com/">Web Design News</a>
<a href="/design/great.pdf">A Great PDF To Read</a>
</body>
[attribute*=value]
The final attribute substring selector we’ll look at makes use of the asterisk (*
) operator, which stands for “contains”.
[attribute*=value] { css style properties }
[attribute*=value] Selector Example
[class*="blockquote"] {
background-color: lightblue;
}
<body>
<div class="blockquote-lead">Leading div element.</div>
<div class="banana">Div in the middle.</div>
<p class="blockquote-footer">Paragraph in the footer area.</p>
</body>
Universal Selector
* { css style properties }
Universal Selector Example
The asterisk is often used as a wild card character of sorts, and when used as a CSS selector that is exactly what it is. The Universal Selector selects every element on the web page at once. It’s not something you would use frequently but is good for resetting the box-sizing in layouts to render better widths and heights. You will often see a style sheet use the universal selector to set margin and padding both to 0. This gives the same starting point for a page layout no matter what type of browser, device, or operating system is being used.
* {
background-color: lightblue;
}
<body>
<div>One</div>
<div>Two</div>
<div>Three</div>
</body>
Combinator Selectors
Combinator selectors in CSS are the next level of granularity when selecting page elements in CSS. Combinators are used to target children, grandchildren, great-grandchildren, or later of a given element in the document tree. They symbols used for Combinators include the space character
, greater than character >
, the plus sign +
, and the tilde ~
.
Descendant Combinator
The Descendant Combinator is actually an empty space (
). The pattern of this combinator is simply two tags side by side with a space in between them. It selects elements that are descendants of the first element.
tag tag { css style properties }
Descendant Combinator Selector Example
In this example there are four <li> elements on the page. Only the two that are descendants of the <div> are targeted however.
div li {
background-color: lightblue;
}
<body>
<ul>
<li>First in the list.</li>
<li>Second in the list.</li>
</ul>
<div>
<li>First in the list.</li>
<li>Second in the list.</li>
</div>
</body>
Child Combinator
The child combinator uses the greater than (>
) operator and targets elements that are immediate children of the parent. The difference between Descendant and Child selectors is that the Child Combinator is more specific. It only will select direct children elements of the first tag. The Descendant Combinator however is more liberal. Not only will it select children of the first tag, it will also select grand children, great grand children, and so on.
tag > tag { css style properties }
Child Combinator Selector Example
div > p {
background-color: lightblue;
}
<body>
<div>
<p>Paragraph in a div.</p>
<p>Another paragraph in a div.</p>
<span>
<p>A paragraph in a span.</p>
</span>
</div>
</body>
Watch the difference now if we use the Descendant Combinator (div p
) instead of the Child Combinator (div > p
). Note now that the third paragraph which is a grandchild of the <div> is still targeted.
div p {
background-color: lightblue;
}
Adjacent Sibling Combinator
The Adjacent Sibling Combinator uses the plus sign (+
) and targets elements that are next to each other in the document tree which have the same parent. In other words the second tag directly follows the first, and they share the same parent element.
tag + tag { css style properties }
Adjacent Sibling Combinator Selector Example
h2 + p {
background-color: lightblue;
}
<body>
<div>
<h1>Adjacent Sibling Combinator!</h1>
<p>Paragraph.</p>
<section>
<h2>Section Title</h2>
<p>Paragraph in the section.</p>
<p>Next Paragraph in the section.</p>
</section>
<p>Paragraph after the section.</p>
</div>
</body>
So in this example h2 + p
targets every <p> element that is placed immediately after an <h2> element.
General Sibling Combinator
The General Sibling Combinator uses the tilde (~
) operator. It differs from the Adjacent Sibling Combinator in that the second selector doesn’t have to immediately follow the first. Both elements must both share the same parent.
tag ~ tag { css style properties }
General Sibling Combinator Selector Example
Both the <h1> and the <section> share the <div> as the same parent. Note that there is a <p> <em>in between</em> the <h1> and the <section>. The general sibling combinator ignores that <p> and targets the <section>.
h1 ~ section {
background-color: lightblue;
}
<body>
<div>
<h1>General Sibling Combinator!</h1>
<p>Paragraph.</p>
<section>
<h2>Section Title</h2>
<p>Paragraph in the section.</p>
<p>Next Paragraph in the section.</p>
</section>
<p>Paragraph after the section.</p>
</div>
</body>
Pseudo Classes
Pseudo-classes are used to target elements on the web page based on state information that is not part of the document tree. First we’ll look at the Structural pseudo-classes.
Structural Pseudo Classes
Structural Pseudo Classes are a powerful way to target elements in the DOM which otherwise would not be able to be targeted without adding extra IDs or classes. The use of Structural Pseudo Classes is meant to minimize the addition of extraneous classes in your HTML markup thereby keeping your layouts cleaner and easier to deal with.
:first-child Selector
The :first-child
selector allows you to target the first child of a specified element in the document tree.
:first-child { css style properties }
:first-child Selector Example
p:first-child {
background-color: lightblue;
}
<body>
<p>This <p> is the first child of <body>.</p>
<h1>:first-child Selector Example</h1>
<p>This <p> is the third child of <body>.</p>
<div>
<p>This <p> is the first child of <div>.</p>
<p>This <p> is not the first child of <div>.</p>
</div>
</body>
:last-child Selector
The :last-child selector targets any element that is the last child of its parent element.
:last-child { css style properties }
:last-child Selector Example
p:last-child {
background-color: lightblue;
}
<body>
<p>This <p> is the first child of <body>.</p>
<h1>:last-child Selector Example</h1>
<p>This <p> is the third child of <body>.</p>
<div>
<p>This <p> is the first child of <div>.</p>
<p>This <p> is the last child of <div>.</p>
</div>
</body>
:nth-child Selector
The :nth-child selector allows you to select one or more specific children of a given parent element. It can take the form of a number (integer), keywords (odd or even), or a calculation (expression).
:nth-child { css style properties }
:nth-child Selector Example 1
:nth-child(4) {
background-color: lightblue;
}
<body>
<ul>
<li>Honda</li>
<li>Tesla</li>
<li>Subaru</li>
<li>Toyota</li>
<li>Lambo</li>
</ul>
</body>
:nth-child Selector Example 2
li:nth-child(even) {
background-color: lightblue;
}
<body>
<ul>
<li>Honda</li>
<li>Tesla</li>
<li>Subaru</li>
<li>Toyota</li>
<li>Lambo</li>
</ul>
</body>
:nth-child Selector Example 3
li:nth-child(odd) {
background-color: lightblue;
}
<body>
<ul>
<li>Honda</li>
<li>Tesla</li>
<li>Subaru</li>
<li>Toyota</li>
<li>Lambo</li>
</ul>
</body>
:nth-child Selector Example 4
a
is an integer valuen
is the literal letter "n"+
is an operator and may also be a-
b
is an integer and is required if an operator is included in the formula
li:nth-child(3n+3) {
background-color: lightblue;
}
<body>
<ul>
<li>Honda</li>
<li>Tesla</li>
<li>Subaru</li>
<li>Toyota</li>
<li>Lambo</li>
<li>Porche</li>
</ul>
</body>
:nth-last-child Selector
The :nth-last-child Selector works just like the :nth-child Selector except in reverse. That is to say that :nth-last-child starts counting from the last element.
:nth-last-child { css style properties }
:nth-last-child Selector Example 1
li:nth-last-child(2) {
background-color: lightblue;
}
<body>
<ul>
<li>Honda</li>
<li>Tesla</li>
<li>Subaru</li>
<li>Toyota</li>
<li>Lambo</li>
<li>Porche</li>
</ul>
</body>
:nth-last-child Selector Example 2
li:nth-last-child(even) {
background-color: lightblue;
}
<body>
<ul>
<li>Honda</li>
<li>Tesla</li>
<li>Subaru</li>
<li>Toyota</li>
<li>Lambo</li>
<li>Porche</li>
</ul>
</body>
:nth-last-child Selector Example 3
li:nth-last-child(odd) {
background-color: lightblue;
}
<body>
<ul>
<li>Honda</li>
<li>Tesla</li>
<li>Subaru</li>
<li>Toyota</li>
<li>Lambo</li>
<li>Porche</li>
</ul>
</body>
:nth-last-child Selector Example 4
li:nth-last-child(odd) {
background-color: lightblue;
}
<body>
<ul>
<li>Honda</li>
<li>Tesla</li>
<li>Subaru</li>
<li>Toyota</li>
<li>Lambo</li>
<li>Porche</li>
</ul>
</body>
:only-child Selector
The :only-child selector targets an element that doesn’t have any sibling elements. In other words, it works by targeting any element that is the only child of its parent.
:only-child { css style properties }
:only-child Selector Example
div:only-child {
background-color: lightblue;
}
<body>
<div>
<div>This div is an only child.</div>
</div>
<div>
<div>This div is a 1st sibling.</div>
<div>This div is a 2nd sibling.</div>
<div>This div is a 3rd sibling
<div>This div is an only child.</div>
</div>
</div>
</body>
:first-of-type Selector
The :first-of-type Selector targets the first element of this type within any parent. So if you have two divs, each had within it a paragraph, div, div, and ul. Then div div:first-of-type would select the first div inside the first div and the first div inside the second div.
:first-of-type { css style properties }
:first-of-type Selector Example
div div:first-of-type {
background-color: lightblue;
}
<body>
<div>
<p>Paragraph</p>
<div>div</div>
<div>div</div>
<ul>
<li>list item</li>
</ul>
</div>
<div>
<p>Paragraph</p>
<div>div</div>
<div>div</div>
<ul>
<li>list item</li>
</ul>
</div>
</body>
:last-of-type Selector
The :last-of-type Selector works just like the :first-of-type Selector except the last of the specified type of element is targeted.
:last-of-type { css style properties }
:last-of-type Selector Example
div div:last-of-type {
background-color: lightblue;
}
<body>
<div>
<p>Paragraph</p>
<div>div</div>
<div>div</div>
<ul>
<li>list item</li>
</ul>
</div>
<div>
<p>Paragraph</p>
<div>div</div>
<div>div</div>
<ul>
<li>list item</li>
</ul>
</div>
</body>
:nth-of-type Selector
The :nth-of-type selector works in a similar way to :nth-child and uses the same syntax. It is sometimes more useful than :nth-child if there are elements between those you are targeting. For example if inside a div you had a number of paragraphs and a number of divs. If you wanted to select all the even divs, :nth-child won’t work there but you could use div div:nth-of-type(even).
:nth-of-type { css style properties }
:nth-of-type Selector Example
div div:nth-of-type(even) {
background-color: lightblue;
}
<body>
<div>
<p>A p tag</p>
<div>A div tag</div>
<div>A div tag</div>
<p>A p tag</p>
<p>A p tag</p>
<p>A p tag</p>
<div>A div tag</div>
<div>A div tag</div>
<p>A p tag</p>
</div>
</body>
:nth-last-of-type Selector
The :nth-last-of-type Selector works just like the :nth-of-type Selector but starts at the end instead of the beginning.
:nth-last-of-type { css style properties }
:nth-last-of-type Selector Example
div div:nth-last-of-type(even) {
background-color: lightblue;
}
<body>
<div>
<p>A p tag</p>
<div>A div tag</div>
<div>A div tag</div>
<p>A p tag</p>
<p>A p tag</p>
<p>A p tag</p>
<div>A div tag</div>
<div>A div tag</div>
<p>A p tag</p>
</div>
</body>
:only-of-type Selector
The :only-of-type selector targets elements where the parent elements do not have any other children of the same type.
:only-of-type { css style properties }
:only-of-type Selector Example
p:only-of-type {
background-color: lightblue;
}
<body>
<div>
Div 1
<p>1 p tag</p>
<p>2 p tags</p>
</div>
<div>
Div 2
<p>1 p tag</p>
</div>
</body>
:empty Selector
The :empty selector can be a useful pseudo-class. It represents an element in the web page that has no content. Imagine there is a dynamically generated widget on your page that sometimes has no contents, depending on various factors. If it is empty, we can hide it using :empty.
widget:empty {
display:none;
}
For completeness, there is also a :root structural pseudo-class which targets the root of the document. There probably aren’t a lot of use cases for the :root selector, but it’s good to know it exists.
Pseudo Elements
Pseudo elements are elements that can be seen on a web page but aren’t technically “in the DOM” so to speak. They are instead inserted directly from CSS. It’s kind of like having a low powered version of jQuery built right into CSS. Pseudo elements allow you to do lots little design tricks without cluttering the markup. At first it might be easy to confuse the Pseudo Classes we discussed above and Pseudo Elements. Notice above that all the selectors started with a single colon (:
). That is the signature of a Pseudo Class. Pseudo Elements on the other hand always use a double colon (::
).
::before Pseudo Element
::before { css style properties }
::before creates content right before the selected element. ::before is often used to add simple cosmetic content to an element using the content
property.
::before Pseudo Element Example
p::before {
content: 'Check this out: ';
color: gray;
}
<body>
<div>
<p>This is a message you don't want to miss.</p>
</div>
</body>
::after Pseudo Element
The ::after pseudo element works just like ::before except content is added after the targeted element.
::after { css style properties }
::after Pseudo Element Example
p::after {
content: ' Thanks for reading!';
color: gray;
}
<body>
<div>
<p>This is a message you don't want to miss.</p>
</div>
</body>
::first-line Pseudo Element
The ::first-line selector targets the first line of a block-level element. The effect may be dynamic as the length of the first line depends on many factors such as the width of the element, the width of the page, and the font size in use.
::first-line { css style properties }
::first-line Pseudo Element Example
p::first-line {
background-color: lightblue;
}
<body>
<div>
<p>This paragraph is full of nonsense for the bored reader
to find interest in. We're not sure how long it will go,
but it would be nice if it goes a few lines so we can
demonstrate the ::first-line pseudo-element. Thanks.
</p>
</div>
</body>
::first-letter Pseudo Element
The ::first-letter Pseudo Element simply targets the very first letter of the specified element.
::first-letter { css style properties }
::first-letter Pseudo Element Example
p::first-letter {
background-color: lightblue;
font-size: 25px;
}
<body>
<div>
<p>Hi. How's it going?</p>
</div>
</body>
CSS Selectors Tutorial Summary
In this tutorial we learned all about how selectors work in CSS. With practice, you’ll learn how to best use selectors to reduce the need to add unnecessary classes and IDs to your markup, which ensures that we can separate the content and presentation from each other. We learned all about Simple selectors such as Type, Class, ID, Universal, and Attribute along with the Descendant combinator, Child combinator, Adjacent Sibling combinator, and the General Sibling combinator. In addition, we had a good overview of what Pseudo Classes and Pseudo Elements are and how to use them.