CSS function to reference other property's value

It would be useful to be able to reference another property’s value similar to how currentColor works for the color property.

While the following examples would be possible with custom properties (variables), authors of utility classes and third party libraries don’t always know what custom properties are available.

Example 1

Refer to the current background color to set a text color that has good contrast

.a11y-text {
  color: color-contrast(
    prop(background-color) vs white, black
  );
}

Example 2

Refer to inherited margin values in order to swap them

.card-layout {
  margin-inline-start: 1em;
  margin-inline-end: auto;
}

.card-layout.reverse {
  --prev-start: prop(margin-inline-start);
  --prev-end: prop(margin-inline-end);

  margin-inline-start: var(--prev-end);
  margin-inline-end: var(--prev-start);
}
1 Like

Yeah, this has been proposed numerous times, unfortunately it cannot be done in such a general way because it can introduce cycles, and cycle detection on that scale is nontrivial.

In fact, even your Example 2 is cyclical and would not do what you expect it to do: margin-inline-start depends on margin-inline-end and margin-inline-end depends on margin-inline-start.

A less powerful form of this that doesn’t permit cycles would be the ability to reference a parent’s property value. This was proposed here and accepted by the CSS WG here, though editorial work is still pending.

For your first example, there have been discussions for a currentBackgroundColor keyword, akin to currentColor.

1 Like

Would it be possible to at least reference the “current” value of the same property? So we could write something like this:

* {
  line-height: max(1.5, current);
}

This would effectively allow any length property to have a minimum and maximum value without overriding any value between them. For instance:

p { width: 38rem; }

p.special {
  width: max(current, 50ch);
}

If this concept of referencing other properties on the same selector target has been proposed several times, then there must be a lot of use cases for it. Is it possible to implement a weaker version that doesn’t introduce cycles?