rya*_*nve 9 css scope css-variables
我试图通过var自定义属性来缩放大小,这种方式可以在没有耦合的情况下构成类.期望的效果是3个列表将是3个不同的比例,但是在codepen上演示,所有3个列表都是相同的比例.我正在寻找范围的解释和CSS自定义属性技术,可以使用可组合的松散耦合代码实现这一点.
:root {
--size-1: calc(1 * var(--scale, 1) * 1rem);
--size-2: calc(2 * var(--scale, 1) * 1rem);
--size-3: calc(3 * var(--scale, 1) * 1rem);
}
.size-1 { font-size: var(--size-1) }
.size-2 { font-size: var(--size-2) }
.size-3 { font-size: var(--size-3) }
.scale-1x { --scale: 1 }
.scale-2x { --scale: 2 }
.scale-3x { --scale: 3 }
html {
font: 1em sans-serif;
background: papayawhip;
}
ol {
float: left;
list-style: none;
margin: 1rem;
}Run Code Online (Sandbox Code Playgroud)
<ol class="scale-1x">
<li class="size-1">size 1</li>
<li class="size-2">size 2</li>
<li class="size-3">size 3</li>
</ol>
<ol class="scale-2x">
<li class="size-1">size 1</li>
<li class="size-2">size 2</li>
<li class="size-3">size 3</li>
</ol>
<ol class="scale-3x">
<li class="size-1">size 1</li>
<li class="size-2">size 2</li>
<li class="size-3">size 3</li>
</ol>Run Code Online (Sandbox Code Playgroud)
Tem*_*fif 10
它在某种程度上是棘手的,但在您的情况下,您已经--scale在根级别评估了自定义属性以定义--size-*属性,然后您--scale 再次定义了内部子元素.这不会再次触发评估,因为它已经在较高级别完成.
这是一个简单的例子来说明这个问题:
.box {
--color: var(--c, blue);
}
span {
color: var(--color);
}Run Code Online (Sandbox Code Playgroud)
<div>
<div class="box"><!-- --c is evaluated at this level -->
<span style="--c:red">I will not be red because the property is already evaluated and --color is set to blue using the default value</span>
</div>
</div>
<div style="--c:red">
<div class="box"><!-- --c is evaluated at this level -->
<span>I will be red because at the time of the evaluation --c is red (inherited from the upper div)</span>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
要解决您的问题,您需要移动声明:root并使其处于相同的--scale定义级别:
.scale {
--size-1: calc(1 * var(--scale, 1) * 1rem);
--size-2: calc(2 * var(--scale, 1) * 1rem);
--size-3: calc(3 * var(--scale, 1) * 1rem);
}
.size-1 { font-size: var(--size-1) }
.size-2 { font-size: var(--size-2) }
.size-3 { font-size: var(--size-3) }
.scale-1x { --scale: 1 }
.scale-2x { --scale: 2 }
.scale-3x { --scale: 3 }
html {
font: 1em sans-serif;
background: papayawhip;
}
ol {
float: left;
list-style: none;
margin: 1rem;
}Run Code Online (Sandbox Code Playgroud)
<ol class="scale-1x scale">
<li class="size-1">size 1</li>
<li class="size-2">size 2</li>
<li class="size-3">size 3</li>
</ol>
<ol class="scale-2x scale">
<li class="size-1">size 1</li>
<li class="size-2">size 2</li>
<li class="size-3">size 3</li>
</ol>
<ol class="scale-3x scale">
<li class="size-1">size 1</li>
<li class="size-2">size 2</li>
<li class="size-3">size 3</li>
</ol>Run Code Online (Sandbox Code Playgroud)
在这种情况下,--scale定义在其评估的同一级别,因此--size-*将针对每种情况正确定义.
从规格:
要在属性值中替换var():
- 如果由第一个参数变种()函数名为自定义属性是动画污染的,和使用var()函数中,动画属性被使用或它的longhands之一,治疗自定义属性为具有其初始值其余的这个算法.
- 如果var()函数的第一个参数指定的自定义属性的值不是初始值,则将var()函数替换为相应自定义属性的值.除此以外,
- 如果var()函数的回退值作为其第二个参数,则用回退值替换var()函数.如果后备中有任何var()引用,也可以替换它们.
- 否则,包含var()函数的属性在计算值时间无效
在你的第一种情况下,你属于(3)因为--scale在根级别没有指定值,但在最后一种情况下我们落入(2)因为我们--scale在同一级别定义并且我们有它的值.
在所有情况下,我们应该避免任何:root级别的评估,因为它根本没用.根级别是DOM中最高级别,因此所有元素都将继承相同的值,除非我们再次评估变量,否则不可能在DOM内部具有不同的值.
您的代码与此代码相同:
:root {
--size-1: calc(1 * 1 * 1rem);
--size-2: calc(2 * 1 * 1rem);
--size-3: calc(3 * 1 * 1rem);
}
Run Code Online (Sandbox Code Playgroud)
让我们再看一个例子:
:root {
--r:0;
--g:0;
--b:255;
--color:rgb(var(--r),var(--g),var(--b))
}
div {
color:var(--color);
}
p {
--g:100;
color:var(--color);
}Run Code Online (Sandbox Code Playgroud)
<div>
some text
</div>
<p>
some text
</p>Run Code Online (Sandbox Code Playgroud)
直觉上,我们可能认为我们可以--color通过改变在:root级别定义的3个变量中的一个来改变,但是没有.我们不能这样做,上面的代码与此相同:
:root {
--color:rgb(0,0,255)
}
div {
color:var(--color);
}
p {
--g:100;
color:var(--color);
}Run Code Online (Sandbox Code Playgroud)
<div>
some text
</div>
<p>
some text
</p>Run Code Online (Sandbox Code Playgroud)
该3个变量(--r,--g,--b)进行评估里面:root,所以我们已经可以与他们的价值观subtitute他们.
在这种情况下,我们有2个可能性:
:root使用JS或其他CSS规则中的变量,但它不允许我们使用不同的颜色::root {
--r:0;
--g:0;
--b:255;
--color:rgb(var(--r),var(--g),var(--b))
}
div {
color:var(--color);
}
p {
--g:200; /*this will not have any effect !*/
color:var(--color);
}
:root {
--g:200; /*this will work*/
}Run Code Online (Sandbox Code Playgroud)
<div>
some text
</div>
<p>
some text
</p>Run Code Online (Sandbox Code Playgroud)
:root将变得无用(或至少将成为默认值)::root {
--r:0;
--g:0;
--b:255;
--color:rgb(var(--r),var(--g),var(--b))
}
div {
color:var(--color);
}
p {
--g:200;
--color:rgb(var(--r),var(--g),var(--b));
color:var(--color);
}Run Code Online (Sandbox Code Playgroud)
<div>
some text
</div>
<p>
some text
</p>Run Code Online (Sandbox Code Playgroud)
考虑到这一点,我们应该始终将评估保持在DOM树中尽可能低,特别是在变量(或在同一级别)之后
这是我们不应该做的
:root {
--r: 0;
--g: 0;
--b: 0;
}
.color {
--color: rgb(var(--r), var(--g), var(--b))
}
.green {
--g: 255;
}
.red {
--r: 255;
}
p {
color: var(--color);
}
h1 {
border-bottom: 1px solid var(--color);
}Run Code Online (Sandbox Code Playgroud)
<div class="color">
<h1 class="red">Red </h1>
<p class="red">I want to be red :(</p>
</div>
<div class="color">
<h1 class="green">Green </h1>
<p class="green">I want to be green :(</p>
</div>Run Code Online (Sandbox Code Playgroud)
这是我们应该做的
:root {
--r:0;
--g:0;
--b:0;
}
.color {
--color:rgb(var(--r),var(--g),var(--b));
}
.green {
--g:255;
}
.red {
--r:255;
}
p {
color:var(--color);
}
h1 {
border-bottom: 1px solid var(--color);
}Run Code Online (Sandbox Code Playgroud)
<div class="red">
<h1 class="color">Red title</h1>
<p class="color">Yes I am red :D</p>
</div>
<div class="green">
<h1 class="color">Green title</h1>
<p class="color">Yes I am green :D</p>
</div>Run Code Online (Sandbox Code Playgroud)
我们也可以这样做:
:root {
--r:0;
--g:0;
--b:0;
}
.color {
--color:rgb(var(--r),var(--g),var(--b));
}
.green {
--g:255;
}
.red {
--r:255;
}
p {
color:var(--color);
}
h1 {
border-bottom: 1px solid var(--color);
}Run Code Online (Sandbox Code Playgroud)
<div class="red color">
<h1 >Red title</h1>
<p >Yes I am red :D</p>
</div>
<div class="green color">
<h1>Green title</h1>
<p >Yes I am green :D</p>
</div>Run Code Online (Sandbox Code Playgroud)