Skip to content

CSS Advanced Selectors: Powerful Tools for Precise Element Targeting ​

The Essence of Selectors ​

CSS selectors are like an "addressing system" that tells the browser: "I want to apply styles to these specific elements." Basic selectors (class selectors, ID selectors, element selectors) are like painting all restaurants in a city with a color, while advanced selectors allow you to be precise down to "restaurants on Main Street with door numbers starting with 5."

Mastering advanced selectors means you can control page styles with less code and more elegance, without needing to add a class name to every element.

Attribute Selectors ​

Attribute selectors allow you to select elements based on their attributes and attribute values. This is particularly useful when working with forms, links, and similar scenarios.

Basic Attribute Selectors ​

css
/* Select all elements with a title attribute */
[title] {
  border-bottom: 1px dotted #999;
  cursor: help;
}

/* Select all input elements with a disabled attribute */
input[disabled] {
  background-color: #f5f5f5;
  cursor: not-allowed;
}

/* Select all form controls with a required attribute */
[required] {
  border-left: 3px solid #e74c3c;
}

Exact Attribute Value Match ​

css
/* Select input elements with type attribute value of "text" */
input[type="text"] {
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

/* Select links with target attribute value of "_blank" */
a[target="_blank"] {
  padding-right: 18px;
  background: url("external-link.svg") no-repeat right center;
  background-size: 14px 14px;
}

/* Select content in specific languages */
[lang="en"] {
  font-family: "Georgia", serif;
}

[lang="zh"] {
  font-family: "Microsoft YaHei", sans-serif;
}

Partial Attribute Value Matching ​

CSS provides multiple partial matching methods, each with specific use cases:

css
/* ^= begins with match: select links starting with "https://" */
a[href^="https://"]
{
  color: #27ae60;
}

a[href^="http://"]
{
  color: #f39c12;
}

/* $= ends with match: set different icons based on file extension */
a[href$=".pdf"] {
  padding-left: 20px;
  background: url("pdf-icon.svg") no-repeat left center;
}

a[href$=".zip"] {
  padding-left: 20px;
  background: url("zip-icon.svg") no-repeat left center;
}

a[href$=".doc"],
a[href$=".docx"] {
  padding-left: 20px;
  background: url("doc-icon.svg") no-repeat left center;
}

/* *= contains match: select elements with class containing "button" */
[class*="button"] {
  cursor: pointer;
  user-select: none;
}

/* ~= word list match: select elements with class attribute containing complete word "highlight" */
[class~="highlight"] {
  background-color: yellow;
}

/* |= prefix match: mainly used for language codes, such as lang="en" or lang="en-US" */
[lang|="en"] {
  quotes: '"' '"' "'" "'";
}

Practical Application Cases ​

css
/* Auto-identify email input box */
input[type="email"] {
  background-image: url("email-icon.svg");
  background-repeat: no-repeat;
  background-position: 10px center;
  background-size: 16px;
  padding-left: 35px;
}

/* Auto-identify external links */
a[href^="http"]:not([href*="mywebsite.com"])::after {
  content: " ↗";
  font-size: 0.8em;
  color: #3498db;
}

/* Unified style for download links */
a[download] {
  display: inline-flex;
  align-items: center;
  padding: 8px 16px;
  background-color: #3498db;
  color: white;
  text-decoration: none;
  border-radius: 4px;
  transition: background-color 0.3s;
}

a[download]:hover {
  background-color: #2980b9;
}

/* Form validation status */
input[aria-invalid="true"] {
  border-color: #e74c3c;
  background-color: #fadbd8;
}

input[aria-invalid="false"] {
  border-color: #27ae60;
  background-color: #d5f4e6;
}

Combinator Selectors ​

Combinator selectors define relationships between elements, allowing you to select elements based on DOM tree structure.

Descendant Selector (Space) ​

The descendant selector selects all descendant elements of an element, regardless of nesting depth:

css
/* Select all p elements inside article */
article p {
  line-height: 1.8;
  color: #333;
}

/* Select all links inside nav */
nav a {
  text-decoration: none;
  color: #2c3e50;
  transition: color 0.3s;
}

/* Multi-level nesting */
.sidebar .widget ul li a {
  display: block;
  padding: 5px 10px;
}

Use Case: When you want to apply styles to all specific elements inside a container, without caring about their specific nesting level.

Child Selector (>) ​

The child selector only selects direct child elements, not affecting deeper descendants:

css
/* Only select the direct child ul of nav */
nav > ul {
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Only select direct child li of .menu */
.menu > li {
  position: relative;
  padding: 10px 20px;
}

/* Comparing with descendant selector */
.sidebar ul li {
  /* Selects li at all levels */
  margin-left: 20px;
}

.sidebar > ul > li {
  /* Only selects first-level li */
  margin-left: 0;
  font-weight: bold;
}

Use Case: When you only want to affect direct children to avoid cascading styles. For example, in multi-level menus where only the first level needs styling.

Adjacent Sibling Selector (+) ​

The adjacent sibling selector selects the first sibling element immediately following an element:

css
/* First paragraph after a heading uses lead-in style */
h2 + p {
  font-size: 1.2em;
  font-style: italic;
  color: #555;
  margin-top: 0;
}

/* When checkbox is checked, change the style of the immediately following label */
input[type="checkbox"]:checked + label {
  color: #27ae60;
  font-weight: bold;
}

/* Error message immediately follows input box */
input:invalid + .error-message {
  display: block;
  color: #e74c3c;
  font-size: 0.9em;
  margin-top: 4px;
}

Use Case: Custom form styles, creating accordion effects, implementing special typography needs, etc.

General Sibling Selector (~) ​

The general sibling selector selects all sibling elements after an element (not necessarily adjacent):

css
/* After checked tab, all tab content styles */
.tab:checked ~ .tab-content {
  display: block;
}

/* All paragraphs after h2 */
h2 ~ p {
  text-indent: 2em;
}

/* Active state affects subsequent elements */
.item:hover ~ .item {
  opacity: 0.6;
}

Use Case: When you need to affect all subsequent sibling elements based on an element's state, such as implementing pure CSS tab switching.

Combinator Selectors in Practice ​

css
/* Complex navigation menu */
nav > ul > li {
  position: relative;
}

/* Secondary menu hidden by default */
nav > ul > li > ul {
  position: absolute;
  top: 100%;
  left: 0;
  display: none;
  background: white;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

/* Display on hover */
nav > ul > li:hover > ul {
  display: block;
}

/* Breadcrumb navigation */
.breadcrumb li + li::before {
  content: "/";
  padding: 0 8px;
  color: #999;
}

/* Card list layout */
.card-grid > .card {
  background: white;
  border-radius: 8px;
  padding: 20px;
}

.card-grid > .card + .card {
  margin-top: 20px;
}

/* Form group */
.form-group input:focus ~ label {
  color: #3498db;
  transform: translateY(-20px);
  font-size: 12px;
}

Universal Selector and Combinatorial Usage ​

The universal selector * can select all elements. Although it has poor performance when used alone, it's very powerful when combined with other selectors:

css
/* Reset margin and padding for all elements */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* Select all direct children of .container */
.container > * {
  margin-bottom: 20px;
}

.container > *:last-child {
  margin-bottom: 0;
}

/* Select all elements inside article */
article * {
  max-width: 100%;
}

/* Classic clearfix method */
.clearfix::after {
  content: "";
  display: table;
  clear: both;
}

/* Unified style for all form elements */
form * {
  font-family: inherit;
}

Selector Performance Considerations ​

Browsers parse CSS selectors from right to left, which means more specific selectors perform better:

css
/* Poor performance: browser needs to traverse all a tags */
div div div a {
  color: blue;
}

/* Better performance: directly targets .nav-link */
.nav-link {
  color: blue;
}

/* Avoid using wildcard as the key selector */
/* Bad */
* .widget {
  margin: 10px;
}

/* Good */
.widget {
  margin: 10px;
}

Best Practices:

  • Try to use class selectors, avoid overly deep nesting
  • Avoid using the universal selector as the key selector (rightmost selector)
  • ID selectors have the best performance but reduce reusability
  • Keep selectors concise, generally no more than 3-4 levels

Practical Techniques ​

Smart Form Styling ​

css
/* Auto-adjust based on input type */
input[type="number"],
input[type="tel"] {
  text-align: right;
}

input[type="search"] {
  border-radius: 20px;
  padding-left: 15px;
}

/* Placeholder style */
input::placeholder {
  color: #999;
  font-style: italic;
}

/* Autofill style */
input:-webkit-autofill {
  -webkit-box-shadow: 0 0 0 1000px white inset;
}

Responsive Image Handling ​

css
/* All images responsive */
img {
  max-width: 100%;
  height: auto;
}

/* Images with specific aspect ratio */
img[width][height] {
  aspect-ratio: attr(width) / attr(height);
}

/* Special handling for SVG images */
img[src$=".svg"] {
  width: 100%;
  height: auto;
}
css
/* Hide navigation and sidebar when printing */
@media print {
  nav,
  aside,
  .no-print {
    display: none;
  }

  /* Show URL after links */
  a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 0.8em;
    color: #666;
  }
}

Summary ​

Advanced selectors are one of the core capabilities of CSS. By properly using attribute selectors and combinator selectors, you can write more concise and maintainable style code.

Key Points:

  • Attribute Selectors: Provide precise selection capabilities based on HTML attributes
    • Basic selection: [attr] selects elements with a specific attribute
    • Exact match: [attr="value"] selects elements whose attribute value matches exactly
    • Partial match: ^= (begins with), $= (ends with), *= (contains) provide flexible matching methods
  • Combinator Selectors: Select elements based on DOM tree structure relationships
    • Descendant selector (space): selects all descendant elements
    • Child selector (>): only selects direct child elements
    • Adjacent sibling selector (+): selects the first immediately following sibling
    • General sibling selector (~): selects all following sibling elements
  • Performance Optimization: Keep selectors concise, avoid overly deep nesting, use universal selector cautiously
  • Practical Scenarios: Form beautification, link identification, print styles, responsive images, etc.