0
0
CSSmarkup~15 mins

Starts-with and ends-with selectors in CSS - Deep Dive

Choose your learning style9 modes available
Overview - Starts-with and ends-with selectors
What is it?
Starts-with and ends-with selectors are special ways in CSS to pick HTML elements based on the beginning or ending of their attribute values. Instead of selecting elements by exact matches, these selectors let you find elements whose attribute values start or end with certain text. This helps style groups of elements that share similar attribute patterns without adding extra classes or IDs. They make styling more flexible and powerful.
Why it matters
Without these selectors, you would need to add many extra classes or IDs to style elements that share similar attribute patterns, which can be time-consuming and messy. These selectors save time and keep HTML cleaner by letting CSS do the work of finding elements based on attribute value patterns. This makes websites easier to maintain and update, especially when dealing with many similar elements.
Where it fits
Before learning these selectors, you should understand basic CSS selectors like element, class, and ID selectors, and attribute selectors with exact matches. After mastering starts-with and ends-with selectors, you can learn about more advanced attribute selectors like contains selectors and complex combinators for precise styling.
Mental Model
Core Idea
Starts-with and ends-with selectors let CSS find elements by matching the beginning or end of their attribute values, like searching for words that start or end with certain letters.
Think of it like...
Imagine sorting mail by looking at the first or last letters of the recipient's name on the envelope. You pick all letters starting with 'A' or ending with 'son' without opening each one.
Attribute selectors overview:

┌───────────────────────────────┐
│ [attr^="value"]  Starts-with  │  ← Selects elements whose attr starts with "value"
│ [attr$="value"]  Ends-with    │  ← Selects elements whose attr ends with "value"
└───────────────────────────────┘

Example:

