วิธีการเปลี่ยนสีขององค์ประกอบ svg?


350

ฉันต้องการใช้เทคนิคนี้http://css-tricks.com/svg-fallbacks/และเปลี่ยนสี svg แต่จนถึงตอนนี้ฉันยังไม่สามารถทำได้ ฉันใส่มันลงใน CSS แต่ภาพของฉันจะเป็นสีดำเสมอไม่ว่าอะไรก็ตาม รหัสของฉัน:

.change-my-color {
  fill: green;
}
<svg>
    <image class="change-my-color" xlink:href="https://svgur.com/i/AFM.svg" width="96" height="96" src="ppngfallback.png" />
</svg>


ฉันไม่ใช่ผู้เชี่ยวชาญ svg แต่คุณได้ลองเปลี่ยนสีเติมเป็นสีพื้นหลังหรือไม่?
Meg

@Megan ใน svg background-color ถูกระบุด้วยคุณสมบัติ 'fill' และเส้นขอบที่มี 'stroke' (ดังที่คุณทำใน Illustrator) w3.org/TR/SVG/propidx.html
Barbara

4
CSS จากเอกสาร HTML ของคุณจะไม่สามารถใช้กับองค์ประกอบ SVG ภายใน <img />
pawel

1
เป็นไปได้ตอนนี้ คำตอบที่ง่ายและใช้งานได้ที่นี่: stackoverflow.com/a/53336754/467240
mtyson

คำตอบ:


188

คุณไม่สามารถเปลี่ยนสีของภาพได้ หากคุณโหลด SVG เป็นรูปภาพคุณจะไม่สามารถเปลี่ยนวิธีการแสดงโดยใช้ CSS หรือ Javascript ในเบราว์เซอร์

หากคุณต้องการที่จะเปลี่ยนภาพ SVG ของคุณคุณต้องโหลดโดยใช้<object>, <iframe>หรือใช้<svg>แบบอินไลน์

หากคุณต้องการใช้เทคนิคในหน้านี้คุณต้องมีห้องสมุด Modernizr ซึ่งคุณสามารถตรวจสอบการสนับสนุน SVG และแสดงผลแบบมีเงื่อนไขหรือไม่เป็นรูปภาพสำรอง จากนั้นคุณสามารถอินไลน์ SVG ของคุณและใช้สไตล์ที่คุณต้องการ

ดู:

คุณสามารถอินไลน์ SVG ของคุณติดแท็กรูปภาพทางเลือกด้วยชื่อคลาส ( my-svg-alternate):

<svg width="96px" height="96px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
<path id="time-3-icon" .../>
</svg>

<image class="my-svg-alternate" width="96" height="96" src="ppngfallback.png" />

และใน CSS ใช้no-svgคลาสจาก Modernizr (CDN: http://ajax.aspnetcdn.com/ajax/modernizr/modernizr-2.7.2.js ) เพื่อตรวจสอบการสนับสนุน SVG หากไม่มีการสนับสนุน SVG บล็อก SVG จะถูกละเว้นและรูปภาพจะปรากฏขึ้นมิฉะนั้นรูปภาพจะถูกลบออกจากต้นไม้ DOM ( display: none):

.my-svg-alternate {
  display: none;
}
.no-svg .my-svg-alternate {
  display: block;
  width: 100px;
  height: 100px;
  background-image: url(image.png);
}

จากนั้นคุณสามารถเปลี่ยนสีขององค์ประกอบที่ขีดเส้นใต้ของคุณ:

#time-3-icon {
   fill: green;
}

5
คุณไม่สามารถจัดสไตล์objectSVG ในตัวจากเอกสารโฮสติ้ง
Javier Rey

1
@JavierRey คุณสามารถใส่สไตล์ลงในเนื้อหาของแท็กวัตถุผ่าน javascript แต่คุณคิดว่ามันใช้ไม่ได้ถ้าคุณเพิ่งเพิ่มไปยังสไตล์ชีทของเอกสารโฮสติ้ง
Robert Longson

2
ฉันใช้วิธีแก้ปัญหาจาก @ manish-menaria และทำงานได้อย่างสมบูรณ์
Ryan Ellis

