selector.replace() belongs to the built-in sass:selector module. It returns a copy of a selector with one piece swapped for another, using the same intelligent unification as @extend. This page covers the three arguments, vs selector.extend, and five compiled examples.
01
Concept
Swap, don’t keep
02
Module
@use "sass:selector"
03
Returns
Selector value
04
Args
sel, original, replacement
05
vs extend
Swap vs add-on
06
Practice
5 examples
Concept
What Is selector.replace()?
Official docs: returns a copy of $selector with all instances of $original replaced by $replacement. It uses the @extend rule’s intelligent unification so the replacement fits into the surrounding selector. If $selector never contains $original, the value is returned unchanged.
Three arguments: the selector to rewrite, what to find, and what to put instead.
Placeholder selectors are allowed; parent selectors (&) are not.
See also selector.extend() when you want to keep the original and add a form.
💡
Beginner tip
Think find-and-replace for selectors: a.disabled with a → .link becomes .disabled.link—the a is gone, .disabled stays.
Foundation
📝 Syntax
styles.scss
@use "sass:selector";
// Recommended
selector.replace($selector, $original, $replacement)
// Legacy global name
selector-replace($selector, $original, $replacement)
Parameters
Parameter
Type
Required
Description
$selector
Selector
Yes
Selector to rewrite.
$original
Selector
Yes
The piece to find and remove/replace.
$replacement
Selector
Yes
What to put in place of $original.
Return value
Type
Result
Selector
Replaced selector (or the original if $original was absent)
Modules
📦 Loading sass:selector
styles.scss
// Recommended — namespaced (Dart Sass 1.23+)
@use "sass:selector";
$sel: selector.replace("a.disabled", "a", ".link");
// .disabled.link
// Optional — bring members into scope
@use "sass:selector" as *;
$sel: replace("a.disabled", "a", ".link");
// Legacy global
$sel: selector-replace("a.disabled", "a", ".link");
Unlike extend, the first sample does not keep a.disabled—only the replaced form remains. Dart Sass may print compound classes in a different simple-selector order (for example .disabled.link); matching is the same as .link.disabled.
Compare
⚖️ replace vs extend
Helper
Typical result for a.disabled / a → .link
Use when
selector.replace
.disabled.link
Swap the original piece out completely
selector.extend
a.disabled, .disabled.link
Keep the original and add the extender form
Support
🛠 Compatibility
This is about Sass compilers, not browsers. The rewrite runs at compile time.
Implementation
replace
Dart Sass
Yes — prefer selector.replace (module since 1.23.0)
LibSass
Legacy selector-replace may exist; no @use "sass:selector"
Ruby Sass
Legacy selector-replace may exist; no @use "sass:selector"
Prefer current Dart Sass so the module API matches the official docs.
When $original is present, it is swapped out (not kept). When it is missing, nothing changes. Complex replacements can expand into more than one complex selector.
Example 2 — Build Rule Selectors
Interpolate the replaced result into a real style rule.
Finds $original, drops it, and integrates $replacement.
Compile
3
Interpolate into rules
Use #{…} as the selector for a style block.
Emit
4
✓
CSS ships
Browsers only see finished selectors like .disabled.link.
Watch Out
⚠️ Common Pitfalls
Confusing with extend — replace drops the original; extend keeps it.
Parent selectors — & is not allowed in these arguments.
Wrong argument order — remember selector, then original, then replacement.
Forgetting interpolation — wrap results in #{…} to use them as rule selectors.
Expecting plain string replace — this is selector unification, not text search.
Pro Tips
💡 Best Practices
✅ Do
Use @use "sass:selector" and selector.replace()
Use it when you want a full swap
Prefer extend when keeping the original matters
Pass clean selectors without parent &
Prefer Dart Sass 1.23+
❌ Don’t
Pass parent selectors (&)
Assume every miss is an error—unchanged return is intentional
Treat it like JavaScript string replace
Expect browsers to evaluate the call
Rely on LibSass for the module API
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about selector.replace()
Swap selector pieces with @extend-style unification—the original match is dropped.
5
Core concepts
📝01
API
replace(sel, old, new)
Call
📦02
Module
sass:selector
@use
🔗03
Result
original dropped
Output
📚04
Miss
returns as-is
Detail
✓05
Alt
extend to keep
Compare
❓ Frequently Asked Questions
selector.replace($selector, $original, $replacement) returns a copy of $selector with all instances of $original replaced by $replacement, using @extend-style intelligent unification. Example: replace("a.disabled", "a", ".link") becomes .disabled.link.
replace swaps the original out. extend keeps the original and adds the extender form. Same args: replace → .disabled.link; extend → a.disabled, .disabled.link.
Official docs: if $selector does not contain $original, the function returns $selector unchanged.
No. Arguments may contain placeholder selectors, but not parent selectors.
Yes. selector-replace($selector, $original, $replacement) is the legacy global name. Prefer selector.replace after @use "sass:selector".
Dart Sass 1.23+. LibSass and Ruby Sass do not load sass:selector with @use; they may still offer the legacy global name.
Did you know?
Official Sass docs say selector.replace uses the same intelligent unification as the @extend rule—so complex replacements can produce multiple unified selectors, not just a simple text swap.
selector.replace() rewrites selectors by swapping $original for $replacement with @extend-style unification. Prefer selector.extend when you need to keep the original, and avoid parent selectors.