[title^="Hello"] → elements with title starting with "Hello"
[href$=".pdf"] → elements with href ending with ".pdf"
Build-Up - 7 Steps
1
FoundationBasic attribute selectors in CSS
🤔
Concept: Learn how CSS selects elements by matching exact attribute values.
CSS attribute selectors let you pick elements based on their attributes. For example, [type="text"] selects all elements with type attribute exactly equal to "text". This is useful but only matches exact values.
Result
You can style all input boxes with type="text" by writing input[type="text"] { color: blue; }.
Understanding exact attribute matching is the base for more flexible selectors like starts-with and ends-with.
2
FoundationWhat are starts-with and ends-with selectors?
🤔
Concept: Introduce the ^ and $ symbols in attribute selectors to match beginnings and endings.
Starts-with selector uses [attr^="value"] to select elements whose attribute starts with "value". Ends-with selector uses [attr$="value"] to select elements whose attribute ends with "value". For example, a[href^="https"] selects links starting with https, and img[src$=".png"] selects images ending with .png.
Result
You can style all secure links or all PNG images without extra classes.
These selectors let you find groups of elements sharing attribute patterns, making CSS more powerful and flexible.
3
IntermediateUsing starts-with selector in practice
🤔Before reading on: do you think [class^="btn"] selects elements with class exactly 'btn' or any class starting with 'btn'? Commit to your answer.
Concept: Learn how starts-with selector matches any attribute value beginning with the given string, even if longer.
The selector [class^="btn"] matches elements with class="btn", class="btn-primary", or class="btn-large" because their class attribute starts with "btn". This helps style all button variants at once.
Result
All elements with classes starting with 'btn' get the styles, even if the class has extra words.
Knowing starts-with matches prefixes, not exact values, helps you target groups of related elements efficiently.
4
IntermediateUsing ends-with selector in practice
🤔Before reading on: does [href$='.com'] select links ending exactly with '.com' or also '.com/page'? Commit to your answer.
Concept: Understand ends-with selector matches attribute values that finish with the specified string, regardless of what comes before.
The selector [href$='.com'] matches links with href="https://example.com" but does NOT match href="https://example.com/page" because the attribute value must literally end with '.com'.
Result
Only links whose href attribute ends exactly with '.com' get styled.
Ends-with selector matches the exact ending of attribute values, so partial matches inside the string don't count.
5
IntermediateCombining starts-with and ends-with selectors
🤔Before reading on: can you combine [attr^='start'][attr$='end'] to select elements? What does it mean? Commit to your answer.
Concept: Learn how to combine selectors to find elements whose attribute values start and end with specific strings.
You can write selectors like [data-id^='user'][data-id$='123'] to select elements whose data-id attribute starts with 'user' and ends with '123'. This narrows down the selection to very specific patterns.
Result
Only elements matching both conditions get styled, allowing precise targeting.
Combining selectors lets you create powerful filters for styling elements with complex attribute patterns.
6
AdvancedPerformance considerations of attribute selectors
🤔Before reading on: do you think starts-with and ends-with selectors are faster or slower than class selectors? Commit to your answer.
Concept: Understand how browsers process these selectors and their impact on page performance.
Browsers match class and ID selectors very fast because they use optimized lookup. Attribute selectors like starts-with and ends-with require checking attribute values for each element, which can be slower on large pages. Use them wisely and avoid overusing in performance-critical parts.
Result
Using these selectors on many elements may slow down rendering slightly compared to simple class selectors.
Knowing performance tradeoffs helps you write efficient CSS that balances flexibility and speed.
7
ExpertLimitations and quirks of starts-with and ends-with selectors
🤔Before reading on: do you think these selectors work on all attributes including style and class lists? Commit to your answer.
Concept: Explore edge cases and limitations in how these selectors behave with certain attributes and dynamic changes.
Starts-with and ends-with selectors work on attribute values as strings. For class attributes, which can have multiple space-separated classes, these selectors match the whole attribute string, not individual classes. So [class^='btn'] matches only if the entire class attribute starts with 'btn', not if one class inside does. Also, dynamic changes to attributes may not trigger CSS updates immediately in some browsers.
Result
You may get unexpected results if you assume these selectors work like class selectors on multi-class attributes.
Understanding these quirks prevents bugs and helps you choose the right selector for your needs.
Under the Hood
When the browser applies CSS, it parses selectors and matches them against the DOM elements. For starts-with ([attr^="value"]) and ends-with ([attr$="value"]) selectors, the browser reads the attribute's string value and checks if it begins or ends with the specified substring. This check happens for each element with that attribute. The matching is case-sensitive and literal. The browser uses efficient string comparison algorithms internally but still must check each candidate element's attribute value.
Why designed this way?
These selectors were introduced to provide more flexible styling options without requiring extra markup or JavaScript. Exact attribute matching was too limited for many real-world cases. The design balances expressiveness and performance by limiting matches to string starts or ends, which are simpler to check than complex patterns. Alternatives like regular expressions were avoided for performance and complexity reasons.
CSS Selector Matching Flow:

┌───────────────┐
│ CSS Selector  │
│ [attr^="val"]│
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Browser scans │
│ DOM elements  │
└──────┬────────┘
       │
       ▼
┌─────────────────────────────┐
│ For each element with attr:  │
│ Check if attr value starts  │
│ with "val" (string compare)│
└──────┬──────────────────────┘
       │
       ▼
