img src SVG зміни стилів за допомогою CSS


373

html

<img src="logo.svg" alt="Logo" class="logo-img">

css

.logo-img path {
  fill: #000;
}

Наведений вище SVG завантажується і є вродженим, fill: #fffале коли я використовую вище, cssщоб спробувати змінити його на чорний, він не змінюється, це вперше я граю зі SVG, і я не впевнений, чому це не працює.


25
Ви не можете впливати на SVG- зображення таким чином ... лише вбудовані елементи SVG
Paulie_D


Перевірте мою відповідь тут, щоб використовувати вміст SVG та CSS. stackoverflow.com/questions/11978995/…
Бенджамін

Відповіді:


153

Якщо ваша мета - просто змінити колір логотипу, і вам не обов'язково НЕОБХІДНО використовувати CSS, тоді не використовуйте JavaScript або jquery, як було запропоновано в попередніх відповідях.

Щоб точно відповісти на початкове запитання, просто:

  1. Відкрийте свій logo.svgтекстовий редактор.

  2. шукати fill: #fffі замінювати йогоfill: #000

Наприклад, це logo.svgможе виглядати приблизно так, коли відкриється в текстовому редакторі:

<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
  <path d="M0 0h24v24H0z" fill="none"/>
  <path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z" fill="#fff"/>
</svg>

... просто змінити заливку і зберегти.


6
... і якщо немає «заливки», ви можете просто додати його до pathабо circleпредметів , як <path fill="#777777" d="m129.774,74.409c-5.523,....
SaeX

1
що робити, якщо мій логотип має один колір на заголовку та інший колір на колонтитулі?
rubens.lopes

. @ ruben.lopes два найрізноманітніші файли, або два різних рядки, буде найпростішим
Rowe Morehouse

11
Ви також можете використовувати fill="currentColor"тодішній colorбатьківський елемент css-tricks.com/cascading-svg-fill-color
Сергій

10
Це, очевидно, можливо і не дуже корисна відповідь.
Timmmm

102

Ви можете встановити SVG як маску. Таким чином, встановлення кольору тла буде виконувати роль вашого кольору заливки.

HTML

<div class="logo"></div>

CSS

.logo {
    background-color: red;
    -webkit-mask: url(logo.svg) no-repeat center;
    mask: url(logo.svg) no-repeat center;
}

JSFiddle: https://jsfiddle.net/KuhlTime/2j8exgcb/
MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/mask

Перевірте, чи підтримує ваш браузер цю функцію: https://caniuse.com/#search=mask


3
Тож ні для чого, крім внутрішнього веб-сайту, непридатний.
Генрік Венделбо

9
89% глобальної підтримки станом на 29 травня 2016 р.
Gajus

1
Це дивовижне рішення для таких ситуацій, як описано тут , де використання чого-небудь іншого, крім урину даних у CSS, є біль. Дякую!
Гарк Гарсія

3
не працює. він говорить , що maskце invalid property value. я тестую це в хромі.
Eren555

1
@MadMac Я використовую ту саму версію Chrome, але мені не вдалося повторити таку поведінку. Це JSFiddle, який ви пробували, або ваш код?
Андре Кульман

78

Спробуйте чистий CSS:

.logo-img {
  // to black
  filter: invert(1);
  // or to blue
  // filter: invert(1) sepia(1) saturate(5) hue-rotate(175deg);
}

більше інформації в цій статті https://blog.union.io/code/2017/08/10/10/img-svg-fill/


Один із моїх спроб останнім часом отримував на Edge інший колір, ніж в інших браузерах.
Джулікс

4
Це працює в самому браузері, але у мене виникли проблеми з браузером IOS-Safari.
Саймон Людвіг

30

2018: Якщо ви хочете динамічного кольору, не хочете використовувати javascript і не хочете вбудованого SVG, використовуйте змінну CSS. Працює в Chrome, Firefox та Safari. edit: і Edge

<svg>
    <use xlink:href="logo.svg" style="--color_fill: #000;"></use>
</svg>

У вашому SVG замінити всі екземпляри style="fill: #000"з style="fill: var(--color_fill)".


1
Яка

@KevinGoedecke Chrome, Firefox, Safari and Edge
northamerican

4
Здається, застарілий у SVG 2
vsync

5
@northamerican - посилання на інші відповіді stackoverflow як "докази" не мають значення. кожен може написати що завгодно на цій платформі. MDN:"This feature has been removed from the Web standards. Though some browsers may still support it, it is in the process of being dropped"
vsync

8
Здається, xlink:hrefце застаріло на користь href. Тож це ще може спрацювати.
Бенджамін Інталь

20

Спочатку доведеться ввести SVG у HTML DOM.

Існує бібліотека з відкритим кодом під назвою SVGInject, яка робить це для вас. Він використовує onloadатрибут для запуску ін'єкції.

Ось мінімальний приклад використання SVGInject:

<html>
  <head>
    <script src="svg-inject.min.js"></script>
  </head>
  <body>
    <img src="image.svg" onload="SVGInject(this)" />
  </body>
</html>

Після завантаження зображення onload="SVGInject(this)запустить ін'єкцію, і <img>елемент буде замінено вмістом файлу SVG, наданого в srcатрибуті.

Він вирішує кілька проблем із ін'єкцією SVG:

  1. SVG-файли можна приховати, поки ін'єкція не закінчиться. Це важливо, якщо стиль вже застосовується під час завантаження, що в противному випадку спричинить короткий "неспокійний спалах вмісту".

  2. Ці <img>елементи вводять себе автоматично. Якщо ви додаєте SVG динамічно, вам не доведеться турбуватися про виклик ін'єкційної функції знову.

  3. До кожного ідентифікатора в SVG додається випадкова рядок, щоб у документі не було одного і того ж ідентифікатора кілька разів, якщо SVG вводиться більше одного разу.

SVGInject - це звичайний Javascript і працює з усіма браузерами, які підтримують SVG.

Відмова: Я є співавтором SVGInject


3
Це найпростіша відповідь. Я тестував його в Chrome, Firefox та Edge, і він працює чудово.
Себастьян Лоріон

15

Відповідь від @Praveen є твердою.

Я не міг змусити його відповісти у своїй роботі, тому я зробив функцію наведення jquery для цього.

CSS

.svg path {
   transition:0.3s all !important;
}

JS / JQuery

// code from above wrapped into a function
replaceSVG();

// hover function
// hover over an element, and find the SVG that you want to change
$('.element').hover(function() {
    var el = $(this);
    var svg = el.find('svg path');
    svg.attr('fill', '#CCC');
}, function() {
    var el = $(this);
    var svg = el.find('svg path');
    svg.attr('fill', '#3A3A3A');
});

1
Це не спрацювало б лише, якщо SVG був на початку?
Даніель Томпсон

Так - але якщо ви працюєте з багатьма файлами SVG або регулярно оновлюєте їх, керувати болем.
Метт Вуек

15

Чому б не створити веб-шрифт зі своїм svg зображенням або зображеннями, імпортувати веб-шрифт у css, а потім просто змінити колір гліфа за допомогою атрибута css color? Не потрібно JavaScript


5
Якщо у вашому svg є декілька елементів різного кольору, це рішення стає дуже хитким (кілька елементів вставлено).
kakaja

1
@kakaja Це рішення лише для векторних зображень, які мають у собі 1 колір. дивіться відповідь bpulecio для більш детальної інформації
gringo

1
Тому що значок - це не текст. Шрифти призначені для тексту. Svgs призначені для ікон.
Лазар Любенович

2
@ LazarLjubenović - технічно текст складається з символів, які є символами, а піктограми - також символами, тому багато хто не має проблем із використанням шрифтів значків. це просто як створення "іншої" текстуальної мови. Мандарин використовує «ікони», а не букви, також не рідкість в людстві використовувати іконки як «текст»
vsync

1
в той час як це звучить як цікаве рішення, я дуже рекомендую детальніше відповісти детальніше, як "як" замість "чому б ні"
YakovL

15

Ця відповідь ґрунтується на відповіді https://stackoverflow.com/a/24933495/3890888, але із звичайною версією JavaScript, що використовується там.

Вам потрібно зробити SVG, щоб він був вбудованим SVG . Ви можете скористатися цим сценарієм, додавши svgдо зображення клас :

/*
 * Replace all SVG images with inline SVG
 */
document.querySelectorAll('img.svg').forEach(function(img){
    var imgID = img.id;
    var imgClass = img.className;
    var imgURL = img.src;

    fetch(imgURL).then(function(response) {
        return response.text();
    }).then(function(text){

        var parser = new DOMParser();
        var xmlDoc = parser.parseFromString(text, "text/xml");

        // Get the SVG tag, ignore the rest
        var svg = xmlDoc.getElementsByTagName('svg')[0];

        // Add replaced image's ID to the new SVG
        if(typeof imgID !== 'undefined') {
            svg.setAttribute('id', imgID);
        }
        // Add replaced image's classes to the new SVG
        if(typeof imgClass !== 'undefined') {
            svg.setAttribute('class', imgClass+' replaced-svg');
        }

        // Remove any invalid XML tags as per http://validator.w3.org
        svg.removeAttribute('xmlns:a');

        // Check if the viewport is set, if the viewport is not set the SVG wont't scale.
        if(!svg.getAttribute('viewBox') && svg.getAttribute('height') && svg.getAttribute('width')) {
            svg.setAttribute('viewBox', '0 0 ' + svg.getAttribute('height') + ' ' + svg.getAttribute('width'))
        }

        // Replace image with new SVG
        img.parentNode.replaceChild(svg, img);

    });

});

І тоді, якщо ви робите:

.logo-img path {
  fill: #000;
}

Або можливо:

.logo-img path {
  background-color: #000;
}

JSFiddle: http://jsfiddle.net/erxu0dzz/1/


1
Чудово .. працює. крім того, якщо на нашій сторінці є декілька svgs, нам потрібно буде поставити блок отримання в IIFE.
Сандіп Шарма

1
Чудово! Добре працює з ES6. Якщо вам не байдуже IE 9, ви навіть можете скористатись: parser.parseFromString(text, "image/svg+xml");
ChristoKiwi

Не працює в UIWebView на iOS 9.3.5. Я думаю, це може бути пов’язано з використанням fetchякого було додано до Safari в 10.1 ( developer.mozilla.org/en-US/docs/Web/API/Fetch_API ). Версія jQuery вище працює.
Марія-Інес Каррера

7

Використовуйте фільтри для перетворення в будь-який колір.

Нещодавно я знайшов це рішення, і сподіваюся, що хтось, можливо, зможе ним скористатися. Оскільки рішення використовує фільтри, його можна використовувати з будь-яким типом зображення. Не тільки svg.

Якщо у вас є одноколірне зображення, яке ви просто хочете змінити колір, ви можете зробити це за допомогою деяких фільтрів. Він, звичайно, також працює на багатобарвних зображеннях, але ви не можете орієнтуватися на конкретний колір. Лише весь образ.

Фільтри вийшли із сценарію, запропонованого в розділі Як перетворити чорний колір у будь-який заданий колір, використовуючи лише фільтри CSS. Якщо ви хочете змінити білий на будь-який колір, ви можете налаштувати значення інвертування у кожному фільтрі.

.startAsBlack{
  display: inline-block;
  width: 50px;
  height: 50px;
  background: black;
}

.black-green{
  filter: invert(43%) sepia(96%) saturate(1237%) hue-rotate(88deg) brightness(128%) contrast(119%);
}

.black-red{
  filter: invert(37%) sepia(93%) saturate(7471%) hue-rotate(356deg) brightness(91%) contrast(135%);
}

.black-blue{
  filter: invert(12%) sepia(83%) saturate(5841%) hue-rotate(244deg) brightness(87%) contrast(153%);
}

.black-purple{
  filter: invert(18%) sepia(98%) saturate(2657%) hue-rotate(289deg) brightness(121%) contrast(140%);
}
Black to any color: <br/>
<div class="startAsBlack black-green"></div>
<div class="startAsBlack black-red"></div>
<div class="startAsBlack black-blue"></div>
<div class="startAsBlack black-purple"></div>


4

Для розширення відповіді на @gringo метод Javascript, описаний в інших відповідях, працює, але вимагає, щоб користувач завантажував непотрібні файли зображень, а IMO він розмиває ваш код.

Я думаю, що кращим підходом було б перенести всю одноколірну векторну графіку у файл веб-шрифту. Раніше я використовував Fort Awesome , і це чудово поєднує ваші власні піктограми / зображення у форматі SVG, а також будь-які сторонні піктограми, які ви можете використовувати (Awesome Font, Bootstrap тощо) в один файл веб-шрифту користувач має завантажити. Ви також можете налаштувати його, тому ви включаєте лише піктограми сторонніх виробників, які ви використовуєте. Це зменшує кількість запитів на сторінку, і ви загальну вагу сторінки, особливо якщо ви вже включаєте будь-які бібліотеки сторонніх іконок.

