Я пытался разработать скелетное изображение SVG для его отображения во время загрузки данных. Вот код, который я использовал для редактирования SVG.
// converting svg tag to data url and setting it as background image
const svgURL = 'data:image/svg+xml;charset=utf-8;base64,' + btoa(document.querySelector('svg').outerHTML);
document.querySelector('#xyz').style.backgroundImage = `url(${svgURL})`;svg {
height: 48px;
}
.xyz {
background-repeat: repeat-y !important;
background-size: 100% 48px !important;
}<svg
width = "100%"
height = "48"
xmlns = "http://www.w3.org/2000/svg"
stroke = "none"
fill = "grey"
>
<circle cx = "24" cy = "24" r = "12" />
<rect height = "20" width = "calc(100% - 60px)" x = "48" y = "14" rx = "10" ry = "7" fill = "grey" />
</svg>
<div id = "xyz" style = "border: red 1px solid; height: 300px; width: 100%"></div>Как вы можете видеть, тот же svg отображается правильно, если он является частью html, но как только мы используем его в качестве фона, ширина прямоугольника устанавливается неправильно.
Есть идеи, что я делаю неправильно и как это исправить?



Вашей основной проблемой было отсутствие viewBox и отсутствие удаления пробелов между тегами SVG.
IMG.src более снисходителен к пробелам.
К вашему сведению; xmlns NameSpace требуется для backgroundImage и IMG, но его можно опустить при использовании в качестве встроенного SVG в (современном) HTML-документе.
Вам не нужен Oldskool Base64 в современных браузерах, просто экранируйте некоторые специальные символы URI.
(Для краткости я использовал ярлык глобального идентификатора oldskool, используйте правильные ссылки в рабочем коде)
function escape(svg) {
return "data:image/svg+xml;charset=UTF-8," + svg
.replace(/\>[\t\s\n ]+\</g, "><") // replace all whitespace BETWEEN tags
.replace(/#/g, '%23')
.replace(/"/g, "'")
.replace(/&/g, '&');
}
XYZ.style.backgroundImage = `url("${escape(SVG.outerHTML)}")`;
IMG.src = escape(SVG.outerHTML);img, svg { width: 100%; height: 40px; background: pink }
#XYZ {
border: red 1px solid; height: 60px; width: 100%;
background-repeat: repeat-y;
background-size: 100% 40px;
}<b>Original SVG</b>
<svg id=SVG xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 350 50">
<circle cx = "24" cy = "24" r = "12" fill = "green"/>
<rect height = "20" width = "calc(100% - 40px)" x = "48" y = "14" rx = "10" ry = "7" fill = "teal" />
</svg>
<b>backgroundImage</b>
<div id = "XYZ"></div>
<b>IMG</b>
<img id=IMG>CSS calc() по-прежнему может быть непредсказуемым в разных браузерах при применении к элементам SVG.
Вы можете использовать этот хак, используя элементы <line> вместо <rect>.
.
Мы определяем длину через x2=100%,
примените преобразование translateX, чтобы сократить линию вправо
и смещение по оси X влево.
Протестировано в Firefox, Chrome и Safari.
// converting svg tag to data url and setting it as background image
const svgURL = 'data:image/svg+xml;charset=utf-8;base64,' + btoa(document.querySelector('svg').outerHTML);
document.querySelector('#xyz').style.backgroundImage = `url(${svgURL})`;svg {
height: 48px;
border:1px solid #ccc;
}
.xyz {
background-repeat: repeat-y;
background-size: 100% 48px !important;
resize:both;
overflow:auto;
}<svg
width = "100%"
height = "48"
xmlns = "http://www.w3.org/2000/svg"
stroke = "none"
fill = "grey"
>
<circle cx = "24" cy = "24" r = "12" />
<line x1 = "110" y1 = "24" x2 = "100%" y2 = "24" stroke-width = "20" stroke-linecap = "round" stroke = "grey" style = "transform:translate(-40px, 0)"></line>
</svg>
<h3>Resize me</h3>
<div class = "xyz" id = "xyz" style = "border: red 1px solid; height: 300px; width: 100%"></div>
Кажется, в Firefox все в порядке. Сообщайте о любых ошибках в соответствующую систему отслеживания ошибок браузера.