Как изменить цвет изображения SVG с помощью CSS (замена изображения jQuery SVG)?

437

Это самостоятельные вопросы и ответы о полезном куске кода, который я придумал.

В настоящее время нет простого способа внедрить изображение SVG, а затем получить доступ к элементам SVG через CSS. Существуют различные способы использования каркасов JS SVG, но они слишком сложны, если все, что вы делаете, - это создание простого значка с состоянием опрокидывания.

Итак, вот что я придумала, и я думаю, что это самый простой способ использовать файлы SVG на веб-сайте. Он берет свое понятие из ранних методов замены текста в изображение, но, насколько мне известно, никогда не было сделано для SVG.

Это вопрос:

Как встроить SVG и изменить его цвет в CSS без использования инфраструктуры JS-SVG?

Дрю Бейкер
источник
1
К сожалению, тег img не работает с файлами SVG в IE, так что имейте это в виду. IE распознает теги для вставки. Во всяком случае, хорошая работа!
2
Для svg вы должны использовать свойство css "fill". Для изображений уместно использовать «фильтр». «Фильтр» фактически работает для обоих, но нет необходимости выполнять всю эту работу для векторной графики.
Сэми Бенчериф,

Ответы:

536

Во-первых, используйте тег IMG в своем HTML для встраивания SVG-графики. Я использовал Adobe Illustrator для создания графики.

<img id="facebook-logo" class="svg social-link" src="/images/logo-facebook.svg"/>

Это так же, как вы бы встраивали нормальное изображение. Обратите внимание, что вам нужно настроить IMG на наличие класса svg. Класс 'social-link' только для примера. Идентификатор не обязателен, но полезен.