Якщо ви віддаєте перевагу більш орієнтованому на розробку варіант, ви можете Google "npm svg webfont" і використовувати один із модулів вузлів, найбільш відповідний для вашого середовища.

Після того, як ви зробили будь-який із цих двох варіантів, ви могли легко змінити колір за допомогою CSS, і, швидше за все, ви прискорили свій сайт у процесі.


Спробуйте спрагти SVG. На мій досвід, веб-шрифти мають випадкові проблеми між версіями браузера. Спробуйте це: fontastic.me - але використовуйте версії спрайтів SVG - і подивіться, що ви думаєте. :)
sheriffderek

4

Якщо ви просто перемикаєте зображення між реальним кольором та чорно-білим, ви можете встановити один селектор як:

{filter: none;}

та інший як:

{filter:grayscale(100%);}

3

Простий ..

Ви можете використовувати цей код:

<svg class="logo">
  <use xlink:href="../../static/icons/logo.svg#Capa_1"></use>
</svg>

Спочатку вкажіть шлях до svg, а потім напишіть його ідентифікатор. У цьому випадку "Capa_1". Ви можете отримати ідентифікатор svg, відкривши його в будь-якому редакторі.

У css:

.logo {
  fill: red;
}

kabrice, Ви можете використовувати цей код codepen.io/hmzajmal/pen/ZEGvWYa
Hamza Jamal

2

Основна проблема у вашому випадку полягає в тому, що ви імпортуєте svg з <img>тегу, який приховає структуру SVG.

Щоб отримати бажаний ефект, ви повинні використовувати <svg>тег спільно з <use>. Щоб він працював, вам потрібно вказати idшлях, який ви хочете використовувати у файлі SVG, <path id='myName'...>щоб потім мати можливість отримати їх з <use xlink:href="#myName"/>тегу. Спробуйте фрагменти нижче.

Зауважте, що ви можете поставити будь-яку URL-адресу перед фрагментом, #якщо ви хочете завантажити SVG із зовнішнього джерела (а не вставляти його у свій HTML). Крім того, зазвичай ви не вказуєте заповнення у CSS. Краще розглянути можливість використання fill:"currentColor"всередині самого SVG. Потім буде використане значення кольору CSS відповідного елемента.


2

Оскільки SVG в основному код, вам потрібен лише вміст. Я використовував PHP для отримання вмісту, але ви можете використовувати все, що завгодно.

<?php
$content    = file_get_contents($pathToSVG);
?>

Потім я надрукував вміст "як є" всередині контейнера div

<div class="fill-class"><?php echo $content;?></div>

Щоб остаточно встановити правило для SVG-дочірок контейнера на CSS

.fill-class > svg { 
    fill: orange;
}

Я отримав ці результати за допомогою значка матеріалу SVG:

Mozilla Firefox 59.0.2 (64-розрядний) Linux

введіть тут опис зображення

Google Chrome66.0.3359.181 (build oficial) (64 біт) Linux

введіть тут опис зображення

Opera 53.0.2907.37 Linux

введіть тут опис зображення


Я не можу спростувати, але, будь ласка, ніколи цього не роблю.
шліфувальник

5
Причини? Альтернативи?
Бенджамін

Моя причина цього не робити полягає в тому, що це заважає браузеру кешувати SVG. Альтернативою є використання інжектора SVG, згаданого в кількох інших відповідях тут. Файл SVG все ще буде кешований браузером, а введений SVG все ще може бути стилізований за допомогою CSS. Але я не заперечую вас.
Sơn Trần-Nguyễn

Я розумію, але все одно кеш не згадується. Найкраща відповідь - код JavaScript, який можна перезавантажувати (чи ні) кожного разу за допомогою заголовка, закінчуючи маніпуляцію або примушуйте хеш після імені файлу link.Thanks for not downvote, але я все ще вважаю, що моя відповідь вирішує змінити SVG за допомогою атрибута CSS fill.
Бенджамін

2

Це може бути корисно для людей, які використовують PHPу поєднанні з.svg зображеннями, якими вони хочуть маніпулювати за допомогою CSS.

Ви не можете перезаписати властивості всередині тегу img за допомогою CSS. Але коли вихідний код svg буде вбудований у HTML, ви, безумовно, можете. Мені подобається вирішити цю проблему require_onceфункцією, куди я включаю.svg.php файл. Це як імпорт зображення, але ви все одно можете перезаписати стилі за допомогою CSS!

