question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

@extend should unify parent selectors that share a simple selector

See original GitHub issue

Hi! Sorry to (maybe) resurrect a long-dead issue, but I’m having the same problem as #1428, #1052 and others. I am attempting to do the same thing as the OP of #1052: create a system where styles are abstracted from selectors, so we can:

  • use the same styles everywhere
  • style differently-structured across projects—markup we can’t necessarily change

Placeholders for the styles—@extended in a layer of selectors—was working well until I ran into the issue with how it combines multiple descendant selectors. (For example: output I like \ output I don’t like ) I’ve tried using descendants in the placeholder layer and using them in the selector layer, but the result is the same: at some point, I (usually inadvertently) make it so the relationship between the placeholders doesn’t match with the selectors’, and I start to get selectors like .thing.state .thing.other-state .part when I need .thing.state.other-state .part.

I already know that I can work around this by creating a flat structure of placeholders/mixins with every permutation of states/styles encoded into their names, but I’m reluctant to settle for that—especially when my setup with placeholders for each style/state almost works. (I’d really like to avoid forcing my teammates to remember/reproduce long names of states, parts, and/or variants in the correct order, e.g. %button-small-focus-active-background.)

The team’s responses to other issues in this vein make me think it’d be fruitless to ask for a change to placeholders or @extend, since our mental models about what those things should be don’t match up. Maybe some kind of Sass-specific combinator could solve the problem, or a flag on @extend that makes it…dumber?

Hopefully at the very least, you can see what I’m looking to solve for. Let me know if I need to clarify. Thanks!

Issue Analytics

  • State:open
  • Created 5 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
nex3commented, Oct 2, 2018

You’re actually running into a different problem than the issues you cite. Those issues are about Sass generating too many selectors, which it has to do because it’s unaware of how the HTML that’s being styled is structured. Your issue is that it’s not generating enough selectors; specifically, it’s not generating .thing.state.other-state .part.

The reason for this in general is that Sass trims selectors it judges unlikely to match real-world HTML, in order to avoid bloating the CSS and annoying even more people than those who filed the issues you linked. For example, the most theoretically-safe way to expand the selectors for

.a %b {x: y}
.c .d {@extend %b}

would be

.a .c .d, .c .a .d, .a.c .d {
  x: y;
}

but Sass assumes that you probably aren’t going to be putting class="a c" on the same element, and uses that to generate less CSS. (Users like those who filed #1428 and #1052 wish it would go even further and only generate one of .a .c .d and .c .a .d, but there’s no way for it to know which one to choose.)

In your specific case, though, .a is .custom-text-field:focus-within and .b is .custom-text-field.invalid. These two compound selectors share the simple selector .custom-text-field, which is a good reason to believe that they’ll apply to the same element, so Sass’s heuristic to delete the unified selector fails.

I think this is worth tweaking the extension algorithm for. Specifically, I think we should generate the unified parent selector if and only if the two selectors being unified share at least one simple selector. For backwards compatibility, it should be generated in addition to the un-unified versions.

0reactions
nategreencommented, Jun 20, 2019

Sorry for the long delay before circling back on this, haven’t had time to try and dig into editing the spec but we also don’t need/want this as urgently as 6 months ago; ran into performance/filesize problems after all, so our approach has changed and doesn’t rely on @extend anymore.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Sass: @extend
You can directly access Sass's intelligent unification using selector functions! The selector.unify() function returns a selector that matches the intersection ...
Read more >
Sass: How to merge nested import selectors with parent ...
modal , but I want to have .my-selector.modal . I want to avoid having to copy-paste the style rules. If I can somehow...
Read more >
Selector Functions in Sass | Explained - Linux Hint
This function makes use of the @extend rule to extend the provided selector. The @extend rule is stated as follows. @extend rule. #{$extender}...
Read more >
Top 6 Types of SASS Selector Functions - eduCBA
selector -append; selector-extend; selector-nest; selector-replace; selector-unify; simple-selectors. The following are the examples that depict the usage of ...
Read more >
USS selectors - Unity - Manual
USS supports a set of simple selectors that are analogous, but not identical, to simple selectors in CSS. A simple selector matches elements...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found