Skip to content

[css-values] Cyclic definitions with relative units #2115

@Loirooriol

Description

@Loirooriol

CSS Values 4 introduces the lh unit. How exactly does the following resolve?

* {
  line-height: 2em;
  font-size: 3lh;
}

Or using registerProperty from CSS Properties and Values,

CSS.registerProperty({
  name: "--prop",
  syntax: "<length>",
  initialValue: "0"
});
* {
  --prop: 2em;
  font-size: var(--prop);
}

You can use the codes above to make the computed value of font-size depend on the computed value of another property that depends on the computed value of font-size.

I think you should generalize this:

When used in the value of the font-size property (or the line-height property, for the lh and rlh units) on the element they refer to, these units refer to the computed font metrics of the parent element

into this:

For each element, create a directed dependency graph, containing nodes for font-size, line-height and any other property which uses some font-relative unit. For each use of one of these units unit in a property prop on the element unit refers to, add an edge between prop and line-height if unit is lh or rlh, or between prop and font-size otherwise. Edges are possible from a property to itself. If there is some cycle in the dependency graph, each font-relative unit that added an edge in that cycle refers to the computed font metrics of the parent element (or the computed font metrics corresponding to the initial values of the font property, if the element has no parent).

Then,

parent {
  line-height: 2px;
  font-size: 3px;
}
child {
  line-height: 5em; /* 5 * 3px = 15px, em refers to parent */
  font-size: 7lh; /* 7 * 2px = 14px, lh refers to parent */
}
/*  line-height ──────┐
    ▲                 ▼
    └──────────── font-size  */
parent {
  line-height: 2px;
  font-size: 3px;
}
child {
  line-height: 5px;
  --prop: max(1em, 1lh); /* max(3px, 5px) = 5px, em refers to parent, lh does not */
  font-size: var(--prop); /* 5px */
}
/*  ┌────── --prop ──────┐
    ▼          ▲         ▼
line-height    └──── font-size  */

Another approach could be resolving font-size and line-height first, by making relevant font-relative units and var() functions retrieve the value from the parent.

parent {
  --prop: 2px;
  font-size: 3px;
}
child {
  font-size: var(--prop); /* 2px, --prop refers to parent */
  --prop: 5em; /* 5 * 1px = 5px */
}
/*  --prop ──────┐
       ▲         ▼
       └──── font-size  */

But I don't think CSS Values should mess with CSS Variables by altering what var() does.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions