Skip to content

[css-mixins-1][css-values-5] The inherit() function in custom functions #12987

@andruud

Description

@andruud

The inherit keyword is left unresolved on the result descriptor, meaning that a function can return literally inherit, and trigger explicit inheritance at the call site. This behavior is good; it's to similar to how the var() in color:var(--c, inherit) can return inherit regardless of which syntax --c is registered with.

But is it weird that the same is not true for the functional form, inherit()?

@function --a() {
  --x: red;
  result: --b();
}
@function --b() {
  result: inherit;
}
#parent {
  --x: green;
}
#parent > #child {
  --x: --a();
  color: var(--x); /* green */
}

vs

@function --a() {
  --x: red;
  result: --b();
}
@function --b() {
  result: inherit(--x);
}
#parent {
  --x: green;
}
#parent > #child {
  --x: --a();
  color: var(--x); /* red */
}

This seems like a not-entirely-intended side effect of the "hypothetical element" model. While I'm sure there are use-cases for grabbing the value in the outer stack frame, it also defeats most/all of the use-cases outlined for the inherit() function (#2864), which do require inherit() to resolve against the actual flat tree parent.


Within the var()-based mixin model (#12927), this means the following would give red, which seems unlikely to be what you want:

<style>
  @mixin --m() {
    & > .child {
      color: inherit(--x);
    }
  }
  .parent {
    --x: green;
    @apply --m();
  }
  .child {
    --x: red;
  }
</style>
<div class=parent>
  <div class=child>
  </div>
</div>

I'm not sure how to solve this.

  • The current state is bad, because it makes inherit() useless for its original use-cases.
  • Always resolving inherit() against the flat-tree parent is also bad, because it makes values in the calling stack frame unreachable.
  • We could add a parent() function in addition to inherit(), but I'd rather not add two very similar functions to "global" CSS due to @function being weird.
  • Do we let both inherit and inherit() refer to the inherited value of the real element, and instead add a new keyword (+ function?) that refers to the calling stack frame? It weakens the "hyopthetical element" model, but perhaps this is the best move.
  • EDIT: Or perhaps we generalize inherit()? [css-mixins-1][css-values-5] A general inheritance syntax #12990

cc @tabatkins @EricSL

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