1
คำตอบที่ยอมรับควรเปลี่ยนเป็น: stackoverflow.com/a/53336754/467240
mtyson

376

2563 ตอบ

CSS Filter ใช้งานได้กับเบราว์เซอร์ปัจจุบันทั้งหมด

ในการเปลี่ยนสี SVG ใด ๆ

  1. เพิ่มภาพ SVG โดยใช้<img>แท็ก
<img src="dotted-arrow.svg" class="filter-green"/>
  1. หากต้องการกรองเป็นสีเฉพาะให้ใช้Codepenต่อไปนี้(คลิกที่นี่เพื่อเปิด codepen)เพื่อแปลงรหัสสีฐานสิบหกเป็นตัวกรอง CSS:

ตัวอย่างเช่นผลลัพธ์สำหรับ#00EE00คือ

filter: invert(42%) sepia(93%) saturate(1352%) hue-rotate(87deg) brightness(119%) contrast(119%);
  1. เพิ่ม CSS filterลงในคลาสนี้
    .filter-green{
        filter: invert(48%) sepia(79%) saturate(2476%) hue-rotate(86deg) brightness(118%) contrast(119%);
    }

5
สิ่งนี้มาพร้อมกับข้อแม้ที่ปกติเกี่ยวกับการไม่รองรับเบราว์เซอร์เวอร์ชันเก่า: developer.mozilla.org/en-US/docs/Web/CSS/…
Kevin Wang

17
ดังที่ระบุไว้ใน CodePen หาก SVG ของคุณไม่ใช่สีดำ (ของฉันเป็นสีเทา) การเพิ่มbrightness(0) saturate(100%)ไปที่จุดเริ่มต้นของรายการตัวกรองจะเปลี่ยนเป็นสีดำ 100% ซึ่งจะทำให้ตัวกรองอื่น ๆ เปลี่ยนเป็นสีที่ถูกต้อง
jdunning

2
นอกจากนี้พื้นหลังที่น่าสนใจมากมายในการแก้ปัญหาในคำถาม StackOverflowนี้ที่แจ้ง CodePen
jdunning

3
ผู้ชายของฉัน. การสนับสนุนที่ดูเหมือนว่ายอมรับcaniuse.com/#feat=css-filters
Sam Doidge

ทำงานได้ดีใช้ codepen ที่ไม่ได้ใช้ร่วมกันเพื่อให้ hex ของฉันเป็นตัวกรอง: codepen.io/sosuke/pen/Pjoqqp
WEBjuju

220

ในการเปลี่ยนสีของ SVG ใด ๆ คุณโดยตรงสามารถเปลี่ยนรหัส SVG โดยการเปิดไฟล์ SVG ในตัวแก้ไขข้อความใด รหัสอาจมีลักษณะเหมือนรหัสด้านล่าง

<?xml version="1.0" encoding="utf-8"?>
    <!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
    <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
         width="500px" height="500px" viewBox="0 0 500 500" enable-background="new 0 0 500 500" xml:space="preserve">
    <g>
        <path d="M114.26,436.584L99.023,483h301.953l-15.237-46.416H114.26z M161.629,474.404h-49.592l9.594-29.225h69.223
            C181.113,454.921,171.371,464.663,161.629,474.404z"/>
    /*Some more code goes on*/
    </g>
    </svg>

คุณสามารถสังเกตเห็นว่ามีบางแท็ก XML เช่นเส้นทางวงกลมรูปหลายเหลี่ยม ฯลฯ มีคุณสามารถเพิ่มสีของคุณเองด้วยความช่วยเหลือของแอตทริบิวต์สไตล์ ดูตัวอย่างด้านล่าง

<path style="fill:#AB7C94;" d="M114.26,436.584L99.023,483h301.953l-15.237-46.416H114.26z M161.629,474.404h-49.592l9.594-29.225h69.223
                C181.113,454.921,171.371,464.663,161.629,474.404z"/>

เพิ่มแอตทริบิวต์สไตล์ให้กับแท็กทั้งหมดเพื่อให้คุณได้รับ SVG ของสีที่ต้องการ


