如何在 SVG <use> 元素上应用自定义 CSS 样式
How to apply custom CSS style on SVG <use> element
我正在使用 svg 元素
var defsElement = document.querySelector('defs');
var defsElementX = defsElement.getBBox().x;
var defsElementY = defsElement.getBBox().y;
var colX = [];
for (var i = 0; i < 3; i++) {
(i == 0) ? colX.push(25): colX.push(colX[i - 1] + 60)
};
//console.log(colX);
const y = 145;
const svg = document.querySelector("svg");
const svgns = "http://www.w3.org/2000/svg"
colX.forEach(
(a, i) => {
let useEl = document.createElementNS(svgns, 'use');
useEl.setAttributeNS('http://www.w3.org/1999/xlink', "xlink:href", "#stick man");
useEl.setAttribute("class", "use" + [i]);
useEl.setAttribute("id", "id" + [i]);
useEl.setAttribute("x", `${a}`);
useEl.setAttribute("y", `${y}`);
svg.appendChild(useEl);
}
)
.stickman {
stroke: red;
fill: none;
}
.stickman>.head {
fill: black;
stroke: blue;
}
.head {
fill: brown;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<link rel="stylesheet" href="style.css"></link>
<svg id="layer" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
<defs>
<g id="stick man" style="fill: none; stroke: black;">
<circle class="head" cx="10" cy="10" r="10"/>
<line class="body" x1="10" y1="20" x2="10" y2="44"/>
<polyline class="upper" points="1 58, 10 44, 19 58"/>
<polyline class="lower" points="1 24, 10 30, 19 24"/>
</g>
</defs>
<g class="stickman" id="stickman" transform = "translate (85,50)">
<circle class="head" cx="10" cy="10" r="10"/>
<line class="body" x1="10" y1="20" x2="10" y2="44"/>
<polyline class="upper" points="1 58, 10 44, 19 58"/>
<polyline class="lower" points="1 24, 10 30, 19 24"/>
<script href="index.js"></script>
</svg>
</body>
</html>
我想了解如何将 CSS 样式应用于不同的 <use></use>
元素。例如,如何为每个 head
应用 3 种不同的颜色 fill
。我应该使用什么 CSS 选择器?
我试过了
.use0>.head {
fill: brown;
}
它什么也没做。
javascript
正在生成这个
在你的例子中没有 use0
class 所以显然没有改变任何东西,你的规则:
.head {
fill: brown;
}
刚刚被覆盖:
.stickman>.head {
fill: black;
}
确保您有一个优先级 css 规则来覆盖另一个规则...有很多方法可以避免 !Important
,例如:
body .stickman .head {
fill: brown;
}
关于 css 优先级的更多信息 here
您可以为此使用 CSS 个变量:
const svg = document.querySelector("svg");
const svgns = "http://www.w3.org/2000/svg";
for (let i = 0; i < 3; ++i) {
let useEl = document.createElementNS(svgns, 'use');
useEl.setAttributeNS('http://www.w3.org/1999/xlink', "xlink:href", "#stickRef");
useEl.setAttribute("id", `id${i}`);
useEl.setAttribute("x", (i * 60) + 25);
useEl.setAttribute("y", 25);
svg.appendChild(useEl);
}
#id0 { --head-colour: #F00; --line-colour: #900; }
#id1 { --head-colour: #0F0; --line-colour: #090; }
#id2 { --head-colour: #00F; --line-colour: #009; }
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
<defs>
<symbol id="stickRef" style="fill: none; stroke: var(--line-colour);">
<circle class="head" cx="10" cy="10" r="10" style="fill: var(--head-colour)" />
<line class="body" x1="10" y1="20" x2="10" y2="44"/>
<polyline class="upper" points="1 58, 10 44, 19 58"/>
<polyline class="lower" points="1 24, 10 30, 19 24"/>
</symbol>
</defs>
</svg>
您可以用 style="fill: none;"
将火柴人的线条和多段线包裹在一个组 <g>
中,留下未指定填充的圆圈。
现在您可以设置填充属性或为 <use>
元素指定样式。填充将仅应用于圆。
use{fill:red}
use:nth-of-type(2){fill:gold}
use:nth-of-type(3){fill:blue}
<svg id="layer" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 100 500 500">
<defs>
<g id="stickman" style="stroke: black;">
<circle class="head" cx="10" cy="10" r="10"></circle>
<g style="fill: none;">
<line class="body" x1="10" y1="20" x2="10" y2="44"></line>
<polyline class="upper" points="1 58, 10 44, 19 58"></polyline>
<polyline class="lower" points="1 24, 10 30, 19 24"></polyline>
</g>
</g>
</defs>
<use xlink:href="#stickman" x="25" y="145"></use>
<use xlink:href="#stickman" x="85" y="145"></use>
<use xlink:href="#stickman" x="145" y="145"></use>
</svg>
我正在使用 svg 元素
var defsElement = document.querySelector('defs');
var defsElementX = defsElement.getBBox().x;
var defsElementY = defsElement.getBBox().y;
var colX = [];
for (var i = 0; i < 3; i++) {
(i == 0) ? colX.push(25): colX.push(colX[i - 1] + 60)
};
//console.log(colX);
const y = 145;
const svg = document.querySelector("svg");
const svgns = "http://www.w3.org/2000/svg"
colX.forEach(
(a, i) => {
let useEl = document.createElementNS(svgns, 'use');
useEl.setAttributeNS('http://www.w3.org/1999/xlink', "xlink:href", "#stick man");
useEl.setAttribute("class", "use" + [i]);
useEl.setAttribute("id", "id" + [i]);
useEl.setAttribute("x", `${a}`);
useEl.setAttribute("y", `${y}`);
svg.appendChild(useEl);
}
)
.stickman {
stroke: red;
fill: none;
}
.stickman>.head {
fill: black;
stroke: blue;
}
.head {
fill: brown;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<link rel="stylesheet" href="style.css"></link>
<svg id="layer" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
<defs>
<g id="stick man" style="fill: none; stroke: black;">
<circle class="head" cx="10" cy="10" r="10"/>
<line class="body" x1="10" y1="20" x2="10" y2="44"/>
<polyline class="upper" points="1 58, 10 44, 19 58"/>
<polyline class="lower" points="1 24, 10 30, 19 24"/>
</g>
</defs>
<g class="stickman" id="stickman" transform = "translate (85,50)">
<circle class="head" cx="10" cy="10" r="10"/>
<line class="body" x1="10" y1="20" x2="10" y2="44"/>
<polyline class="upper" points="1 58, 10 44, 19 58"/>
<polyline class="lower" points="1 24, 10 30, 19 24"/>
<script href="index.js"></script>
</svg>
</body>
</html>
我想了解如何将 CSS 样式应用于不同的 <use></use>
元素。例如,如何为每个 head
应用 3 种不同的颜色 fill
。我应该使用什么 CSS 选择器?
我试过了
.use0>.head {
fill: brown;
}
它什么也没做。
javascript
正在生成这个
在你的例子中没有 use0
class 所以显然没有改变任何东西,你的规则:
.head {
fill: brown;
}
刚刚被覆盖:
.stickman>.head {
fill: black;
}
确保您有一个优先级 css 规则来覆盖另一个规则...有很多方法可以避免 !Important
,例如:
body .stickman .head {
fill: brown;
}
关于 css 优先级的更多信息 here
您可以为此使用 CSS 个变量:
const svg = document.querySelector("svg");
const svgns = "http://www.w3.org/2000/svg";
for (let i = 0; i < 3; ++i) {
let useEl = document.createElementNS(svgns, 'use');
useEl.setAttributeNS('http://www.w3.org/1999/xlink', "xlink:href", "#stickRef");
useEl.setAttribute("id", `id${i}`);
useEl.setAttribute("x", (i * 60) + 25);
useEl.setAttribute("y", 25);
svg.appendChild(useEl);
}
#id0 { --head-colour: #F00; --line-colour: #900; }
#id1 { --head-colour: #0F0; --line-colour: #090; }
#id2 { --head-colour: #00F; --line-colour: #009; }
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
<defs>
<symbol id="stickRef" style="fill: none; stroke: var(--line-colour);">
<circle class="head" cx="10" cy="10" r="10" style="fill: var(--head-colour)" />
<line class="body" x1="10" y1="20" x2="10" y2="44"/>
<polyline class="upper" points="1 58, 10 44, 19 58"/>
<polyline class="lower" points="1 24, 10 30, 19 24"/>
</symbol>
</defs>
</svg>
您可以用 style="fill: none;"
将火柴人的线条和多段线包裹在一个组 <g>
中,留下未指定填充的圆圈。
现在您可以设置填充属性或为 <use>
元素指定样式。填充将仅应用于圆。
use{fill:red}
use:nth-of-type(2){fill:gold}
use:nth-of-type(3){fill:blue}
<svg id="layer" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 100 500 500">
<defs>
<g id="stickman" style="stroke: black;">
<circle class="head" cx="10" cy="10" r="10"></circle>
<g style="fill: none;">
<line class="body" x1="10" y1="20" x2="10" y2="44"></line>
<polyline class="upper" points="1 58, 10 44, 19 58"></polyline>
<polyline class="lower" points="1 24, 10 30, 19 24"></polyline>
</g>
</g>
</defs>
<use xlink:href="#stickman" x="25" y="145"></use>
<use xlink:href="#stickman" x="85" y="145"></use>
<use xlink:href="#stickman" x="145" y="145"></use>
</svg>