CSS 如果无效,变量默认为 SVG 填充

CSS Variables default to SVG fill if invalid

我有一个 SVG,其中包含许多矩形,这些矩形在向下移动 SVG 时会改变填充颜色(以某种渐变外观)。用户可以选择纯色填充颜色 'theme' 他们的体验。这种颜色取代了矩形的 'gradient' 颜色。我正在使用 CSS 变量执行此操作。

但是,如果他们不选择主题颜色,我想默认返回 SVG 中定义的填充颜色。在这种情况下,CSS 变量设置为 '' 使其无效。对于其他元素,我使用元素回退到的默认值。我不能对 SVG 矩形执行此操作,因为它们各不相同。我尝试删除默认值,但我相信这会将填充设置为其初始 CSS 值,这是透明的。

如果我有以下矩形: <rect id="rect" fill="#000000" x="0" y="0" width="200" height="50" rx="6"></rect> 和下面的 CSS: rect { fill: var(--preview-primary); }--preview-primary 无效时,我希望它是黑色的,但它是透明的。

我有办法做到这一点吗?谢谢。

从 SVG 中删除 fill 样式,并在 CSS 中放置一个默认的 "fallback" 颜色,用于未定义变量的情况。

rect {
  fill: var(--preview-primary, 000);
}

rect {
  fill: var(--preview-primary, black);
}

.red {
  --preview-primary: red;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <rect x="10" y="10" height="100" width="100"/>
</svg>

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <rect class="red" x="10" y="10" height="100" width="100"/>
</svg>

不,无法回退到 fill 属性。

具有有效的 fill CSS 规则将优先于 fill 属性。 对于 CSSOM,var(--anything) 始终是有效规则。如果 var() 函数的计算无效,那么它将回退到默认值。 fill 的默认值为 black:

#f {
  fill: var(--foobar);
}
<svg>
  <rect id="f" x="0" y="0" height="80" width="80" fill="green"/>
</svg>

因此,要解决这种情况,您有以下几种选择:

  • 如果您无法修改您的 SVG,您可以仅在值不是 "" 时启用用户选择的规则。

sel.onchange = e => {
  document.documentElement.style
    .setProperty('--selected-color', sel.value);
  // toggle a class so we know we have to handle it
  document.documentElement.classList
    .toggle('user-selected-color', sel.value !== "");
};
.user-selected-color rect {
  fill: var(--selected-color);
}
select{vertical-align:top}
<svg height="180" width="180">
  <rect x="0" y="0" height="80" width="80" fill="green"/>
  <rect x="90" y="0" height="80" width="80" fill="blue"/>
  <rect x="0" y="90" height="80" width="80" fill="red"/>
  <rect x="90" y="90" height="80" width="80" fill="black"/>
</svg>

<select id="sel">
  <option value="">none</option>
  <option>orange</option>
  <option>pink</option>
  <option>violet</option>
  <option>aqua</option>
</select>

  • 如果可以,您可以设置每个元素的 CSS color,然后回退到 CSS 值 currentColor:

sel.onchange = e => {
  document.documentElement.style
    .setProperty('--selected-color', sel.value);
};
rect {
  fill: var(--selected-color, currentColor);
}
select{vertical-align:top}
<svg height="180" width="180">
  <rect x="0" y="0" height="80" width="80" fill="green" style="color:green"/>
  <rect x="90" y="0" height="80" width="80" fill="blue" style="color:blue"/>
  <rect x="0" y="90" height="80" width="80" fill="red" style="color:red"/>
  <rect x="90" y="90" height="80" width="80" fill="black" style="color:black"/>
</svg>

<select id="sel">
  <option value="">none</option>
  <option>orange</option>
  <option>pink</option>
  <option>violet</option>
  <option>aqua</option>
</select>