img src SVG Изменение цвета заливки

231

HTML

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

CSS

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

Выше svg загружается и является изначально fill: #fff, но когда я использую вышеуказанный css, чтобы попробовать изменить его на черный, он не изменяется, это мой первый раз, когда я играю с SVG, и я не уверен, почему он не работа.

Показать ещё 2 комментария
Теги:
svg
image

14 ответов

202
Лучший ответ

Вам нужно, чтобы SVG был встроенным SVG. Вы можете использовать этот script, добавив к изображению класс svg:

/*
 * Replace all SVG images with inline SVG
 */
jQuery('img.svg').each(function(){
    var $img = jQuery(this);
    var imgID = $img.attr('id');
    var imgClass = $img.attr('class');
    var imgURL = $img.attr('src');

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

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

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

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

        // Replace image with new SVG
        $img.replaceWith($svg);

    }, 'xml');

});

И тогда, теперь, если вы выполните:

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

Или может быть:

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

Это работает!

Fiddle: http://jsfiddle.net/wuSF7/462/

Кредиты для вышеуказанного script: Как изменить цвет изображения SVG с помощью CSS (замена изображения SVG для jQuery)?

  • 1
    Если вы хотите использовать этот скрипт для нескольких скриптов, я немного адаптировал скрипт. jsfiddle.net/wuSF7/31
  • 2
    Эй, это плохая задница !! Это действительно крутой трюк. Я не уверен, насколько это "хорошо", хотя, ты понимаешь, о чем я? Это кажется очень хакерским. Хотя стоит сказать: действительно крутой и креативный ответ, просто не уверен, что я когда-нибудь так поступлю. Тем не менее, чтобы сыграть в защиту дьяволов, не хотите ли вы использовать что-то вроде использования атрибута данных вместо атрибута src, чтобы предотвратить загрузку ресурса два раза? Или кеш браузера просто вернет этот второй запрос? Хммм .. любопытно.
Показать ещё 27 комментариев
99

Если ваша цель - просто изменить цвет логотипа, и вам НЕОБХОДИМО использовать CSS, тогда не используйте javascript или jquery, как было предложено в некоторых предыдущих ответах.

Чтобы точно ответить на исходный вопрос, просто:

  • Откройте logo.svg в текстовом редакторе.

  • найдите 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>

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

  • 3
    ... и если "заливка" отсутствует, вы можете просто добавить ее к <path fill="#777777" d="m129.774,74.409c-5.523,... path или circle , например, <path fill="#777777" d="m129.774,74.409c-5.523,...
  • 0
    Хорошо для производительности мобильного браузера
Показать ещё 3 комментария
42

Вы можете установить 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/

Обратите внимание, что этот метод не работает для браузера Edge. Вы можете проверить это, перейдя на этот сайт: https://caniuse.com/#search=mask

  • 2
    Так что ни для чего, кроме внутреннего сайта, непригодного для использования.
  • 6
    89% глобальная поддержка по состоянию на 29 мая 2016 года.
Показать ещё 4 комментария
15

Попробуйте чистый 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/img-svg-fill/

  • 0
    На Edge был другой цвет, чем в других браузерах с одной из моих недавних попыток.
  • 0
    Это работает в большинстве браузеров, но у меня были некоторые проблемы с браузером IOS-Safari.
15

Ответ от @Praveen прочен.

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

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');
});
  • 0
    Разве это не сработало бы, если бы SVG был встроенным для начала?
  • 0
    Да, но если вы работаете со многими SVG-файлами или регулярно обновляете их, это очень сложно.
11

Этот ответ основан на ответе https://stackoverflow.com/questions/24933430/img-src-svg-changing-the-fill-color но с простой версией 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 ID to the new SVG
        if(typeof imgID !== 'undefined') {
            svg.setAttribute('id', imgID);
        }
        // Add replaced image 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");
Показать ещё 3 комментария
11

Почему бы не создать webfont с вашим изображением или изображениями svg, импортировать webfont в css, а затем просто изменить цвет глифа, используя атрибут цвета css? Нет необходимости в javascript

  • 2
    Если ваш svg имеет несколько элементов разных цветов, это решение становится очень хакерским (несколько элементов вставляются).
  • 0
    @kakaja Это решение предназначено только для векторных изображений с одним цветом. см. ответ bpulecio для более подробной информации
