css-modules/css-modules-loader-core

Using composes with psuedo-selectors

ryngonzalez opened this issue · 2 comments

Is there anyway to use composes with a psuedo-selector? For instance, like this:

.item:last-child {
  composes: no-border from 'shared/styles.css';
}

No, that's not possible. See css-modules/css-modules#33 (comment) for a bit more discussion, but the short answer is that CSS Modules adds extra classes to an element, but not dynamically, so there's no way for it to only add that extra class to the last .item in a list, or anything. You can compose something that has pseudo-selectors though:

/* shared/styles.css */

.normal-border {
  border: 1px solid;
}

.no-border-on-last:last-child {
  border: none;
}
.item {
  composes: normal-border no-border-on-last from 'shared/styles.css';
}

This feels weird coming from Sass, I'll admit, but lets you break up the behaviour in whichever way makes sense. In fact, in shared/styles.css you could also add do something like this:

.normal-border {
  border: 1px solid;
}

.list-borders {
  composes: normal-border;
}
.list-borders:last-child {
  border: none;
}

Then you've wrapped up something complex (borders on all but last) into a single name list-borders that you can reuse.

Does that answer your question? Please close the issue if so, otherwise I'm happy to explain further.

It does! I was going to suggest folding in the behavior of @extend into composes, but after taking a closer look at css-modules/postcss-modules-scope#3 and https://tabatkins.github.io/specs/css-extend-rule/, I think it would be outside the scope of this project.

Thanks for responding! Closing now 🍻