Затем используйте этот код jQuery (в отдельном файле или в заголовке в заголовке).

    /**
     * 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's ID to the new SVG
                if(typeof imgID !== 'undefined') {
                    $svg = $svg.attr('id', imgID);
                }
                // Add replaced image's 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');

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

            }, 'xml');

        });

Вышеприведенный код выполняет поиск всех IMG с классом 'svg' и заменяет его на встроенный SVG из связанного файла. Огромное преимущество заключается в том, что теперь вы можете использовать CSS для изменения цвета SVG, например:

svg:hover path {
    fill: red;
}

Код jQuery, который я написал, также переносится через исходный идентификатор изображения и классы. Так что этот CSS тоже работает:

#facebook-logo:hover path {
    fill: red;
}

Или:

.social-link:hover path {
    fill: red;
}

Вы можете увидеть пример его работы здесь: http://labs.funkhausdesign.com/examples/img-svg/img-to-svg.html

У нас есть более сложная версия, которая включает кеширование здесь: https://github.com/funkhaus/style-guide/blob/master/template/js/site.js#L32-L90

Дрю Бейкер
источник
6
Иногда это может не работать в Safari (например), чтобы гарантировать, что возвращаемые данные читаемы, замените });$ .get на}, 'xml');
Joan
29
Вы могли бы даже заменить селектор img[src$=".svg"]и исключить необходимость в svgклассе.
Кейси Чу
2
@ LeonGaban Я не думаю, что есть способ нацелить заливку фонового изображения. Было бы очень полезно, если бы вы могли, хотя!
Дрю Бейкер
3
Немного поздно, @LeonGaban, но лучшим способом сделать это, вероятно, будет полное удаление атрибута fill и использование CSS-файла для добавления заполнения в родительский svg. $('#ico_company path').removeAttr('fill'), Тогда вы могли бы сделать #ico_company { fill: #ccc }в своем файле CSS
биобалл
2
@Soaku было бы легко сделать так, чтобы jQuery устанавливал все пути одинаковыми с цветом шрифта, делая что-то вроде: var color = $ img.closest ('p'). Css ('color'); $ svg.find ('path'). attr ('fill', color); `Но я думаю, что эту работу лучше оставить CSS.
Дрю Бейкер
56

Стиль

svg path {
    fill: #000;
}

скрипт

$(document).ready(function() {
    $('img[src$=".svg"]').each(function() {
        var $img = jQuery(this);
        var imgURL = $img.attr('src');
        var attributes = $img.prop("attributes");

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

            // Remove any invalid XML tags
            $svg = $svg.removeAttr('xmlns:a');

            // Loop through IMG attributes and apply on SVG
            $.each(attributes, function() {
                $svg.attr(this.name, this.value);
            });

            // Replace IMG with SVG
            $img.replaceWith($svg);
        }, 'xml');
    });
});
Хенрик Альбрехтссон
источник
1
Если у вас нет атрибута ширины, он просто создает его с неправильным номером. width="170.667"в моем случае
срыв один
2
Это не идеально, так как он теряет предыдущие размеры img.
RichieHH
Здравствуйте, предположим, у меня есть разные svg с расцветкой difnet каждый. Используя этот метод, все мои цвета SVG становятся такими же, как первый SVG, который зацикливается. Любая идея, как я могу маневрировать вокруг этого, чтобы каждый цвет оставался таким же, как прежде?
tnkh
1
обратите внимание, что если ваш svg сделан также из неформ path(например rect), вам нужно будет обрабатывать их также в css
Mugen
33

Теперь вы можете использовать свойство CSSfilter в большинстве современных браузеров (включая Edge, но не IE11). Он работает с изображениями SVG и другими элементами. Вы можете использовать hue-rotateили invertдля изменения цветов, хотя они не позволяют вам изменять разные цвета независимо друг от друга. Я использую следующий класс CSS, чтобы показать «отключенную» версию иконки (где оригинал представляет собой изображение SVG с насыщенным цветом):

.disabled {
    opacity: 0.4;
    filter: grayscale(100%);
    -webkit-filter: grayscale(100%);
}

Это делает его светло-серым в большинстве браузеров. В IE (и, возможно, Opera Mini, который я не тестировал) он заметно исчезает благодаря свойству opacity, которое все еще выглядит довольно хорошо, хотя и не серым.

Вот пример с четырьмя различными классами CSS для значка колокольчика Twemoji : оригинальный (желтый), вышеупомянутый «отключенный» класс, hue-rotate(зеленый) и invert(синий).

aldel
источник
Просто заметил, что инвертировать это хорошее решение, если вы не хотите создавать иконки шрифтов. Я использовал этот код jQuery для изменения иконки в заголовке моего сайта в соответствии со свойством css color (обратите внимание, что я использую белые иконки png):if ($('.w3-top img').css("color") == "rgb(0, 0, 0)") { $('.w3-top img').css("filter", "invert(100%)"); $('.w3-top img').css("-webkit-filter", "invert(100%)"); };
RedClover
Отличный подход. Отредактировал мой SVG xml, чтобы добавить целевой цвет значка, затем использовал класс .icon-disabled, чтобы затемнить его.
SushiGuy
Обратите внимание, что старый Explores не поддерживает фильтр: w3schools.com/cssref/css3_pr_filter.asp
JillAndMe
25

В качестве альтернативы вы можете использовать CSS mask, если поддержка браузера не очень хорошая, но вы можете использовать запасной вариант

.frame {
    background: blue;
    -webkit-mask: url(image.svg) center / contain no-repeat;
}
seanjacob
источник
14
MDN указывает, что -webkit-maskне следует использовать на любом производственном веб-сайте.
vaindil
1
не окрашивает svg
vishal
Может быть, уместно сказать, что сейчас, спустя четыре года, это решение работает во всех основных браузерах. Только что протестировано здесь, и это на 100% нормально.
Даниэль Лемес
23

Если вы можете включить файлы (включая PHP или включить через CMS) на свою страницу, вы можете добавить код SVG и включить его на свою страницу. Это работает так же, как вставка исходного кода SVG на страницу, но делает разметку страницы более чистой.

Преимущество заключается в том, что вы можете нацеливать части SVG с помощью CSS для наведения - никакой JavaScript не требуется.

http://codepen.io/chriscoyier/pen/evcBu

Вам просто нужно использовать правило CSS, как это:

#pathidorclass:hover { fill: #303 !important; }

Обратите внимание, что этот !importantбит необходим для переопределения цвета заливки.

trebor1979
источник
3
Для тех, кто использует AngularJS:<div ng-include="'svg.svg'"></div>
Mikel
Хотя это не очень элегантное решение для хранения SVG-данных в базе данных. Не неправильно, но выкачивание данных DOM xml / html / svg из API или CMS вместо использования шаблонов или других ресурсов просто кажется неправильным.
ChristoKiwi
Спасибо за этот вклад ... Самые современные сайты сегодня предоставляют данные svg для всех видов деятельности, без этого ответа я бы не догадался!
webMan
Кроме того, если ваш SVG имеет прозрачные области, они не будут считаться парящими, и вы можете столкнуться с «вспыхивающим парением». Чтобы это исправить, просто добавьте элемент-обертку (<a>, если это удобно), а затем добавьте это в правило CSS. #pathidorclass:hover, .wrapperclass:hover #pathidorclass { fill: green; }Или даже просто удалите исходное наведение SVG-пути, поскольку вы все равно нацеливаетесь на него через элемент-обертку.
Нил Монро
18

@Drew Baker дал отличное решение для решения проблемы. Код работает правильно. Тем не менее, те, кто использует AngularJ, могут найти много зависимости от jQuery. Следовательно, я подумал, что это хорошая идея - вставить для пользователей AngularJS код, соответствующий решению @Drew Baker.

AngularJs способ того же кода

1. HTML : используйте тег ниже в вашем HTML-файле:

<svg-image src="/icons/my.svg" class="any-class-you-wish"></svg-image>

2. Директива : это будет директива, которая вам понадобится для распознавания тега:

'use strict';
angular.module('myApp')
  .directive('svgImage', ['$http', function($http) {
    return {
      restrict: 'E',
      link: function(scope, element) {
        var imgURL = element.attr('src');
        // if you want to use ng-include, then
        // instead of the above line write the bellow:
        // var imgURL = element.attr('ng-include');
        var request = $http.get(
          imgURL,
          {'Content-Type': 'application/xml'}
        );

        scope.manipulateImgNode = function(data, elem){
          var $svg = angular.element(data)[4];
          var imgClass = elem.attr('class');
          if(typeof(imgClass) !== 'undefined') {
            var classes = imgClass.split(' ');
            for(var i = 0; i < classes.length; ++i){
              $svg.classList.add(classes[i]);
            }
          }
          $svg.removeAttribute('xmlns:a');
          return $svg;
        };

        request.success(function(data){
          element.replaceWith(scope.manipulateImgNode(data, element));
        });
      }
    };
  }]);

3. CSS :

.any-class-you-wish{
    border: 1px solid red;
    height: 300px;
    width:  120px
}

4. Юнит-тест с карма-жасмином :

'use strict';

describe('Directive: svgImage', function() {

  var $rootScope, $compile, element, scope, $httpBackend, apiUrl, data;

  beforeEach(function() {
    module('myApp');

    inject(function($injector) {
      $rootScope = $injector.get('$rootScope');
      $compile = $injector.get('$compile');
      $httpBackend = $injector.get('$httpBackend');
      apiUrl = $injector.get('apiUrl');
    });

    scope = $rootScope.$new();
    element = angular.element('<svg-image src="/icons/icon-man.svg" class="svg"></svg-image>');
    element = $compile(element)(scope);

    spyOn(scope, 'manipulateImgNode').andCallThrough();
    $httpBackend.whenGET(apiUrl + 'me').respond(200, {});

    data = '<?xml version="1.0" encoding="utf-8"?>' +
      '<!-- Generator: Adobe Illustrator 17.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">' +
      '<!-- Obj -->' +
      '<!-- Obj -->' +
      '<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"' +
      'width="64px" height="64px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">' +
        '<g>' +
          '<path fill="#F4A902" d=""/>' +
          '<path fill="#F4A902" d=""/>' +
        '</g>' +
      '</svg>';
    $httpBackend.expectGET('/icons/icon-man.svg').respond(200, data);
  });

  afterEach(function() {
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
  });

  it('should call manipulateImgNode atleast once', function () {
    $httpBackend.flush();
    expect(scope.manipulateImgNode.callCount).toBe(1);
  });

  it('should return correct result', function () {
    $httpBackend.flush();
    var result = scope.manipulateImgNode(data, element);
    expect(result).toBeDefined();
  });

  it('should define classes', function () {
    $httpBackend.flush();
    var result = scope.manipulateImgNode(data, element);
    var classList = ["svg"];
    expect(result.classList[0]).toBe(classList[0]);
  });
});
Максимум
источник
1
Ваше решение не работает, может быть<div ng-include="/icons/my.svg" class="any-class-you-wish"></div>
Гийом Винсент
@guillaumevincent, если вы хотите использовать его, ng-includeпросто измените эту строку var imgURL = element.attr('src');наvar imgURL = element.attr('ng-include');
Макс
Это очень удобное решение, но будьте осторожны при его чрезмерном использовании, поскольку оно может сильно ухудшить производительность - IE набор из 5 значков общего доступа, повторяющихся в списке статей, или что-то в этом роде.
skxc
1
Существует проблема с вашим кодом в IE. Вы можете использовать только if (typeof(imgClass) !== 'undefined') { $svg.setAttribute("class", imgClass); }вместо split и for loop.
Роберт Бокори
2
Отличная работа! Но для определенного изображения вам нужно получить первый элемент svg ( angular.element(data)[0];) и заставить его работать с использованием IE if ($svg.getAttribute('class')) { $svg.setAttribute('class', $svg.getAttribute('class') + ' ' + imgClass); } else { $svg.setAttribute('class', imgClass); }. Также вы можете захотеть добавить cache: trueк параметрам, $http.getиначе ваша страница может стать очень медленной.
Лев
16

Я понимаю, что вы хотите сделать это с помощью CSS, но просто напоминание, если это маленькое простое изображение - вы всегда можете открыть его в Notepad ++ и изменить заполнение пути / whateverelement:

<path style="fill:#010002;" d="M394.854,205.444c9.218-15.461,19.102-30.181,14.258-49.527
    ...
    C412.843,226.163,402.511,211.451,394.854,205.444z"/>

Это может спасти тонну ужасного сценария. Извините, если это не основа, но иногда простые решения могут быть пропущены.

... даже обмен нескольких изображений SVG может быть меньше по размеру, чем некоторые фрагменты кода для этого вопроса.

DShultz
источник
7

Я написал директиву для решения этой проблемы с AngularJS. Это доступно здесь - ngReusableSvg .

Он заменяет элемент SVG после его рендеринга и помещает его в divэлемент, что делает его CSS легко изменяемым. Это помогает использовать один и тот же файл SVG в разных местах, используя разные размеры / цвета.

Использование простое:

<object oa-reusable-svg
        data="my_icon.svg"
        type="image/svg+xml"
        class="svg-class"
        height="30"  // given to prevent UI glitches at switch time
        width="30">
</object>

После этого вы можете легко получить:

.svg-class svg {
    fill: red; // whichever color you want
}
Омри Аарон
источник
Привет, спасибо за предоставление этого решения. Я попробовал это, и это дает: <div ng-click = "eventHandler ()" ng-class = "classEventHandler ()" style = "высота: 30px; ширина: 30px; float: left;" class = "svg-class" id = "my-svg" height = "30" width = "30"> [[object SVGSVGElement]] </ div> В html он просто помещает [[object SVGSVGElement]]. Вы знаете, в чем проблема? Другой вопрос, сильно ли это влияет на производительность или я могу использовать его на многих svg на странице? И наконец, это все еще на угловой 1.3 (беседка).
Берлинг
Какую версию angular вы используете? Не сталкивался с вашей проблемой .. может быть, это что-то с SVG? С точки зрения производительности переключатель относительно тяжелый, я сам использовал его на 10, и это было нормально .. Я думаю, это зависит от количества / размера, так что пробуйте и экспериментируйте с ним. В чем проблема с беседкой? Вы используете другую версию, и есть конфликт?
Омри Аарон
5

TL / DR: GO здесь-> https://codepen.io/sosuke/pen/Pjoqqp

Объяснение:

Я предполагаю, что у вас есть что-то вроде HTML:

<img src="/img/source.svg" class="myClass">

Обязательно пройдите фильтр маршрута, т.е. Ваш SVG, скорее всего, черный или белый. Вы можете применить фильтр, чтобы получить тот цвет, который вы хотите, например, у меня есть черный svg, который я хочу, мятно-зеленый. Сначала я инвертирую его в белый цвет (формально это все цвета RGB на полную), затем играю с насыщенностью оттенка и т. Д. Чтобы сделать это правильно:

filter: invert(86%) sepia(21%) saturate(761%) hue-rotate(92deg) brightness(99%) contrast(107%);

Еще лучше то, что вы можете просто использовать инструмент для преобразования нужного вам гекса в фильтр для вас: https://codepen.io/sosuke/pen/Pjoqqp

AhrenFullStop
источник
Это отличное решение только для CSS, плюс кодовое поле от hex до фильтра просто великолепно.
Ричи Гонсалес
4

Вот версия для knockout.jsоснованного на принятом ответе:

Важно: на самом деле для замены требуется также jQuery, но я подумал, что это может быть полезно для некоторых.

ko.bindingHandlers.svgConvert =
    {
        'init': function ()
        {
            return { 'controlsDescendantBindings': true };
        },

        'update': function (element, valueAccessor, allBindings, viewModel, bindingContext)
        {
            var $img = $(element);
            var imgID = $img.attr('id');
            var imgClass = $img.attr('class');
            var imgURL = $img.attr('src');

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

                // Add replaced image's ID to the new SVG
                if (typeof imgID !== 'undefined')
                {
                    $svg = $svg.attr('id', imgID);
                }
                // Add replaced image's 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');

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

            }, 'xml');

        }
    };

Тогда просто примените data-bind="svgConvert: true"к вашему тегу img.

Это решение полностью заменяет imgтег SVG, и любые дополнительные привязки не будут соблюдаться.

Simon_Weaver
источник
2
Это замечательно! Если вы хотите перейти на следующий уровень, у нас есть обновленная версия, которая включает в себя кэширование, поэтому один и тот же SVG не запрашивается дважды. github.com/funkhaus/style-guide/blob/master/template/js/…
Дрю Бейкер
Я немного волновался об этом, но сам не успел разобраться. Просто нужно что-то быстрое
Simon_Weaver
1
@DrewBaker на самом деле меня больше беспокоило то, что тег img будет запрашивать файл, а затем getбудет запрашивать его снова. Я считал , изменяя srcк data-srcатрибуту по imgтегу, но пришел к выводу , что современные браузеры, вероятно , достаточно умны , чтобы кэшировать файл в любом случае
Simon_Weaver
3

Вот код без фреймворка, только чистый js:

document.querySelectorAll('img.svg').forEach(function(element) {
            var imgID = element.getAttribute('id')
            var imgClass = element.getAttribute('class')
            var imgURL = element.getAttribute('src')

            xhr = new XMLHttpRequest()
            xhr.onreadystatechange = function() {
                if(xhr.readyState == 4 && xhr.status == 200) {
                    var svg = xhr.responseXML.getElementsByTagName('svg')[0];

                    if(imgID != null) {
                         svg.setAttribute('id', imgID);
                    }

                    if(imgClass != null) {
                         svg.setAttribute('class', imgClass + ' replaced-svg');
                    }

                    svg.removeAttribute('xmlns:a')

                    if(!svg.hasAttribute('viewBox') && svg.hasAttribute('height') && svg.hasAttribute('width')) {
                        svg.setAttribute('viewBox', '0 0 ' + svg.getAttribute('height') + ' ' + svg.getAttribute('width'))
                    }
                    element.parentElement.replaceChild(svg, element)
                }
            }
            xhr.open('GET', imgURL, true)
            xhr.send(null)
        })
user3144480
источник
3

Существует библиотека с открытым исходным кодом SVGInject, которая использует onloadатрибут для запуска внедрения. Вы можете найти проект GitHub по адресу https://github.com/iconfu/svg-inject.

Вот минимальный пример использования 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>элементы INJECT themselved автоматически. Если вы добавляете SVG динамически, вам не нужно беспокоиться о повторном вызове функции инъекции.

  3. Случайная строка добавляется к каждому идентификатору в SVG, чтобы избежать многократного использования одного и того же идентификатора в документе, если SVG вводится более одного раза.

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

Отказ от ответственности: я соавтор SVGInject

Waruyama
источник
1
Мне больше нравится это решение, потому что оно заботится о динамически добавляемых SVG.
VickyB
2

Если у нас будет больше таких изображений SVG, мы также можем воспользоваться шрифтовыми файлами.
Такие сайты, как https://glyphter.com/, могут получить нам файл шрифта из наших svgs.


Например

@font-face {
    font-family: 'iconFont';
    src: url('iconFont.eot');
}
#target{
    color: white;
    font-size:96px;
    font-family:iconFont;
}
Абхишек Борар
источник
5
Я лично ненавижу технику «изображения как шрифт». Это затрудняет добавление / редактирование изображений, добавляет много бессмысленной разметки. Шрифты должны быть шрифтами, изображения должны быть изображениями и т. Д.
Дрю Бейкер
Согласовано. Вы также должны помнить / искать изображения, назначенные персонажам. но для конкретного случая, когда изображения используются в качестве значков / кнопок / маркеров, действуют скорее как текст, чем как медиа, шрифтовые файлы также могут быть альтернативой
Абхишек Борар
даже github больше не использует шрифт для иконки github.com/blog/2112-delivering-octicons-with-svg
gagarine
2

Вы можете использовать data-image для этого. используя data-image (data-URI), вы можете получить доступ к SVG, как встроенный.

Вот эффект ролловера с использованием чистого CSS и SVG.

Я знаю это грязно, но вы можете сделать это так.

 .action-btn {
    background-size: 20px 20px;
    background-position: center center;
    background-repeat: no-repeat;
    border-width: 1px;
    border-style: solid;
    border-radius: 30px;
    height: 40px;
    width: 60px;
    display: inline-block;
 }

.delete {
     background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg version='1.1' id='Capa_1' fill='#FB404B' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='482.428px' height='482.429px' viewBox='0 0 482.428 482.429' style='enable-background:new 0 0 482.428 482.429;' xml:space='preserve'%3e%3cg%3e%3cg%3e%3cpath d='M381.163,57.799h-75.094C302.323,25.316,274.686,0,241.214,0c-33.471,0-61.104,25.315-64.85,57.799h-75.098 c-30.39,0-55.111,24.728-55.111,55.117v2.828c0,23.223,14.46,43.1,34.83,51.199v260.369c0,30.39,24.724,55.117,55.112,55.117 h210.236c30.389,0,55.111-24.729,55.111-55.117V166.944c20.369-8.1,34.83-27.977,34.83-51.199v-2.828 C436.274,82.527,411.551,57.799,381.163,57.799z M241.214,26.139c19.037,0,34.927,13.645,38.443,31.66h-76.879 C206.293,39.783,222.184,26.139,241.214,26.139z M375.305,427.312c0,15.978-13,28.979-28.973,28.979H136.096 c-15.973,0-28.973-13.002-28.973-28.979V170.861h268.182V427.312z M410.135,115.744c0,15.978-13,28.979-28.973,28.979H101.266 c-15.973,0-28.973-13.001-28.973-28.979v-2.828c0-15.978,13-28.979,28.973-28.979h279.897c15.973,0,28.973,13.001,28.973,28.979 V115.744z'/%3e%3cpath d='M171.144,422.863c7.218,0,13.069-5.853,13.069-13.068V262.641c0-7.216-5.852-13.07-13.069-13.07 c-7.217,0-13.069,5.854-13.069,13.07v147.154C158.074,417.012,163.926,422.863,171.144,422.863z'/%3e%3cpath d='M241.214,422.863c7.218,0,13.07-5.853,13.07-13.068V262.641c0-7.216-5.854-13.07-13.07-13.07 c-7.217,0-13.069,5.854-13.069,13.07v147.154C228.145,417.012,233.996,422.863,241.214,422.863z'/%3e%3cpath d='M311.284,422.863c7.217,0,13.068-5.853,13.068-13.068V262.641c0-7.216-5.852-13.07-13.068-13.07 c-7.219,0-13.07,5.854-13.07,13.07v147.154C298.213,417.012,304.067,422.863,311.284,422.863z'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e ");
     border-color:#FB404B;
     
 }
 
 .delete:hover {
     background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg version='1.1' id='Capa_1' fill='#fff' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='482.428px' height='482.429px' viewBox='0 0 482.428 482.429' style='enable-background:new 0 0 482.428 482.429;' xml:space='preserve'%3e%3cg%3e%3cg%3e%3cpath d='M381.163,57.799h-75.094C302.323,25.316,274.686,0,241.214,0c-33.471,0-61.104,25.315-64.85,57.799h-75.098 c-30.39,0-55.111,24.728-55.111,55.117v2.828c0,23.223,14.46,43.1,34.83,51.199v260.369c0,30.39,24.724,55.117,55.112,55.117 h210.236c30.389,0,55.111-24.729,55.111-55.117V166.944c20.369-8.1,34.83-27.977,34.83-51.199v-2.828 C436.274,82.527,411.551,57.799,381.163,57.799z M241.214,26.139c19.037,0,34.927,13.645,38.443,31.66h-76.879 C206.293,39.783,222.184,26.139,241.214,26.139z M375.305,427.312c0,15.978-13,28.979-28.973,28.979H136.096 c-15.973,0-28.973-13.002-28.973-28.979V170.861h268.182V427.312z M410.135,115.744c0,15.978-13,28.979-28.973,28.979H101.266 c-15.973,0-28.973-13.001-28.973-28.979v-2.828c0-15.978,13-28.979,28.973-28.979h279.897c15.973,0,28.973,13.001,28.973,28.979 V115.744z'/%3e%3cpath d='M171.144,422.863c7.218,0,13.069-5.853,13.069-13.068V262.641c0-7.216-5.852-13.07-13.069-13.07 c-7.217,0-13.069,5.854-13.069,13.07v147.154C158.074,417.012,163.926,422.863,171.144,422.863z'/%3e%3cpath d='M241.214,422.863c7.218,0,13.07-5.853,13.07-13.068V262.641c0-7.216-5.854-13.07-13.07-13.07 c-7.217,0-13.069,5.854-13.069,13.07v147.154C228.145,417.012,233.996,422.863,241.214,422.863z'/%3e%3cpath d='M311.284,422.863c7.217,0,13.068-5.853,13.068-13.068V262.641c0-7.216-5.852-13.07-13.068-13.07 c-7.219,0-13.07,5.854-13.07,13.07v147.154C298.213,417.012,304.067,422.863,311.284,422.863z'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e ");        
     background-color: #FB404B;
    }
<a class="action-btn delete">&nbsp;</a>

Вы можете конвертировать ваш SVG в URL-адрес данных здесь

  1. https://codepen.io/elliz/full/ygvgay
  2. https://websemantics.uk/tools/svg-to-background-image-conversion/
patelarpan
источник
Это не сработает для сложных SVG, где вы хотите, чтобы только определенные пути / полигоны / и т. Д. Изменялись при наведении, верно?
Дрю Бейкер
Нет, вы можете .. но это очень сложно
patelarpan
Это просто решения для иконы
patelarpan
Если некоторые работают с иконой. Тогда это здорово. Bootstrap 4 также использует эту технику
patelarpan
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:

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

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

  1. Google Chrome66.0.3359.181 (сборка официальная) (64 бит) Linux

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

  1. Опера 53.0.2907.37 Linux

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

Вениамин
источник
1

Выбранное решение подойдет, если вы хотите, чтобы jQuery обрабатывал все элементы svg в вашем DOM, и ваш DOM имеет разумный размер. Но если у вас большой DOM, и вы решили загружать части DOM динамически, нет смысла пересматривать весь DOM только для обновления элементов svg. Вместо этого используйте плагин jQuery, чтобы сделать это:

/**
 * A jQuery plugin that loads an svg file and replaces the jQuery object with its contents.
 *
 * The path to the svg file is specified in the src attribute (which normally does not exist for an svg element).
 *
 * The width, height and class attributes in the loaded svg will be replaced by those that exist in the jQuery object's
 * underlying html. Note: All other attributes in the original element are lost including the style attribute. Place
 * any styles in a style class instead.
 */