Спочатку включіть файл svg:

<?php require_once( '/assets/images/my-icon.svg.php' ); ?>

І він включає в себе цей значок, наприклад:

<svg xmlns="http://www.w3.org/2000/svg" width="20.666" height="59.084" viewBox="0 0 20.666 59.084"><g transform="translate(-639.749 -3139)"><path d="M648.536,3173.876c0-2.875-1.725-3.8-3.471-3.8-1.683,0-3.49.9-3.49,3.8,0,3,1.786,3.8,3.49,3.8C646.811,3177.676,648.536,3176.769,648.536,3173.876Zm-3.471,2.341c-.883,0-1.437-.513-1.437-2.341,0-1.971.615-2.381,1.437-2.381.862,0,1.438.349,1.438,2.381,0,1.907-.616,2.339-1.438,2.339Z" fill="#142312"/><path d="M653.471,3170.076a1.565,1.565,0,0,0-1.416.9l-6.558,13.888h1.2a1.565,1.565,0,0,0,1.416-.9l6.559-13.887Z" fill="#142312"/><path d="M655.107,3177.263c-1.684,0-3.471.9-3.471,3.8,0,3,1.766,3.8,3.471,3.8,1.745,0,3.49-.9,3.49-3.8C658.6,3178.186,656.851,3177.263,655.107,3177.263Zm0,6.139c-.884,0-1.438-.514-1.438-2.34,0-1.972.617-2.381,1.438-2.381.862,0,1.437.349,1.437,2.381,0,1.909-.616,2.34-1.437,2.34Z" fill="#142312"/><path d="M656.263,3159.023l-1.49-14.063a1.35,1.35,0,0,0,.329-.293,1.319,1.319,0,0,0,.268-1.123l-.753-3.49a1.328,1.328,0,0,0-1.306-1.054h-6.448a1.336,1.336,0,0,0-1.311,1.068l-.71,3.493a1.344,1.344,0,0,0,.276,1.112,1.532,1.532,0,0,0,.283.262l-1.489,14.087c-1.7,1.727-4.153,4.871-4.153,8.638v28.924a1.339,1.339,0,0,0,1.168,1.49,1.357,1.357,0,0,0,.17.01h17.981a1.366,1.366,0,0,0,1.337-1.366v-29.059C660.414,3163.893,657.963,3160.749,656.263,3159.023Zm-8.307-17.349h4.274l.176.815H647.79Zm9.785,43.634v10.1H642.434v-17.253a4.728,4.728,0,0,1-2.028-4.284,4.661,4.661,0,0,1,2.028-4.215v-2c0-3.162,2.581-5.986,3.687-7.059a1.356,1.356,0,0,0,.4-.819l1.542-14.614H652.1l1.545,14.618a1.362,1.362,0,0,0,.4.819c1.109,1.072,3.688,3.9,3.688,7.059v9.153a5.457,5.457,0,0,1,0,8.5Z" fill="#142312"/></g></svg>

Тепер ми можемо легко змінити такий колір заливки за допомогою CSS:

svg path {
  fill: blue;
}

Я спершу спробував вирішити цю проблему, file_get_contents()але рішення вище набагато швидше.


0

Знайте, що це давнє питання, але нещодавно ми зіткнулися з тим же питанням, і ми вирішили його з боку сервера. Це відповідь, що стосується php, але я впевнений, що в інших середовищ щось подібне. замість того, щоб використовувати тег img, ви візуалізуєте svg як svg з початку роботи.

public static function print_svg($file){
    $iconfile = new \DOMDocument();
    $iconfile->load($file);
    $tag = $iconfile->saveHTML($iconfile->getElementsByTagName('svg')[0]);
    return $tag;
}

тепер, коли ви надаєте файл, ви отримаєте повний вбудований svg


0

відкрийте значок svg у редакторі коду та додайте клас після тегу шляху:

<path class'colorToChange' ...

Ви можете додати клас до svg та змінити колір так:

кодоп


-2

Якщо у вас є доступ до JQuery, то, поширюючись на відповідь Правена, ви можете програмно змінити колір різних вкладених елементів всередині SVG шляхом:

$('svg').find('path, text').css('fill', '#ffffff');

У межах пошуку ви можете згадати різні елементи, які потрібно змінити в кольорі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.