48
ทำไมไม่เพียงใช้แอตทริบิวต์fillเช่นนี้fill = "#AB7C94"? ไม่แน่ใจว่าทำไมจึงstyleจำเป็นต้องใช้แอตทริบิวต์
bg17aw

4
สวัสดีแดเนียลใช่มันทำงานได้ ฉันไม่ทราบว่าสามารถใช้การเติมเป็นแอตทริบิวต์ได้ ขออภัยที่ไม่ได้แจ้งความคิดเห็นของคุณอีกต่อไป @ bg17aw
sushant047

30

เพิ่มหน้าทดสอบ - เพื่อเปลี่ยนสี SVG ผ่านการตั้งค่าตัวกรอง:

เช่น filter: invert(0.5) sepia(1) saturate(5) hue-rotate(175deg)

อัปโหลดและระบายสี SVG ของคุณ - Jsfiddle

ใช้แนวคิดจาก: https://blog.union.io/code/2017/08/10/img-svg-fill/


1
ขอบคุณคุณช่วยฉันจากตัวฉันเอง .custom-disabled > svg {filter:invert(0.2) sepia(1) saturte(0) hue-rotate(0);}มีเพียงงานที่ฉันต้องปิดไอคอน
เจอร์

20

SVG เท่านั้นที่มีข้อมูลเส้นทาง คุณไม่สามารถทำสิ่งนั้นกับภาพ .. เนื่องจากเส้นทางที่คุณสามารถเปลี่ยนจังหวะและกรอกข้อมูลและเสร็จแล้ว เช่นนักวาดภาพประกอบ

ดังนั้น: ผ่าน CSS คุณสามารถเขียนทับfillค่าเส้นทาง

path { fill: orange; }

แต่ถ้าคุณต้องการวิธีที่ยืดหยุ่นมากขึ้นตามที่คุณต้องการจะเปลี่ยนด้วยข้อความเมื่อมีผลการลอยตัวอยู่บ้าง .. ใช้

path { fill: currentcolor; }

body {
  background: #ddd;
  text-align: center;
  padding-top: 2em;
}

.parent {
  width: 320px;
  height: 50px;
  display: block;
  transition: all 0.3s;
  cursor: pointer;
  padding: 12px;
  box-sizing: border-box;
}

/***  desired colors for children  ***/
.parent{
  color: #000;
  background: #def;
}
.parent:hover{
  color: #fff;
  background: #85c1fc;
}

.parent span{
  font-size: 18px;
  margin-right: 8px;
  font-weight: bold;
  font-family: 'Helvetica';
  line-height: 26px;
  vertical-align: top;
}
.parent svg{
  max-height: 26px;
  width: auto;
  display: inline;
}

/****  magic trick  *****/
.parent svg path{
  fill: currentcolor;
}
<div class='parent'>
  <span>TEXT WITH SVG</span>
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128" viewBox="0 0 32 32">
<path d="M30.148 5.588c-2.934-3.42-7.288-5.588-12.148-5.588-8.837 0-16 7.163-16 16s7.163 16 16 16c4.86 0 9.213-2.167 12.148-5.588l-10.148-10.412 10.148-10.412zM22 3.769c1.232 0 2.231 0.999 2.231 2.231s-0.999 2.231-2.231 2.231-2.231-0.999-2.231-2.231c0-1.232 0.999-2.231 2.231-2.231z"></path>
</svg>
</div>


12

วิธีที่ง่ายที่สุดคือการสร้างแบบอักษรจาก SVG โดยใช้บริการเช่นhttps://icomoon.io/app/#/selectหรือเช่นนั้น อัปโหลด SVG ของคุณคลิก "สร้างแบบอักษร" รวมไฟล์แบบอักษรและ css ไว้ในด้านของคุณแล้วใช้และจัดรูปแบบเหมือนกับข้อความอื่น ๆ ฉันใช้มันแบบนี้เสมอเพราะมันทำให้การออกแบบง่ายขึ้นมาก

แก้ไข:ดังที่กล่าวไว้ในบทความแสดงความคิดเห็นโดย @ แบบอักษร CodeMouse92 แบบอักษรสับสนขึ้นผู้อ่านหน้าจอ (และอาจจะไม่ดีสำหรับ SEO) ดังนั้นค่อนข้างยึดติดกับ SVG


4
นอกจากนี้ยัง messes up โปรแกรมอ่านหน้าจอ ดู"แบบอักษรตายเพื่อไอคอน" โดย Seren Davies
CodeMouse92

7

หน้ากาก SVG บนองค์ประกอบกล่องที่มีสีพื้นหลังจะส่งผลให้:

.icon{
  --size     : 70px;
  display    : inline-block;
  width      : var(--size);
  height     : var(--size);
  transition : .12s;
  -webkit-mask-size: cover;
  mask-size  : cover;
}

.icon-bike{
  background: black;
  -webkit-mask-image: url(https://image.flaticon.com/icons/svg/89/89139.svg);
  mask-image: url(hhttps://image.flaticon.com/icons/svg/89/89139.svg);
  animation: 1s frames infinite ease;
}

@keyframes frames {
  50% { background:red;  }
}
<i class="icon icon-bike" style="--size:150px"></i>


หมายเหตุ - มาสก์ SVG ไม่ได้รับการสนับสนุนในเบราว์เซอร์Internet Explorer


1
ขอบคุณมาก @vsync นี่เป็นเพียงแฮ็คที่ดีที่สุดสำหรับสิ่งที่ฉันต้องการ
Vixson

6

คุณสามารถเปลี่ยนการระบายสี SVG ด้วย css หากคุณใช้เทคนิคบางอย่าง ฉันเขียนบทเล็ก ๆ สำหรับเรื่องนั้น

  • ผ่านรายการองค์ประกอบที่มีภาพ svg
  • โหลดไฟล์ svg เป็น xml
  • ดึงส่วน svg เท่านั้น
  • เปลี่ยนสีของเส้นทาง
  • แทนที่ src ด้วย svg ที่แก้ไขแล้วเป็นรูปภาพอินไลน์
$('img.svg-changeable').each(function () {
  var $e = $(this);
  var imgURL = $e.prop('src');

  $.get(imgURL, function (data) {
    // Get the SVG tag, ignore the rest
    var $svg = $(data).find('svg');

    // change the color
    $svg.find('path').attr('fill', '#000');

    $e.prop('src', "data:image/svg+xml;base64," + window.btoa($svg.prop('outerHTML')));
  });

});

รหัสด้านบนอาจทำงานไม่ถูกต้องฉันใช้สิ่งนี้กับองค์ประกอบที่มีภาพพื้นหลัง svg ซึ่งทำงานคล้ายกับสิ่งนี้ แต่อย่างไรก็ตามคุณต้องแก้ไขสคริปต์นี้ให้เหมาะกับกรณีของคุณ หวังว่ามันจะช่วย


โดยวิธีการ: หากคุณเป็นผู้พัฒนา RoR คุณสามารถเพิ่มวิธีการใหม่สำหรับ sass precompiler ซึ่งสามารถทำงานได้เช่นกัน สิ่งนี้ดีกว่ามากเพราะคุณจะได้รับการเข้ารหัส base64 รูปภาพสีที่ถูกต้องในไฟล์ css ที่คอมไพล์แล้ว ไม่จำเป็นต้องใช้ JS อีกต่อไป! บางทีฉันสามารถให้รหัสที่ฉันเขียนได้ต้องคุยกับ CTO
cydoc

2
+1 สำหรับการแก้ปัญหาแทนที่จะบอกว่าไม่สามารถทำได้ คำตอบนี้เกี่ยวข้องกับ: stackoverflow.com/questions/11978995/…
claytronicon

5

กำหนดเส้นทางภายใน svg:

<svg>
   <path>....
</svg>

คุณสามารถทำแบบอินไลน์เช่น:

<path fill="#ccc">

หรือ

svg{
   path{
        fill: #ccc


2

หากคุณต้องการทำสิ่งนี้กับอินไลน์ svg นั่นคือรูปภาพพื้นหลังใน css ของคุณ:

background: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='rgba(31,159,215,1)' viewBox='...'/%3E%3C/svg%3E");

แน่นอนแทนที่ ... ด้วยรหัสภาพอินไลน์ของคุณ


2

ตัวอย่างเช่นใน HTML ของคุณ:

<body>
  <svg viewBox="" width="" height="">
    <path id="struct1" fill="#xxxxxx" d="M203.3,71.6c-.........."></path>
  </svg>
</body>

ใช้ jQuery:

$("#struct1").css("fill","<desired colour>");

ใช้งานได้เฉพาะในกรณีที่คุณรวมไฟล์ SVG ไว้ใน HTML ฉันได้แก้ไขคำตอบของคุณเพื่อให้ชัดเจน
Flimm

0

ที่จริงแล้วมีวิธีแก้ปัญหาที่ยืดหยุ่นมากกว่าสำหรับปัญหานี้คือการเขียนWeb Componentซึ่งจะแก้ไข SVG เป็นข้อความในขณะทำงาน เผยแพร่ในส่วนของเนื้อหาพร้อมลิงก์ไปยัง JSFiddle

👍ตัวกรอง: กลับ (42%) ซีเปีย (93%) อิ่มตัว (1352%) ความเข้มของสีหมุน (87deg) ความสว่าง (119%) ความคมชัด (119%);

<html>

<head>
  <title>SVG with color</title>
</head>

<body>
  <script>
    (function () {
      const createSvg = (color = '#ff9933') => `
          <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="76px" height="22px" viewBox="-0.5 -0.5 76 22">
            <defs/>
              <g>
                <ellipse cx="5" cy="10" rx="5" ry="5" fill="#ff9933" stroke="none" pointer-events="all"/>
                <ellipse cx="70" cy="10" rx="5" ry="5" fill="#ff9933" stroke="none" pointer-events="all"/>
                <path d="M 9.47 12.24 L 17.24 16.12 Q 25 20 30 13 L 32.5 9.5 Q 35 6 40 9 L 42.5 10.5 Q 45 12 50 6 L 52.5 3 Q 55 0 60.73 3.23 L 66.46 6.46" fill="none" stroke="#ff9933" stroke-miterlimit="10" pointer-events="stroke"/>
              </g>
          </svg>`.split('#ff9933').join(color);

      function SvgWithColor() {
        const div = Reflect.construct(HTMLElement, [], SvgWithColor);
        const color = div.hasAttribute('color') ? div.getAttribute('color') : 'cyan';
        div.innerHTML = createSvg(color);
        return div;
      }

      SvgWithColor.prototype = Object.create(HTMLElement.prototype);
      customElements.define('svg-with-color', SvgWithColor);

      document.body.innerHTML += `<svg-with-color
        color='magenta' 
      ></svg-with-color>`;

    })();

  </script>
</body>

</html>

-1

วิธีที่เข้ากันได้กับ Bootstrap สั้นที่สุดไม่มี JavaScript:

.cameraicon {
height: 1.6em;/* set your own icon size */
mask: url(/camera.svg); /* path to your image */
-webkit-mask: url(/camera.svg) no-repeat center;
}

และใช้มันเช่น:

<td class="text-center">
    <div class="bg-secondary cameraicon"/><!-- "bg-secondary" sets actual color of your icon -->
</td>

-1

เปิดภาพของคุณโดยใช้เบราว์เซอร์คลิกขวาที่ภาพคลิกที่แหล่งที่มาของหน้าดูและคุณจะเห็นแท็ก svg ของภาพ จัดการและวางลงใน html ของคุณจากนั้นเปลี่ยนสีให้เป็นสีที่คุณต้องการ


คำตอบที่ได้รับการยอมรับแล้วแสดงให้เห็น inlining แล้วการตั้งค่าสีเป็นวิธีการแก้ปัญหา
Robert Longson

-1

เพียงเพิ่มการเติม: "ที่ต้องการสี" ในแท็ก svg ของภาพ: ตัวอย่าง:

<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#bbb9c6">
<path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"/><path d="M0 0h24v24H0z" fill="none"/></svg>

นั่นเป็นข้อเสนอแนะเดียวกับคำตอบนี้
Robert Longson

คำตอบเหล่านั้นได้กล่าวถึงการกรอกข้อมูลในแท็กเส้นทางมันใช้งานได้สำหรับฉันในแท็ก svg ดังนั้นฉันโพสต์มัน
Shivani
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.