递归变量可以用css表示吗?
Can a recursive variable be expressed in css?
对于html:
<body>
<div>
<div>
<div>
...
</div>
</div>
</div>
</body>
有什么方法可以创建使用其父值的递归变量:
body > div {
--x: 1;
}
div {
--x: calc(var(--x) + 1);
}
以上内容无效,因为 css variables cannot have dependency cycles。另一个无效的例子:
body > div {
--is-even: 0;
--is-odd: 1;
}
div {
--is-even: var(--is-odd);
--is-odd: var(--is-even);
}
在css中有没有间接的方法来表达这样的递归变量?
您可以使用两个 CSS 变量来模拟递归行为并避免循环依赖。
这是一个例子:
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>
如果您检查该元素,您会发现最后一个元素的 border-right 等于 17px (10 + 7
) 并且 border-left 等于 16px (10 + 6
)
这个想法非常适合具有 2 级结构的元素,例如列表:
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>
如果您不能添加中间元素(div 与备用 类 或 ul/li),那么最简单的方法似乎是手动设置变量:
div { --x: 1 }
div div { --x: 2 }
div div div { --x: 3 }
/* ... */
在任何情况下,文档的嵌套都是有限的,比如 20、50、100 层。不是几千。
这里还有关于自引用变量的an article。作者提出以下做法:
:root {
--x: 1;
}
div {
--mixin: {
--x: calc(var(--x) + 1);
};
@apply --mixin;
}
但是他说了下面的话:
Currently you need Google Chrome with the experimental web plattform features flag enabled to see it working.
UPDATE: Jan 2019
CSS @apply was discarded, partly because of some problems it has with applying mixins that themself include other variables. So we have to wait until parent-var() becomes a thing in CSS.
所以现在可以使用以下选项:
- 为每个级别手动定义变量
- 对交替元素使用两个变量
- 等待
parent-var()
对于html:
<body>
<div>
<div>
<div>
...
</div>
</div>
</div>
</body>
有什么方法可以创建使用其父值的递归变量:
body > div {
--x: 1;
}
div {
--x: calc(var(--x) + 1);
}
以上内容无效,因为 css variables cannot have dependency cycles。另一个无效的例子:
body > div {
--is-even: 0;
--is-odd: 1;
}
div {
--is-even: var(--is-odd);
--is-odd: var(--is-even);
}
在css中有没有间接的方法来表达这样的递归变量?
您可以使用两个 CSS 变量来模拟递归行为并避免循环依赖。
这是一个例子:
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>
如果您检查该元素,您会发现最后一个元素的 border-right 等于 17px (10 + 7
) 并且 border-left 等于 16px (10 + 6
)
这个想法非常适合具有 2 级结构的元素,例如列表:
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>
如果您不能添加中间元素(div 与备用 类 或 ul/li),那么最简单的方法似乎是手动设置变量:
div { --x: 1 }
div div { --x: 2 }
div div div { --x: 3 }
/* ... */
在任何情况下,文档的嵌套都是有限的,比如 20、50、100 层。不是几千。
这里还有关于自引用变量的an article。作者提出以下做法:
:root {
--x: 1;
}
div {
--mixin: {
--x: calc(var(--x) + 1);
};
@apply --mixin;
}
但是他说了下面的话:
Currently you need Google Chrome with the experimental web plattform features flag enabled to see it working.
UPDATE: Jan 2019 CSS @apply was discarded, partly because of some problems it has with applying mixins that themself include other variables. So we have to wait until parent-var() becomes a thing in CSS.
所以现在可以使用以下选项:
- 为每个级别手动定义变量
- 对交替元素使用两个变量
- 等待
parent-var()