420 Stimmen

Inline-SVG in CSS

Ist es möglich, eine Inline-SVG-Definition in CSS zu verwenden?

Ich meine so etwas wie:

.my-class {
  background-image: <svg>...</svg>;
}

12voto

Lea Rosema Punkte 1070

Ich habe eine CodePen-Demo geforkt, die das gleiche Problem mit der Einbettung von Inline-SVG in CSS hatte. Eine Lösung, die mit SCSS funktioniert, ist eine einfache url-encoding-Funktion zu bauen.

Eine String-Ersetzungsfunktion kann aus den eingebauten Funktionen str-slice und str-index erstellt werden (siehe css-tricks (Dank an Hugo Giraudel).

Dann ersetzen Sie einfach % , < , > , " , ' , mit dem %xx Codes:

@function svg-inline($string){
  $result: str-replace($string, "<svg", "<svg xmlns='http://www.w3.org/2000/svg'");
  $result: str-replace($result, '%', '%25');
  $result: str-replace($result, '"', '%22');
  $result: str-replace($result, "'", '%27');
  $result: str-replace($result, ' ', '%20');
  $result: str-replace($result, '<', '%3C');
  $result: str-replace($result, '>', '%3E');
  @return "data:image/svg+xml;utf8," + $result;
}

$mySVG: svg-inline("<svg>...</svg>");

html {
  height: 100vh;
  background: url($mySVG) 50% no-repeat;
}

Außerdem gibt es eine image-inline Hilfsfunktion, die in Compass verfügbar ist, aber da sie in CodePen nicht unterstützt wird, könnte diese Lösung vielleicht nützlich sein.

Demo auf CodePen: http://codepen.io/terabaud/details/PZdaJo/

8voto

Alex Nikulin Punkte 7249

Ich habe eine Lösung für SVG gefunden. Aber es ist Arbeit nur für Webkit, ich möchte nur meine Abhilfe mit Ihnen teilen. In meinem Beispiel wird gezeigt, wie man SVG-Element von DOM als Hintergrund durch einen Filter verwenden (background-image: url('#glyph') funktioniert nicht).

Funktionen, die für das Rendern dieses SVG-Symbols erforderlich sind:

  1. Anwendung von SVG-Filtereffekten auf HTML-Elemente mit CSS (IE und Edge nicht unterstützt)
  2. feImage fragment load unterstützt (firefox nicht unterstützt)

    .test { / background-image: url('#glyph'); background-size:100% 100%;/ filter: url(#image); height:100px; width:100px; } .test:before { display:block; content:''; color:transparent; } .test2{ width:100px; height:100px; } .test2:before { display:block; content:''; color:transparent; filter: url(#image); height:100px; width:100px; }

    <svg style="height:0;width:0;" version="1.1" viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <defs> <g id="glyph"> <path id="heart" d="M100 34.976c0 8.434-3.635 16.019-9.423 21.274h0.048l-31.25 31.25c-3.125 3.125-6.25 6.25-9.375 6.25s-6.25-3.125-9.375-6.25l-31.202-31.25c-5.788-5.255-9.423-12.84-9.423-21.274 0-15.865 12.861-28.726 28.726-28.726 8.434 0 16.019 3.635 21.274 9.423 5.255-5.788 12.84-9.423 21.274-9.423 15.865 0 28.726 12.861 28.726 28.726z" fill="crimson"/> </g> <svg id="resized-glyph" x="0%" y="0%" width="24" height="24" viewBox="0 0 100 100" class="icon shape-codepen"> <use xlink:href="#glyph"></use> </svg> <filter id="image"> <feImage xlink:href="#resized-glyph" x="0%" y="0%" width="100%" height="100%" result="res"/> <feComposite operator="over" in="res" in2="SourceGraphic"/> </filter> </defs> </svg> <div class="test"> </div> <div class="test2"> </div>

Eine weitere Lösung ist die Verwendung von url encode

var container = document.querySelector(".container");
var svg = document.querySelector("svg");
var svgText = (new XMLSerializer()).serializeToString(svg);
container.style.backgroundImage = `url(data:image/svg+xml;utf8,${encodeURIComponent(svgText)})`;

.container{
  height:50px;
  width:250px;
  display:block;
  background-position: center center;
  background-repeat: no-repeat;
  background-size: contain;
}

<svg  height="100" width="500" xmlns="http://www.w3.org/2000/svg">
    <ellipse cx="240" cy="50" rx="220" ry="30" style="fill:yellow" />
</svg>
<div class="container"></div>

6voto

mp31415 Punkte 6113

Inline-SVG aus Drittanbieter-Quellen (z. B. Google Charts) dürfen kein XML-Namespace-Attribut ( xmlns="http://www.w3.org/2000/svg" ) im SVG-Element (oder vielleicht wird es entfernt, sobald das SVG gerendert ist - weder der Browser-Inspektor noch die jQuery-Befehle der Browser-Konsole zeigen den Namensraum im SVG-Element an).

Wenn Sie diese svg-Schnipsel für andere Zwecke verwenden wollen (background-image in CSS oder img-Element in HTML), achten Sie auf den fehlenden Namespace. Ohne den Namespace verweigern die Browser möglicherweise die Anzeige von SVG (unabhängig von der Kodierung utf8 oder base64).

6voto

Dr Nic Punkte 1832

Wenn Sie postcss verwenden, können Sie die postcss-inline-svg Plugin https://www.npmjs.com/package/postcss-inline-svg

.up {
    background: svg-load('img/arrow-up.svg', fill: #000, stroke: #fff);
}
.down {
    background: svg-load('img/arrow-down.svg', fill=#000, stroke=#fff);
}

3voto

Izhaki Punkte 22440

Programmgesteuert, basierend auf dem Ansatz der bereits erwähnten https://github.com/yoksel/url-encoder/ :

// Svg (string)

const hexagon = `
<svg
width="100"
height="20"
viewBox="0 0 100 20"
xmlns="http://www.w3.org/2000/svg">
  <defs>
    <linearGradient
      id="redyel"
      gradientUnits="objectBoundingBox"
      x1="0"
      y1="0"
      x2="1"
      y2="1"
    >
      <stop offset="0%" stop-color="#ff0000" />
      <stop offset="100%" stop-color="#ffff00" />
    </linearGradient>
  </defs>
  <polygon
    points="0,10 5,0 95,0 100,10 95,20 5,20"
    fill="#eee"
    stroke="url(#redyel)"
  />
</svg>
`

// svgToBackgroundImage

const symbols = /[%#()<>?[\\\]^`{|}]/g;

const newLine = /\r?\n/;

const notEmptyString = (str) => str.length;
const trim = (str) => str.trim();

const toOneLine = (str) =>
  str.split(newLine).filter(notEmptyString).map(trim).join(" ");

function addNameSpace(svgString) {
  if (svgString.indexOf(`http://www.w3.org/2000/svg`) < 0) {
    svgString = svgString.replace(
      /<svg/g,
      `<svg xmlns="http://www.w3.org/2000/svg"`
    );
  }

  return svgString;
}

function encodeSVG(svgString) {
  svgString = svgString.replace(/>\s{1,}</g, `><`);
  svgString = svgString.replace(/\s{2,}/g, ` `);

  // Using encodeURIComponent() as replacement function
  // allows to keep result code readable
  return svgString.replace(symbols, encodeURIComponent);
}

const svgToBackgroundImage = (svgString) =>
  `url('data:image/svg+xml,${encodeSVG(addNameSpace(toOneLine(svgString)))}')`;

// DOM

const element = document.querySelector("#hexagon");
element.style.backgroundImage = svgToBackgroundImage(hexagon);

#hexagon {
  width: 100px;
  height: 20px;
}

<div id="hexagon"/>

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X