Select All Classes Containing A Word

Master CSS attribute selectors for class matching. Learn to use [class*="value"], [class^="value"], and [class$="value"] syntax with practical examples for modern web development.

CSS attribute selectors are among the most powerful yet underutilized tools in a frontend developer's toolkit. When you need to target elements based on class names that contain specific words or patterns--without adding new classes to your HTML--the [class*="value"] syntax gives you precise control.

Whether you're styling dynamically generated components in a React/Next.js application, applying consistent thememing across a design system, or targeting elements with BEM-style naming conventions, understanding how to select classes containing specific substrings is essential. This guide covers everything you need to know about CSS attribute selectors for class matching, from basic syntax to advanced performance optimization.

What You'll Learn

Substring Matching

Use [class*="value"] to find classes containing specific words anywhere in the class attribute.

Prefix & Suffix Matching

Master [class^="value"] for starts-with and [class$="value"] for ends-with class matching.

Case Sensitivity Control

Handle case-insensitive matching with the i flag for flexible class targeting.

Performance Optimization

Write efficient attribute selectors that don't impact page rendering performance.

Understanding CSS Attribute Selectors for Class Matching

What Are CSS Attribute Selectors?

CSS attribute selectors are patterns that match elements based on the presence or value of HTML attributes. While they're commonly used with href, src, and data-* attributes, attribute selectors are equally powerful when applied to the class attribute. Unlike class selectors that match exact class names (.my-class), attribute selectors can match partial strings within the class attribute value, making them invaluable for pattern-based styling.

The syntax uses square brackets to enclose the attribute name and an operator that defines the matching behavior:

/* Basic attribute presence */
[class] { }

/* Exact value match */
[class="my-class"] { }

/* Whitespace-separated word match */
[class~="my-class"] { }

/* Substring contains match (wildcard) */
[class*="my"] { }

/* Starts with match */
[class^="my"] { }

/* Ends with match */
[class$="my"] { }

Why Use Attribute Selectors for Classes?

Modern frontend frameworks like React and Next.js often generate class names dynamically, especially when using CSS-in-JS solutions, CSS modules, or utility-first frameworks like Tailwind. Rather than adding wrapper classes or modifying component logic, attribute selectors provide a CSS-native way to target elements based on naming patterns.

Attribute selectors are particularly useful in several scenarios: styling BEM-style classes that follow naming conventions (.block__element--modifier), targeting dynamically generated class names from build tools, applying theme-related styles across multiple components without redundant classes, and creating style overrides in design systems where you don't control the source classes. See our guide on CSS best practices for more optimization techniques.

The Contains Selector: Targeting Classes That Include A Word

The [class*="value"] Syntax Explained

The [class*="value"] selector matches any element whose class attribute contains the specified substring "value" anywhere within it. The asterisk operator (*) performs a substring search, meaning it will match if the search term appears at the beginning, middle, or end of any class name in the element's class attribute. This makes it the most versatile option for finding classes that "contain" a specific word or character sequence.

The syntax is straightforward:

/* Selects elements with class containing "btn" */
[class*="btn"] {
 display: inline-flex;
 align-items: center;
 justify-content: center;
 padding: 0.75rem 1.5rem;
 border-radius: 0.375rem;
 font-weight: 500;
 transition: all 0.2s ease;
}

This selector would match elements with classes like btn, button, btn-primary, submit-btn, btn-secondary, or even nonrelated-btn-class. The matching is case-sensitive by default, so [class*="btn"] would not match classes containing "Btn" or "BTN" without additional consideration.

Button Component System with Attribute Selectors
1/* Base button styles for all buttons */2[class*="btn"] {3 display: inline-flex;4 align-items: center;5 justify-content: center;6 padding: 0.75rem 1.5rem;7 border-radius: 0.375rem;8 font-weight: 500;9 transition: all 0.2s ease;10}11 12/* Primary button variant */13[class*="btn-primary"] {14 background-color: #3b82f6;15 color: white;16}17 18/* Secondary button variant */19[class*="btn-secondary"] {20 background-color: #64748b;21 color: white;22}23 24/* Danger/destructive actions */25[class*="btn-danger"] {26 background-color: #ef4444;27 color: white;28}

Related Selectors: Starts-With and Ends-With

The [class^="value"] Prefix Selector

The [class^="value"] selector (caret operator) matches elements whose class attribute value begins with the specified string. This is useful when your naming convention puts distinguishing information at the start of class names, such as with BEM methodology where the block name typically comes first.

/* Match classes starting with "card-" */
[class^="card-"] {
 border: 1px solid #e5e7eb;
 border-radius: 0.5rem;
}

/* Match classes starting with "icon-" */
[class^="icon-"] {
 display: inline-flex;
 align-items: center;
}

/* Match classes starting with "status-" */
[class^="status-"] {
 padding: 0.25rem 0.75rem;
 border-radius: 9999px;
 font-size: 0.875rem;
}

When combining with classes that contain hyphens or other separators, be aware that [class^="card"] will match card-wrapper but not my-card-element since the class attribute value must start with the specified string.

The [class$="value"] Suffix Selector

The [class$="value"] selector (dollar operator) matches elements whose class attribute ends with the specified string. This pattern is particularly useful when your naming convention puts distinguishing information at the end of class names, such as modifier names or variant indicators.

/* Match classes ending with "-disabled" */
[class$="-disabled"] {
 opacity: 0.5;
 pointer-events: none;
}

/* Match classes ending with "-selected" */
[class$="-selected"] {
 background-color: #dbeafe;
 border-color: #3b82f6;
}

/* Match classes ending with "-error" */
[class$="-error"] {
 color: #ef4444;
 border-color: #ef4444;
}

Choosing the Right Selector

SelectorUse WhenExample Match
[class*="btn"]Word appears anywherebtn, submit-btn, my-button
[class^="btn-"]Word is at the start (with separator)btn-primary, btn-secondary
[class$="-primary"]Word is at the end (with separator)action-primary, tag-primary

For BEM-style naming, combining prefix and suffix selectors provides the most precise matching. For example, [class^="btn-"][class$="-primary"] would match btn-large-primary but not btn-primary-large or primary-btn-secondary. Explore more advanced CSS techniques in our guide on CSS painting API.

Case Sensitivity and Advanced Matching

The Case-Insensitive Flag

By default, CSS attribute selectors are case-sensitive when matching attribute values. For class names, this means [class*="btn"] won't match elements with classes like BTN, Btn, or BUTTON. However, you can add the i flag before the closing bracket to make the comparison case-insensitive:

/* Case-sensitive (default) */
[class*="btn"] { }

/* Case-insensitive match */
[class*="btn" i] {
 /* Matches btn, BTN, Btn, BuTn, etc. */
}

This flag is particularly useful when working with third-party libraries or components that might generate class names with varying capitalization, or when you want to write selectors that are more forgiving of naming inconsistencies.

Combining with Other Selectors

Attribute selectors can be combined with any other CSS selector to increase specificity or scope:

/* Direct children of a container */
.container > [class*="card"] {
 margin-bottom: 1rem;
}

/* Within a specific section */
section.features [class*="feature-"] {
 padding: 2rem;
}

/* With pseudo-classes */
[class*="btn"]:hover {
 transform: translateY(-1px);
}

[class*="btn"]:disabled {
 opacity: 0.6;
}

/* With pseudo-elements */
[class*="icon-"]::before {
 content: "";
 width: 1em;
 height: 1em;
}

Performance Considerations and Best Practices

Browser Rendering Performance

CSS selectors are evaluated from right to left by browsers, meaning the key selector (the rightmost part) determines which elements are initially considered for rule matching. For attribute selectors, this means [class*="btn"] asks the browser to check every element on the page (or within the rule's scope) to see if its class attribute contains "btn". While modern browsers are highly optimized for this, overly broad attribute selectors can impact rendering performance, especially on pages with many elements.

Best Practices:

  1. Scope your selectors: Instead of [class*="btn"] globally, scope it to a specific container like .button-group [class*="btn"]

  2. Be specific when possible: [class*="btn-primary"] is more specific than [class*="btn"], potentially matching fewer elements

  3. Consider the DOM structure: If buttons are always within a specific container, include that container in your selector

  4. Avoid over-matching: [class*=""] (empty string) would match every element with a class attribute, which should never be used

Maintainability Guidelines

While attribute selectors provide flexibility, they can also make CSS harder to maintain if overused or used inappropriately:

  1. Document your patterns: When using attribute selectors for class matching, document the naming conventions they expect

  2. Prefer explicit classes when you control HTML: If you can add a specific class, do so--attribute selectors are a fallback for when you can't

  3. Use with CSS-in-JS and CSS modules: These tools generate unique class names, so attribute selectors work well with their deterministic naming

  4. Combine with meaningful classes: Attribute selectors can supplement rather than replace semantic class names

Common Use Cases in Modern Web Development

Styling Dynamic Components in Next.js/React

When building components with dynamic class generation, attribute selectors provide styling flexibility without modifying component logic:

/* Target all variant buttons regardless of component */
[class*="variant-primary"] {
 background-color: #3b82f6;
 color: white;
}

/* Theme-aware component styling */
[class*="theme-dark"] {
 --bg-primary: #1f2937;
 --text-primary: #f9fafb;
}

/* Responsive component targeting */
[class*="breakpoint-md"] {
 flex-direction: row;
}

Design System Implementation

Design systems often use attribute selectors to apply consistent tokens and patterns:

/* Spacing token application */
[class*="space-"] {
 padding: var(--spacing);
}

/* Color token application */
[class*="color-"] {
 color: var(--color);
}

/* Typography scale */
[class*="text-"] {
 font-size: var(--font-size);
 line-height: var(--line-height);
}

BEM Pattern Matching

For projects using BEM methodology, attribute selectors can target specific elements and modifiers:

/* All elements within blocks */
[class*="__"] {
 /* Element styles */
}

/* All modifiers */
[class*="--"] {
 /* Modifier styles */
}

/* Specific block's elements */
[class*="card__title"],
[class*="card__description"] {
 font-family: system-ui, sans-serif;
}

/* Specific block's modifiers */
[class*="card--featured"] {
 border-color: #3b82f6;
 box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
}

Learn how these patterns integrate with modern frontend workflows in our guide on custom functions and mixins.

Complete Button Component System Example
1/* Base button styles */2[class*="btn"] {3 display: inline-flex;4 align-items: center;5 justify-content: center;6 padding: 0.75rem 1.5rem;7 border-radius: 0.375rem;8 font-weight: 500;9 cursor: pointer;10 transition: all 0.2s ease;11 border: none;12}13 14/* Size variants */15[class*="-large"] {16 padding: 1rem 2rem;17 font-size: 1.125rem;18}19 20[class*="-small"] {21 padding: 0.5rem 1rem;22 font-size: 0.875rem;23}24 25[class*="-medium"] {26 padding: 0.75rem 1.5rem;27 font-size: 1rem;28}29 30/* Color variants */31[class*="primary"] {32 background-color: #3b82f6;33 color: white;34}35 36[class*="secondary"] {37 background-color: #64748b;38 color: white;39}40 41[class*="danger"] {42 background-color: #ef4444;43 color: white;44}45 46[class*="ghost"] {47 background-color: transparent;48 color: #3b82f6;49 border: 1px solid #3b82f6;50}51 52/* Interactive states */53[class*="btn"]:hover {54 transform: translateY(-1px);55 box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);56}57 58[class*="btn"]:active {59 transform: translateY(0);60}

Frequently Asked Questions

Summary and Key Takeaways

CSS attribute selectors for class matching--particularly the [class*="value"] syntax--provide powerful pattern-based targeting capabilities that complement traditional class selectors. The contains selector (*=) matches any class attribute containing the specified substring, while starts-with (^=) and ends-with ($=) provide prefix and suffix matching respectively. Case sensitivity can be controlled with the i flag, and selectors can be combined for more precise matching.

When implementing these selectors in modern web applications, consider performance implications by scoping selectors appropriately, maintain clarity by documenting naming conventions, and use attribute selectors strategically to supplement rather than replace semantic class names. Whether you're working with Next.js, React, or vanilla HTML/CSS, understanding these selectors gives you additional flexibility for styling dynamic components and maintaining scalable stylesheets.

For more advanced CSS techniques, explore our comprehensive guide on containing block positioning and how it relates to modern layout techniques.

Need Help Building Modern Web Applications?

Our team specializes in React, Next.js, and modern CSS techniques for performant, scalable websites.