Показать ещё 5 комментариев
9

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
    Какая поддержка браузера для этого
  • 0
    @KevinGoedecke Chrome, Firefox, Safari и Edge
Показать ещё 4 комментария
5

Чтобы расширить ответ на @gringo, работает Javascript-метод, описанный в других ответах, но требует, чтобы пользователь загружал ненужные файлы изображений, и IMO, он раздувает ваш код.

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

Если вы предпочитаете более ориентированную на dev, вы можете использовать "npm svg webfont" Google и использовать один из модулей узлов, наиболее подходящих для вашей среды.

Однажды вы сделали один из этих двух вариантов, затем вы можете легко изменить цвет с помощью CSS, и, скорее всего, вы ускорили ваш сайт в процессе.

  • 0
    Вы должны попробовать SVG спрайты. По моему опыту, веб-шрифты имеют случайные проблемы между выпусками браузера. Попробуйте это: fontastic.me - но используйте версии SVG-спрайтов - и посмотрите, что вы думаете. :)
3

Сначала вам нужно ввести 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, чтобы избежать повторения одного и того же ID в документе, если SVG вводится несколько раз.

SVGInject - это простой Javascript и работает со всеми браузерами, поддерживающими SVG.

Отказ от ответственности: я являюсь соавтором SVGInject

2

Основная проблема в вашем случае заключается в том, что вы импортируете svg из <img> который скроет структуру SVG.

Вам нужно использовать <svg> в сочетании с <use> чтобы получить желаемый эффект. Чтобы заставить его работать, вам нужно <path id='myName'...> id пути, который вы хотите использовать в файле SVG <path id='myName'...> чтобы затем получить их из <use xlink:href="#myName"/>. Попробуйте отрезать внизу.

.icon {
  display: inline-block;
  width: 2em;
  height: 2em;
  transition: .5s;
  fill: currentColor;
  stroke-width: 5;
  }
  .icon:hover {
    fill: rgba(255,255,255,0);
    stroke: black;
    stroke-width: 2;
    }

.red {
  color: red;
  }

.blue {
  color: blue;
  }
<svg width="0" height="0">
  <defs>
    <path id="home" d="M100 59.375l-18.75-18.75v-28.125h-12.5v15.625l-18.75-18.75-50 50v3.125h12.5v31.25h31.25v-18.75h12.5v18.75h31.25v-31.25h12.5z"/>
</svg>

  
  <span class="icon red">
          <svg viewbox="0 0 100 100">
            <use xlink:href="#home"/>
          </svg>
        </span>
  
    <span class="icon blue">
          <svg viewbox="0 0 100 100">
            <use xlink:href="#home"/>
          </svg>
        </span>

Обратите внимание, что вы можете поместить любой URL перед фрагментом # если вы хотите загрузить SVG из внешнего источника (а не вставлять его в свой HTML). Кроме того, обычно вы не указываете заполнение в CSS. Лучше рассмотреть возможность использования fill:"currentColor" в самом SVG. Соответствующее значение цвета CSS элемента будет использовано на месте.

0

Знайте, что это старый вопрос, но недавно мы столкнулись с той же проблемой и решили ее со стороны сервера. Это конкретный ответ php, но я уверен, что другие envs имеют что-то похожее. вместо использования тега 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 - это в основном код, вам нужно просто содержимое. Я использовал PHP для получения контента, но вы можете использовать все, что захотите.

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

Затем я печатал содержимое "как есть" внутри контейнера div

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

Чтобы финализировать правило для контейнеров SVG childs на CSS

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

Я получил эти результаты с помощью значка материала SVG:

Mozilla Firefox 59.0.2 (64-разрядная версия) Linux

Изображение 6081

Google Chrome66.0.3359.181 (Build oficial) (64 бит) Linux

Изображение 6082

Opera 53.0.2907.37 Linux

Изображение 6083

  • 0
    Я не могу понизить голос, но, пожалуйста, никогда не делай этого.
  • 1
    Причины? Альтернативы?
0

Если у вас есть доступ к JQuery, то, переходя к ответу Правэна, можно программно изменить цвет различных вложенных элементов внутри SVG:

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

Внутри find вы можете указать разные элементы, которые необходимо изменить в цвете.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню