Làm thế nào để thay đổi màu sắc của một yếu tố svg?


346

Tôi muốn sử dụng kỹ thuật này http://css-tricks.com/svg-fallbacks/ và thay đổi màu sắc của Svg nhưng cho đến nay tôi vẫn chưa thể làm được. Tôi đặt cái này trong css nhưng hình ảnh của tôi luôn đen, không có vấn đề gì. Mã của tôi:

.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>


Tôi không phải là chuyên gia về Svg, nhưng bạn đã thử thay đổi màu thành màu nền chưa?
Meg

@Megan trong màu nền của Svg được chỉ định bằng thuộc tính 'điền' và đường viền có 'nét' (như bạn sẽ làm trong Illustrator). w3.org/TR/SVG/propidx.html
Barbara

4
CSS từ tài liệu HTML của bạn sẽ không áp dụng cho các thành phần SVG trong <img />
pawel

1
Điều này là có thể bây giờ. Câu trả lời đơn giản và đầy đủ chức năng tại đây: stackoverflow.com/a/53336754/467240
mtyson

Câu trả lời:


188

Bạn không thể thay đổi màu sắc của hình ảnh theo cách đó. Nếu bạn tải SVG dưới dạng hình ảnh, bạn không thể thay đổi cách hiển thị bằng CSS hoặc Javascript trong trình duyệt.

Nếu bạn muốn thay đổi hình ảnh SVG của bạn, bạn phải tải nó sử dụng <object>, <iframe>hoặc sử dụng <svg>inline.

Nếu bạn muốn sử dụng các kỹ thuật trong trang, bạn cần thư viện Modernizr, nơi bạn có thể kiểm tra hỗ trợ SVG và hiển thị có điều kiện hoặc không hiển thị hình ảnh dự phòng. Sau đó, bạn có thể nội tuyến SVG của bạn và áp dụng các phong cách bạn cần.

Xem :

Bạn có thể nội tuyến SVG của bạn, gắn thẻ hình ảnh dự phòng của bạn với một tên lớp ( 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" />

Và trong CSS, sử dụng no-svglớp từ Modernizr (CDN: http://ajax.aspnetcdn.com/ajax/modernizr/modernizr-2.7.2.js ) để kiểm tra hỗ trợ SVG. Nếu không có hỗ trợ SVG, khối SVG sẽ bị bỏ qua và hình ảnh sẽ được hiển thị, nếu không hình ảnh sẽ bị xóa khỏi cây DOM ( display: none):

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

Sau đó, bạn có thể thay đổi màu của phần tử nội tuyến của bạn:

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

5
Bạn không thể tạo kiểu objectSVG nhúng từ tài liệu lưu trữ.
Javier Rey

1
@JavierRey bạn có thể đưa kiểu dáng vào nội dung của thẻ đối tượng thông qua javascript. Nhưng bạn đúng là nó không áp dụng nếu bạn chỉ thêm nó vào biểu định kiểu của tài liệu lưu trữ.
Robert Longson

2
Tôi đang sử dụng giải pháp từ @ manish-menaria và nó hoạt động hoàn hảo.
Ryan Ellis

1
Câu trả lời được chấp nhận nên được đổi thành: stackoverflow.com/a/53336754/467240
mtyson

374

2020 trả lời

Bộ lọc CSS hoạt động trên tất cả các trình duyệt hiện tại

Để thay đổi bất kỳ màu SVG nào

  1. Thêm hình ảnh SVG bằng cách sử dụng một <img>thẻ.
<img src="dotted-arrow.svg" class="filter-green"/>
  1. Để lọc thành một màu cụ thể, hãy sử dụng Codepen sau (Bấm vào đây để mở codepen) để chuyển đổi mã màu hex thành bộ lọc CSS:

Ví dụ: đầu ra cho #00EE00

filter: invert(42%) sepia(93%) saturate(1352%) hue-rotate(87deg) brightness(119%) contrast(119%);
  1. Thêm CSS filtervào lớp này.
    .filter-green{
        filter: invert(48%) sepia(79%) saturate(2476%) hue-rotate(86deg) brightness(118%) contrast(119%);
    }

5
Điều này đi kèm với cảnh báo thông thường về việc không được hỗ trợ trong các phiên bản trình duyệt cũ hơn: developer.mozilla.org/en-US/docs/Web/CSS/
Kẻ

17
Như đã lưu ý trong CodePen, nếu SVG của bạn không có màu đen (của tôi là màu xám), việc thêm brightness(0) saturate(100%)vào đầu danh sách các bộ lọc trước tiên sẽ biến nó thành màu đen 100%, cho phép các bộ lọc khác thay đổi nó thành màu chính xác.
vui vẻ

2
Ngoài ra, rất nhiều nền tảng hấp dẫn về giải pháp trong câu hỏi StackOverflow này đã thông báo cho CodePen.
vui vẻ

3
Chàng trai của tôi. Sự hỗ trợ có vẻ chấp nhận được caniuse.com/#feat=css-filters .
Sam Doidge

hoạt động rất tốt, đã sử dụng codepen không liên kết này để đưa hex của tôi vào bộ lọc: codepen.io/sosuke/pen/Pjoqqp
WEBjuju

220

Để thay đổi màu của bất kỳ SVG nào, bạn có thể trực tiếp thay đổi mã svg bằng cách mở tệp svg trong bất kỳ trình soạn thảo văn bản nào . Mã có thể trông giống như mã dưới đây

<?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>

Bạn có thể quan sát rằng có một số thẻ XML như đường, hình tròn, đa giác vv . Ở đó bạn có thể thêm màu của riêng bạn với sự trợ giúp của thuộc tính style . Nhìn vào ví dụ dưới đây

<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"/>

Thêm thuộc tính kiểu cho tất cả các thẻ để bạn có thể nhận được SVG của màu bạn yêu cầu


48
Tại sao không chỉ sử dụng thuộc tính fillnhư thế này : fill = "#AB7C94"? Không chắc chắn tại sao stylethuộc tính là cần thiết
bg17aw

4
Xin chào Daniel, vâng nó hoạt động. Tôi không biết rằng điền có thể được sử dụng như một thuộc tính. Xin lỗi vì đã không nhận thấy bình luận của bạn quá lâu @ bg17aw
sushant047

30

Đã thêm một trang thử nghiệm - để tô màu SVG thông qua cài đặt Bộ lọc:

VÍ DỤ filter: invert(0.5) sepia(1) saturate(5) hue-rotate(175deg)

Tải lên & tô màu SVG của bạn - Jsfiddle

Lấy ý tưởng từ: https://blog.union.io/code/2017/08/10/img-svg-fill/


1
Cảm ơn, bạn chỉ cứu tôi khỏi bản thân mình. .custom-disabled > svg {filter:invert(0.2) sepia(1) saturte(0) hue-rotate(0);}chỉ làm công việc tôi cần để tắt biểu tượng.
roger

19

Chỉ có SVG với thông tin đường dẫn . bạn không thể làm điều đó với hình ảnh .. vì đường dẫn bạn có thể thay đổi đột quỵ và điền thông tin và bạn đã hoàn thành. như Illustrator

vì vậy: thông qua CSS, bạn có thể ghi đè fillgiá trị đường dẫn

path { fill: orange; }

nhưng nếu bạn muốn cách linh hoạt hơn khi bạn muốn thay đổi nó bằng một văn bản khi có một số hiệu ứng lơ lửng đang diễn ra .. hãy sử dụng

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

cách dễ nhất là tạo một phông chữ ra khỏi SVG bằng cách sử dụng một dịch vụ như https://icomoon.io/app/#/select hoặc như vậy. tải lên SVG của bạn, nhấp vào "tạo phông chữ", bao gồm các tệp phông chữ và css vào bên cạnh của bạn và chỉ cần sử dụng và định kiểu nó như bất kỳ văn bản nào khác. Tôi luôn sử dụng nó như thế này vì nó làm cho kiểu dáng dễ dàng hơn nhiều.

EDIT: Như đã đề cập trong bài viết được bình luận bởi phông chữ biểu tượng @ CodeMouse92 làm rối trình đọc màn hình (và có thể xấu cho SEO). Vì vậy, thay vì gắn bó với các SVG.


4
Nó cũng làm rối trình đọc màn hình. Xem "Phông chữ chết cho biểu tượng" của Seren Davies
CodeMouse92

6

Bạn có thể thay đổi màu SVG bằng css nếu bạn sử dụng một số thủ thuật. Tôi đã viết một kịch bản nhỏ cho điều đó.

  • đi qua một danh sách các yếu tố có hình ảnh svg
  • tải tập tin svg dưới dạng xml
  • chỉ lấy phần của Svg
  • thay đổi màu sắc của con đường
  • thay thế src bằng svg đã sửa đổi thành hình ảnh nội tuyến
$('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')));
  });

});

đoạn mã trên có thể không hoạt động chính xác, tôi đã triển khai mã này cho các phần tử có ảnh nền svg hoạt động gần giống với mã này. Nhưng dù sao bạn cũng phải sửa đổi tập lệnh này để phù hợp với trường hợp của bạn. hy vọng nó sẽ giúp


Nhân tiện: Nếu bạn là nhà phát triển RoR, bạn có thể thêm một phương thức mới cho trình biên dịch trước sass cũng có thể thực hiện công việc. Điều này tốt hơn nhiều vì bạn sẽ có mã cơ sở được mã hóa, tô màu chính xác64 trong tệp css đã biên dịch của bạn. Không cần JS nữa! Có lẽ tôi có thể cung cấp mã tôi đã viết, phải nói chuyện với CTO.
cydoc

2
+1 để cung cấp giải pháp, thay vì nói rằng không thể thực hiện được. Câu trả lời này cũng có liên quan: stackoverflow.com/questions/11978995/ từ
claytronicon

6

Mặt nạ SVG trên thành phần hộp có màu nền sẽ cho kết quả:

.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>


Lưu ý - Mặt nạ SVG không được hỗ trợ trong trình duyệt Internet Explorer


5

Nhắm mục tiêu đường dẫn trong svg:

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

Bạn có thể thực hiện nội tuyến, như:

<path fill="#ccc">

Hoặc là

svg{
   path{
        fill: #ccc


2

Nếu bạn muốn làm điều này với một Svg nội tuyến, ví dụ, một hình nền trong css của bạn:

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");

tất nhiên, thay thế ... bằng mã hình ảnh nội tuyến của bạn


2

Ví dụ: trong HTML của bạn:

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

Sử dụng jQuery:

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

Điều này chỉ hoạt động nếu bạn bao gồm tệp SVG nội tuyến trong HTML. Tôi đã chỉnh sửa câu trả lời của bạn để làm rõ điều này.
Flimm

0

Trên thực tế, có một giải pháp khá linh hoạt hơn cho vấn đề này: viết một Thành phần Web sẽ vá SVG dưới dạng văn bản trong thời gian chạy. Cũng được xuất bản trong ý chính với một liên kết đến JSFiddle

👍 bộ lọc: đảo ngược (42%) nâu đỏ (93%) bão hòa (1352%) độ sáng màu xoay (87deg) (119%) độ tương phản (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

Cách tương thích Bootstrap ngắn nhất, không có 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;
}

và sử dụng nó như:

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

-1

Mở hình ảnh của bạn bằng trình duyệt, nhấp chuột phải vào hình ảnh nhấp vào nguồn trang xem và bạn sẽ thấy thẻ svg của hình ảnh. Đối phó và dán vào html của bạn, sau đó thay đổi màu tô thành màu bạn chọn


Các câu trả lời được chấp nhận đã cho thấy nội tuyến và sau đó thiết lập các màu sắc như các giải pháp.
Robert Longson

-1

Đơn giản chỉ cần thêm điền: "wishColor" trong thẻ svg của hình ảnh: ví dụ:

<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>

Về cơ bản đó là cùng một gợi ý như câu trả lời này
Robert Longson

những câu trả lời đã đề cập điền vào thẻ đường dẫn, nó hoạt động với tôi trong thẻ svg, do đó tôi đã đăng nó
Shivani
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.