EasyCode365EasyCode365

Advanced CSS selectors and combinators

Basic selectors help you style simple pages. As your HTML grows, you often need to style elements based on where they are, what they are inside, or which attributes they have.

Advanced selectors help you target elements more carefully. This means you can write cleaner HTML and avoid adding a class to every single tag.

Quick reminder of basic selectors

You already know these common selectors:

  • An element selector targets every tag of one type, such as p.
  • A class selector starts with . and targets elements with that class, such as .button.
  • An ID selector starts with # and targets one unique element, such as #main-header.

Advanced selectors build on those basics.

What is a combinator?

A combinator is a symbol or space that describes a relationship between two selectors.

For example, a combinator can mean:

  • Select a paragraph inside a card.
  • Select only direct list items inside a menu.
  • Select a button that comes right after an input.

Descendant selector

The descendant selector selects an element inside another element, even if it is nested several levels deep.

Syntax:

Read-only

The space between the selectors is important.

Can edit
<div class="card">
  <h2>Welcome</h2>
  <div>
    <p>This paragraph is inside the card.</p>
  </div>
</div>

<p>This paragraph is outside the card.</p>

<style>
  .card p {
    color: blue;
  }
</style>

The rule .card p means: find any p element that lives anywhere inside an element with the class card.

The paragraph outside .card is not selected.

Use this when you want to style content inside a section, card, article, or navigation area.

Child selector

The child selector selects only direct children. It does not select grandchildren or deeper nested elements.

Syntax:

Read-only
Can edit
<div class="toolbar">
  <button>Save</button>
  <button>Preview</button>

  <div class="more-actions">
    <button>Delete</button>
  </div>
</div>

<style>
  .toolbar > button {
    background-color: blue;
    color: white;
    padding: 8px 12px;
  }
</style>

The rule .toolbar > button means: select only the button elements that are directly inside .toolbar.

The Delete button is not selected because it is inside .more-actions first. It is deeper than one level.

Use this when a section has direct items and nested items that should look different.

Adjacent sibling selector

The adjacent sibling selector selects an element that comes immediately after another element.

Sibling elements share the same parent.

Syntax:

Read-only
Can edit
<article>
  <h2>Learning CSS</h2>
  <p>This first paragraph introduces the lesson.</p>
  <p>This second paragraph continues the idea.</p>
</article>

<style>
  h2 + p {
    margin-top: 0;
    color: blue;
    font-size: 20px;
  }
</style>

The rule h2 + p means: select a p element only when it comes directly after an h2.

The second paragraph is not selected because it is not directly after the heading.

Use this when the first paragraph after a heading needs a special style.

General sibling selector

The general sibling selector selects all matching sibling elements that come after another element.

They must share the same parent, but they do not need to be right next to each other.

Syntax:

Read-only
Can edit
<section>
  <h3>Ingredients</h3>
  <strong>Breakfast list</strong>
  <p>Flour</p>
  <p>Eggs</p>
  <p>Milk</p>
</section>

<style>
  h3 ~ p {
    color: blue;
  }
</style>

The rule h3 ~ p means: select every p element that comes after the h3 inside the same parent.

The strong element between them does not matter.

Use this when several elements after a heading or label need the same style.

Attribute selectors

An attribute selector selects elements by their HTML attributes.

Attributes are extra details inside HTML tags, such as href, type, alt, or placeholder.

Syntax:

Read-only
Can edit
<label>
  Name
  <input type="text" placeholder="Enter your name" />
</label>

<label>
  Password
  <input type="password" placeholder="Enter your password" />
</label>

<style>
  input[type="text"] {
    background-color: lightyellow;
  }
</style>

The rule input[type="text"] means: find input elements where the type attribute is exactly text.

The password input is not selected because its type is password.

Use this for forms, links, images, and other elements where the attribute tells you what kind of element it is.

Universal selector

The universal selector selects every element.

Syntax:

Read-only
Can edit
<h1>Title</h1>
<p>Paragraph text</p>
<button>Click me</button>

<style>
  * {
    color: blue;
  }
</style>

The rule * means: select every element on the page.

Use it carefully. It is common in small reset rules or simple defaults, but it can affect more elements than you expect.

Common beginner mistakes

  • Writing .cardp instead of .card p. .cardp looks for a class named cardp. .card p looks for a paragraph inside .card.
  • Using > when the element is not a direct child. The child selector only looks one level down.
  • Using + when the element is not immediately next. The adjacent sibling selector only selects the very next matching sibling.
  • Using + or ~ for elements that do not share the same parent. Sibling selectors only work between siblings.
  • Using * too often. The universal selector can make your CSS harder to predict on larger pages.

Mini task

Look at this HTML:

Can edit
<div class="box">
  <h2>My title</h2>
  <a href="https://example.com">Click here</a>
</div>

<style>

</style>

Write a CSS rule with a descendant selector that makes the link inside .box orange.

Answer:

Read-only

Short quiz

Question 1: Which symbol is used for the direct child selector?

Answer: The greater-than symbol >.

Question 2: Which selector selects every element on the page?

Answer: The universal selector *.

Question 3: What is the difference between + and ~?

Answer: + selects only the very next sibling. ~ selects all matching siblings that come after.

Small challenge

Try styling this form card:

  • Use a child selector to make the direct paragraph text gray.
  • Use an attribute selector to give the text input a gray border.
  • Use an adjacent sibling selector to make the button text bold.
Can edit
<div class="login-card">
  <p>Please log in below.</p>
  <input type="text" placeholder="Username" />
  <button>Log in</button>
</div>

<style>
  /* 1. Style the direct paragraph */

  /* 2. Style the text input */

  /* 3. Style the button after the input */
</style>

One possible answer:

Read-only

Summary

  • The descendant selector uses a space and selects nested elements.
  • The child selector > selects only direct children.
  • The adjacent sibling selector + selects the next sibling.
  • The general sibling selector ~ selects matching siblings that come later.
  • Attribute selectors target elements by HTML attributes.
  • The universal selector * selects every element.

Related lessons

  • CSS syntax and basic selectors
  • CSS specificity, cascade, and inheritance
  • CSS display and positioning