A partial archive of discourse.wicg.io as of Saturday February 24, 2024.

CSS property restrictions with default value

Nick_Gard
2021-09-27

This idea came about from a specific problem I had: I wrote a component that needed its wrapper to “have position” in order to contain some absolutely positioned children, but I wanted to let consumers of the component give it whatever position value they wanted, except static.

(I solved my particular problem by adding an extra inner wrapper and giving that position: relative; but this caused other smaller problems.)

I would have liked to have had some syntax like this:

constrain([not] value [, value [, ... ]] [/ initialValue])

/* Only allow these values */
position: constrain(relative, absolute, fixed / relative);

/* Disallow this value */
position: constrain(not static / relative);

The initial value would have to be at a lower specificity than the selector it’s declared under, so that something like this would work:

<style>
  .my-wrapper {
    position: fixed;
  }

  .uh-oh {
    position: static;
  }
</style>

<div
  class="my-wrapper"
  style="position: constrain(not static / relative) !important" >
  My position is fixed!
</div>

<div
  class="uh-oh"
  style="position: constrain(not static / relative) !important" >
  My position is relative!
</div>
Nick_Gard
2021-09-29

I think the constraint and default value would work like this: a higher specificity rule (or a matching rule with an !important declaration) would override the value, just like if it were any other value. The default value would only apply if no other authored rules with the same or less specificity matched.

<style>
  .card {
    position: constrain(not static / relative);
  }
  .sticky.card {
    position: constrain(absolute, fixed / fixed);
  }

  nav {
    position: absolute;
  }

  #my-card {
    position: static;
  }
</style>

<div class="card">
  I have position relative because that's my default
</div>

<div class="sticky card">
  I have position fixed because that's my default
</div>

<nav class="card">
  I have position absolute because that's allowed by my constraint
</nav>

<div id="my-card" class="card">
  I have position static because my rule has higher specificity than the constraint rule
</div>