Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a recursive variable be expressed in css?

For the html:

<body>
<div>
  <div>
    <div>
      ...
    </div>
  </div>
</div>
</body>

Are there any ways to create a recursive variable that uses its parent's value:

body > div {
    --x: 1;
}

div {
    --x: calc(var(--x) + 1);
}

The above is not valid because css variables cannot have dependency cycles. Another invalid example:

body > div {
    --is-even: 0;
    --is-odd: 1;
}

div {
    --is-even: var(--is-odd);
    --is-odd: var(--is-even);
}

Are there any indirect ways to express such recursive variables in css?

like image 271
Matt Bierner Avatar asked Apr 23 '18 05:04

Matt Bierner


People also ask

Can variables be used in CSS?

The var() function is used to insert the value of a CSS variable. CSS variables have access to the DOM, which means that you can create variables with local or global scope, change the variables with JavaScript, and change the variables based on media queries.

Can you change CSS variables in JavaScript?

CSS variables have access to the DOM, which means that you can change them with JavaScript.

What is recursive variable?

A recursive expression contains a variable nested inside of another variable (the outer variable). The value of the outer variable is conditional based on the value of the nested variable.


1 Answers

You can use two CSS variables to simulate the recursive behavior and avoid cycle dependency.

Here is an example:

body {
  --x: 10;
}
.y {
  --y: calc(var(--x) + 1);
}
.x{
  --x: calc(var(--y) + 1);
}
.result {
  border-right:calc(1px * var(--y)) solid red;
  border-left:calc(1px * var(--x)) solid green;
  height:50px;
}
<body>
  <div class="y">
    <div class="x">
      <div class="y">
        <div class="x">
          <div class="y">
            <div class="x">
              <div class="y result">

              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</body>

If you inspect the element you will find for the last element that border-right is equal to 17px (10 + 7) and border-left is equal to 16px (10 + 6)

enter image description here

This idea fits nicely in elements with a 2 level structure, like lists:

body {
  --x: 30;
}

ul { 
    font-size: calc(var(--x) * 1px);
    --y: calc(var(--x) - 8);
}

li {
  --x: calc(var(--y));
}
  <ul>level A
    <li>item 1
    </li>
    <li>item 2
      <ul>level B
        <li>item 2.1
          <ul>level C
            <li>item 2.1.1
            </li>
            <li>item 2.1.2
            </li>
          </ul>
        </li>
        <li>item 2.2
        </li>
      </ul>
    </li>
  </ul>
like image 118
Temani Afif Avatar answered Oct 14 '22 17:10

Temani Afif