Skip to content

Descendant combinators proposal #229

@rtsao

Description

@rtsao

I've been thinking how to make a robust implementation of this because it's a fairly common use case.

The proposed idea has a few nice properties:

  • Still no true CSS selectors/class names
  • Clear precedence / style resolution (this is needed because the normal JS method of resolving styles doesn't translate into CSS land)
  • No brittle assumptions about component hierarchy. The correct ancestor/descendant relationship is enforced via the render prop API. (excluding portals, I suppose)

Example

I'm not totally happy with the names of things (still working on it), but hopefully the overall idea makes sense:

import {createAncestor, Descendant} from "styletron-react";

const Foo = styled("div", {color: "green"});

const HoverSource1 = createAncestor(":hover", {
  color: "red"
});

const HoverSource2 = createAncestor(":hover", {
  color: "purple"
});

<HoverSource1 $as="div">
  {target1 => (
    <HoverSource2>
      {target2 => (
        <div>
          <Descendant $as={Foo} $combinators={[target1, target2]} />
        </div>
      )}
    </HoverSource2>
  )}
</HoverSource1>;

Concepts

  • The order of the array passed to Descendant determines the precedence of styling. As an implementation detail, we can iteratively increase the specificity of generated rules to make this happen.
  • Descendent combinator styles always take precedence over "normal styles".

There's still a lot that needs to be ironed out, especially in terms of figuring out all the implementation details, but this is probably the first API that I've liked for this feature.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions