Skip to content

[css-values] if() function #3455

@matthew-dean

Description

@matthew-dean

The addition of min(), max(), clamp() and toggle() to the CSS Values 3 draft has made a lot of great progress towards more expressive styles. One thing that would be a very powerful general purpose logic switch would be an if() function. (Full disclosure, this matches the implementation in Less - http://lesscss.org/functions/#logical-functions-if, but would be much more powerful in the cascade.)

It would have this signature:

if(condition, trueResult, falseResult)

The condition would match the semantics in Media Queries Level 4, and would query the computed properties of an element.

For example, here's usage of an if() as an emulation of min()

.foo {
  --calc: calc(10 * (1vw + 1vh) / 2);
  font-size: if(var(--calc) < 12px, 12px, var(--calc));
}

Obviously, we already have min max, but what's useful about if() is that, like toggle(), you can use it for any value.

.foo {
  /** If our inherited width is below a certain threshold, change flex box wrapping behavior */
  flex-wrap: if(100% < 400px, wrap, nowrap);
  /** Note, a nicer way to write this would be "width < 400px" or some kind of units for inherited container width / height, like "100cw < 400px" but those don't exist */
}

You could also use it to toggle background based on inherited values.

.foo {
  background: if(currentColor = white, black, lightblue);
}

Like calc() and like other languages that have a declarative if() function, you can of course nest it.

.foo {
  width: if(box-sizing = border-box, 100%, if(var(--adjust), calc(100% - 20px), 100%));
}

Note that many other functions in CSS already have a kind of logic test built-in, but they're very restricted, such as var() itself, which tests for an inherited value, and has an else if the value is not defined.

if() would also pair nicely with toggle(), where the toggled value can be tested to resolve other property values.

.foo {
  font-style: toggle(italic, normal);
}
.foo .bar {
  /** Also demonstrates use of MQ4 not() */
  text-transform: if(not (font-style = italic), uppercase, inherit);
}

Anyway, that's for your consideration. Cheers!

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