┌───────────────┐
│ Match or skip │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does [class^='btn'] select elements with class='btn-primary' or only class='btn' exactly? Commit to yes or no.
Common Belief:People often think [class^='btn'] selects any element with a class that starts with 'btn', including multiple classes.
Tap to reveal reality
Reality:It matches only if the entire class attribute string starts with 'btn'. If the element has multiple classes and the first class does not start with 'btn', it won't match.
Why it matters:This misunderstanding leads to CSS not applying as expected, causing styling bugs that are hard to debug.
Quick: Does [href$='.com'] match 'https://example.com/page'? Commit to yes or no.
Common Belief:Many believe ends-with selector matches any attribute containing the string at the end of a segment, even if followed by more text.
Tap to reveal reality
Reality:It matches only if the entire attribute value ends exactly with '.com'. 'https://example.com/page' does not match because it ends with '/page'.
Why it matters:Incorrect assumptions cause selectors to miss elements, leading to incomplete styling.
Quick: Are starts-with and ends-with selectors case-insensitive? Commit to yes or no.
Common Belief:Some think these selectors ignore case when matching attribute values.
Tap to reveal reality
Reality:They are case-sensitive by default, so 'Btn' and 'btn' are different.
Why it matters:Ignoring case sensitivity causes unexpected misses or matches, breaking design consistency.
Quick: Do these selectors work on dynamically changed attributes immediately? Commit to yes or no.
Common Belief:People assume CSS updates instantly when attribute values change dynamically.
Tap to reveal reality
Reality:Some browsers delay or do not update styles immediately when attributes change dynamically, especially for complex selectors.
Why it matters:This can cause UI glitches or stale styles in dynamic web apps.
Expert Zone
1
Starts-with and ends-with selectors operate on the full attribute string, not on tokenized or split values like class lists, which can cause subtle mismatches.
2
Browsers optimize common selectors like classes and IDs heavily, but attribute selectors still require scanning attribute values, so overusing them can degrade performance on large pages.
3
Combining multiple attribute selectors can create very specific matches but also increases selector complexity and matching cost, affecting rendering speed.
When NOT to use
Avoid using starts-with and ends-with selectors for styling large numbers of elements repeatedly or in performance-critical parts; prefer classes or IDs instead. Also, do not rely on them for matching individual classes within a multi-class attribute; use class selectors for that. For complex pattern matching, consider JavaScript or preprocessors instead.
Production Patterns
In real-world projects, these selectors are often used for styling elements with predictable attribute patterns, like buttons with data attributes, links to certain domains, or images with specific file extensions. They help reduce extra markup and keep CSS modular. They are also used in component libraries to style variants without adding many classes.
Connections
Regular Expressions
Starts-with and ends-with selectors are simpler, limited forms of pattern matching similar to regex anchors ^ and $.
Understanding regex anchors helps grasp why these selectors only match beginnings or ends, not arbitrary substrings.
Database LIKE Queries
These selectors resemble SQL LIKE queries with patterns like 'value%' (starts-with) and '%value' (ends-with).
Knowing how databases filter strings with LIKE helps understand CSS attribute selector patterns and their limitations.
Human Language Prefixes and Suffixes
Starts-with and ends-with selectors work like prefixes and suffixes in words, identifying parts at the start or end.
Recognizing this linguistic pattern clarifies why these selectors are useful for grouping elements by attribute 'word parts'.
Common Pitfalls
#1Assuming [class^='btn'] matches any element with a class containing 'btn' anywhere.
Wrong approach: with CSS [class^='btn'] { color: red; } expecting red text.
Correct approach: with CSS [class^='btn'] { color: red; } to match because class attribute starts with 'btn'.
Root cause:Misunderstanding that the selector matches the entire attribute string from the start, not individual classes inside.
#2Using [href$='.com'] to style all links to '.com' domains including subpages.
Wrong approach:Link with CSS [href$='.com'] { font-weight: bold; } expecting bold text.
Correct approach:Link with CSS [href$='.com'] { font-weight: bold; } which matches only exact '.com' endings.
Root cause:Assuming ends-with selector matches substrings inside the attribute rather than the literal end.
#3Expecting CSS to update styles immediately when attribute values change dynamically.
Wrong approach:JavaScript changes element.setAttribute('data-id', 'newValue') and expects CSS [data-id^='new'] to apply instantly.
Correct approach:After changing attribute, force reflow or use classes for dynamic styling to ensure immediate CSS update.
Root cause:Not knowing browser rendering optimizations may delay or skip style recalculations for attribute changes.
Key Takeaways
Starts-with ([attr^='value']) and ends-with ([attr$='value']) selectors let you style elements based on the beginning or end of attribute values, adding flexible targeting beyond exact matches.
These selectors match the entire attribute string from start or end, not parts inside multi-valued attributes like class lists, which can cause unexpected results.
They are case-sensitive and literal, so exact letter casing and full endings matter for matching.
While powerful, these selectors can be slower than simple class or ID selectors, so use them thoughtfully to avoid performance issues.
Understanding their behavior and limitations helps you write cleaner, more maintainable CSS and avoid common styling bugs.