Advanced Selectors
Advanced CSS selectors target elements by their relationships and state instead of just their class or tag, using combinators like > and ~ , attribute selectors such as [type="email"] , and pseudo-classes like :nth-child() to style markup precisely without extra classes.
Learn Python, JavaScript, Java and more with free interactive lessons, real projects and AI-powered help. Beginner-friendly.
Part of the free HTML & CSS course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Basic selectors are like addressing a letter to "John". Advanced selectors are like saying "the third John who lives on Main Street, but only when he's at home." They give you surgical precision — you can target any element based on its state, position, attributes, or relationship to other elements.
Pseudo-classes select elements based on their current state — whether they're hovered, focused, the first child, or match a pattern.
Pseudo-elements create virtual elements that don't exist in the HTML. They're perfect for decorative content, icons, and styling parts of text.
Combinators target elements based on their relationship to other elements in the DOM tree.
Target elements based on their HTML attributes — incredibly useful for styling links, inputs, and data attributes.
You now have surgical precision when targeting CSS elements:
Practice quiz
What is the difference between a single colon and a double colon, as in :hover vs ::before?
- They are interchangeable
- Double colons are invalid CSS
- A single colon marks a pseudo-class (state); a double colon marks a pseudo-element (virtual content)
- Single colons only work on links
Answer: A single colon marks a pseudo-class (state); a double colon marks a pseudo-element (virtual content). Pseudo-classes (:hover, :focus) target a state; pseudo-elements (::before, ::after) create virtual content.
What does the child combinator div > p select?
- Only p elements that are direct children of div
- All p elements anywhere inside div
- The first p after a div
- All p elements that follow div
Answer: Only p elements that are direct children of div. The > combinator matches only direct (immediate) child p elements of div, not deeper descendants.
What does the descendant combinator div p (with a space) select?
- Only direct child p elements
- The p immediately after div
- div elements inside p
- All p elements inside div at any depth
Answer: All p elements inside div at any depth. A space is the descendant combinator: it matches all p inside div regardless of nesting depth.
What does the adjacent sibling combinator h2 + p select?
- All p siblings after h2
- The first p immediately after an h2 (same parent)
- Every p inside h2
- The p before h2
Answer: The first p immediately after an h2 (same parent). h2 + p matches the single p that immediately follows an h2 and shares its parent.
What does the general sibling combinator h2 ~ p select?
- All p elements after h2 that share the same parent
- Only the first p after h2
- p elements inside h2
- The p directly before h2
Answer: All p elements after h2 that share the same parent. h2 ~ p matches every p that comes after an h2 and has the same parent.
Which attribute selector matches links whose href ends with .pdf?
$= matches values that end with the substring, so [href$=".pdf"] targets PDF links.
Which attribute selector matches links whose href starts with https?
^= matches values that start with the substring, so [href^="https"] targets secure links.
Which attribute selector matches an href that contains the substring 'youtube' anywhere?
*= matches values containing the substring anywhere within them.
What must you always include for a ::before or ::after pseudo-element to render?
- A width property
- The content property (even if empty: content: "")
- A position value
- A z-index
Answer: The content property (even if empty: content: ""). ::before and ::after require the content property; without it they do not render at all.
What is the difference between :nth-child(2) and :nth-of-type(2)?
- They are identical
- :nth-of-type counts from the end
- :nth-child(2) targets the 2nd child of any type; :nth-of-type(2) targets the 2nd element of that specific type
- :nth-child only works on lists
Answer: :nth-child(2) targets the 2nd child of any type; :nth-of-type(2) targets the 2nd element of that specific type. :nth-child counts among all siblings; :nth-of-type counts only siblings of the same element type.