(function ($) {
    $.fn.svgLoader = function () {
        var src = $(this).attr("src");
        var width = this.attr("width");
        var height = this.attr("height");
        var cls = this.attr("class");
        var ctx = $(this);

        // Get the svg file and replace the <svg> element.
        $.ajax({
            url: src,
            cache: false
        }).done(function (html) {
            let svg = $(html);
            svg.attr("width", width);
            svg.attr("height", height);
            svg.attr("class", cls);
            var newHtml = $('<a></a>').append(svg.clone()).html();
            ctx.replaceWith(newHtml);
        });

        return this;
    };

}(jQuery));

В вашем html укажите элемент svg следующим образом:

<svg src="images/someSvgFile.svg" height="45" width="45" class="mySVGClass"/>

И примените плагин:

$(".mySVGClass").svgLoader();
AndroidDev
источник
Да, конечно, есть более эффективные способы использования кода, который я дал. Вот как мы на самом деле используем его на производственных площадках. Он кеширует SVG! github.com/funkhaus/style-guide/blob/master/template/js/…
Дрю Бейкер
1

для анимации событий при наведении мыши мы можем оставить стили внутри файла SVG, как

<svg xmlns="http://www.w3.org/2000/svg">
<defs>
  <style>
  rect {
    fill:rgb(165,225,75);
    stroke:none;
    transition: 550ms ease-in-out;
    transform-origin:125px 125px;
  }
  rect:hover {
    fill:rgb(75,165,225);
    transform:rotate(360deg);
  }
  </style>
</defs>
  <rect x='50' y='50' width='150' height='150'/>
</svg>

проверить это на svgshare

ghett
источник