Styling a child element using data-attribute selector
efflam opened this issue ยท 11 comments
Description
It's currently impossible to style a child element using a data-attribute selector.
Reproduction
https://codesandbox.io/s/pensive-thunder-ffsow?file=/src/App.js
Expected behavior
The child element should be blue when hovering the parent as seen in this example implemented with emotion:
https://codesandbox.io/s/emotion-vz1ll?file=/index.js
Actual behavior
The child element is not styled when hovering the parent
Thank you for the submission!
This is an atomic CSS library which only allows a limited set of selectors to be used:
/* Extracted from the `csstype` package */
export type SimplePseudos =
| ":-khtml-any-link"
// Other vendor-prefixed pseudosโฆ
| "::-webkit-slider-thumb"
| "::after"
| "::backdrop"
| "::before"
| "::cue"
| "::cue-region"
| "::first-letter"
| "::first-line"
| "::grammar-error"
| "::marker"
| "::placeholder"
| "::selection"
| "::spelling-error"
| ":active"
| ":after"
| ":any-link"
| ":before"
| ":blank"
| ":checked"
| ":default"
| ":defined"
| ":disabled"
| ":empty"
| ":enabled"
| ":first"
| ":first-child"
| ":first-letter"
| ":first-line"
| ":first-of-type"
| ":focus"
| ":focus-visible"
| ":focus-within"
| ":fullscreen"
| ":hover"
| ":in-range"
| ":indeterminate"
| ":invalid"
| ":last-child"
| ":last-of-type"
| ":left"
| ":link"
| ":only-child"
| ":only-of-type"
| ":optional"
| ":out-of-range"
| ":placeholder-shown"
| ":read-only"
| ":read-write"
| ":required"
| ":right"
| ":root"
| ":scope"
| ":target"
| ":valid"
| ":visited";
While the use of an invalid pseudo selector throws an error in TypeScript, JavaScript doesn't warn about the issue. I think there should be a runtime warning emitted about invalid selectors during development, accompanied with documentation about the phenomenon.
Adding this to the list of debug warnings to be emitted, see #2 for details.
So you can't target children when defining the styles right? It seems like a big limitation no?
Thinking about layout components, how would you implement a margin based Stack
component ("& > * + *": { marginTop: 8 }
) using otion?
@efflam Yes, that's exactly how it should be done, as also suggested by Styletron (please see the Descendant Hover section for an example).
@jgoux Please check out this opinion about the * + *
selector:
<Stack> shouldn't use the so-called lobotomised owl selector (* + *) to avoid wrapper elements around child nodes because it doesn't own those nodes. Why? You're mixing CSS from multiple owners on a single node, meaning their styles can clash with yours, breaking the stack.
โ Mark Dalgleish
See how composable the wrapped children become: https://twitter.com/markdalgleish/status/1261282811421417472
I agree that not being able to use attribute selectors feels like a very strong concession for any css library. For example, styling links with [target='_blank']
seems like a very common use-case. Or combining selectors, such as :not(:first-child)
etc. which do work, but throw typescript errors.
I would like to note that other atomic css libraries such as stitches have a way of supporting arbitrary selectors (although their solution is of course not applicable here).
Maybe one could add a selectors API that supports arbitrary strings, something like this:
const link = css({
selectors: {
"[target='_blank']::after": {
content: "'โ'",
},
},
});
What do you think @kripod?
@biowaffeln That's a good idea. The treat library does something very similar to that, while retaining type safety. I support the selectors
key, as it feels like an escape hatch from strong atomicity.
Advanced selectors including selector, lists
are now supported! ๐
Please refer to the updated documentation for information about their usage.
@all-contributors please add @efflam for ideas!
I've put up a pull request to add @efflam! ๐
@all-contributors please add @biowaffeln for ideas!
I've put up a pull request to add @biowaffeln! ๐