Bagaimana cara mengubah warna gambar SVG menggunakan CSS (pengganti gambar jQuery SVG)?

437

Ini adalah tanya jawab diri sendiri atas sepotong kode praktis yang saya buat.

Saat ini, tidak ada cara mudah untuk menanamkan gambar SVG dan kemudian memiliki akses ke elemen SVG melalui CSS. Ada berbagai metode menggunakan kerangka kerja JS SVG, tetapi mereka terlalu rumit jika semua yang Anda lakukan adalah membuat ikon sederhana dengan keadaan rollover.

Jadi inilah yang saya pikirkan, yang saya pikir sejauh ini adalah cara termudah untuk menggunakan file SVG di situs web. Dibutuhkan konsepnya dari metode penggantian teks-ke-gambar awal, tetapi sejauh yang saya ketahui belum pernah dilakukan untuk SVG.

Ini pertanyaannya:

Bagaimana cara menanamkan SVG dan mengubah warnanya dalam CSS tanpa menggunakan kerangka kerja JS-SVG?

Drew Baker
sumber
1
Sayangnya tag img tidak bekerja dengan file svg di IE, jadi ingatlah itu. IE mengenali tag embed. Ngomong-ngomong, pekerjaan bagus!
2
Untuk svg, Anda harus menggunakan properti css "isi". Untuk gambar sebaiknya menggunakan "filter". "Filter" sebenarnya bekerja untuk keduanya tetapi tidak perlu melakukan semua itu untuk grafik vektor.
Samy Bencherif

Jawaban:

536

Pertama, gunakan tag IMG dalam HTML Anda untuk menyematkan grafik SVG. Saya menggunakan Adobe Illustrator untuk membuat grafik.

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

Ini seperti bagaimana Anda menanamkan gambar normal. Perhatikan bahwa Anda perlu mengatur IMG untuk memiliki kelas svg. Kelas 'tautan sosial' hanyalah untuk contoh saja. ID tidak diperlukan, tetapi berguna.

Kemudian gunakan kode jQuery ini (dalam file terpisah atau sebaris di HEAD).

    /**
     * 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');

        });

Apa yang dilakukan oleh kode di atas adalah mencari semua IMG dengan kelas 'svg' dan menggantinya dengan SVG inline dari file tertaut. Keuntungan besar adalah memungkinkan Anda menggunakan CSS untuk mengubah warna SVG sekarang, seperti:

svg:hover path {
    fill: red;
}

Kode jQuery yang saya tulis juga port di ID gambar dan kelas asli. Jadi CSS ini juga berfungsi:

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

Atau:

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

Anda dapat melihat contohnya berfungsi di sini: http://labs.funkhausdesign.com/examples/img-svg/img-to-svg.html

Kami memiliki versi yang lebih rumit yang mencakup caching di sini: https://github.com/funkhaus/style-guide/blob/master/template/js/site.js#L32-L90

Drew Baker
sumber
6
Kadang-kadang mungkin tidak berfungsi di Safari (misalnya), untuk memastikan data yang dikembalikan dapat dibaca, remplace });$. Get with}, 'xml');
Joan
29
Anda bahkan dapat mengganti pemilih dengan img[src$=".svg"]dan menghilangkan kebutuhan untuk svgkelas.
Casey Chu
2
@LeonGaban Saya tidak berpikir ada cara untuk menargetkan isi gambar latar belakang. Akan sangat membantu jika Anda bisa!
Drew Baker
3
Sedikit terlambat, @LeonGaban, tetapi cara yang lebih baik untuk melakukannya mungkin adalah dengan menghapus atribut fill sama sekali, dan bergantung pada file CSS untuk menambahkan fill ke svg induk. $('#ico_company path').removeAttr('fill'). Maka Anda bisa melakukannya #ico_company { fill: #ccc }di file CSS Anda
bioball
2
@ Soaku akan mudah untuk memiliki jQuery mengatur semua path menjadi sama dengan warna font melakukan sesuatu seperti `var color = $ img.closest ('p'). Css ('color'); $ svg.find ('path'). attr ('fill', color); `Tapi saya pikir ini adalah pekerjaan yang lebih baik diserahkan kepada CSS.
Drew Baker
56

Gaya

svg path {
    fill: #000;
}

Naskah

$(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');
    });
});
Henrik Albrechtsson
sumber
1
Jika Anda tidak memiliki attr lebar, itu hanya membuat satu dengan nomor yang salah. width="170.667"dalam kasus saya
stallingOne
2
Ini tidak sempurna karena kehilangan dimensi img sebelumnya.
RichieHH
Halo saya kira saya punya svg berbeda dengan warna differnet masing-masing. Dengan menggunakan metode ini, semua warna svg saya menjadi sama dengan svg pertama yang sedang diulang. Tahu bagaimana saya bisa bermanuver di sekitar ini sehingga setiap warna tetap sama seperti sebelumnya?
tnkh
1
perhatikan bahwa jika svg Anda juga dibuat dari non- pathbentuk (seperti rect) Anda harus menanganinya dalam css juga
Mugen
33

Anda sekarang dapat menggunakan properti CSSfilter di sebagian besar browser modern (termasuk Edge, tetapi tidak IE11). Ini bekerja pada gambar SVG serta elemen lainnya. Anda dapat menggunakan hue-rotateatau invertmengubah warna, meskipun mereka tidak membiarkan Anda mengubah warna yang berbeda secara independen. Saya menggunakan kelas CSS berikut untuk menampilkan versi ikon "cacat" (di mana aslinya adalah gambar SVG dengan warna jenuh):

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

Ini membuatnya menjadi abu-abu terang di sebagian besar browser. Di IE (dan mungkin Opera Mini, yang belum saya uji) terasa memudar oleh properti opacity, yang masih terlihat cukup bagus, meskipun tidak abu-abu.

Berikut adalah contoh dengan empat kelas CSS berbeda untuk ikon lonceng Twemoji : asli (kuning), kelas "dinonaktifkan" di atas, hue-rotate(hijau), dan invert(biru).

aldel
sumber
Hanya perhatikan bahwa invert adalah solusi yang baik jika Anda tidak ingin membuat font ikon. Saya menggunakan kode jQuery ini untuk mengubah ikon di header situs web saya sesuai dengan properti warna css (perhatikan bahwa saya menggunakan ikon png putih):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
Pendekatan yang bagus. Mengedit xml SVG saya untuk menambahkan warna ikon target kemudian menggunakan kelas .icon-disable untuk menghapusnya.
SushiGuy
Perhatikan bahwa Explores lama tidak mendukung filter: w3schools.com/cssref/css3_pr_filter.asp
JillAndMe
25

Atau Anda dapat menggunakan CSS mask, dukungan browser yang diberikan tidak baik tetapi Anda dapat menggunakan mundur

.frame {
    background: blue;
    -webkit-mask: url(image.svg) center / contain no-repeat;
}
seanjacob
sumber
14
MDN menetapkan bahwa -webkit-masktidak boleh digunakan di situs web produksi mana pun.
vaindil
1
tidak mewarnai svg
vishal
Mungkin relevan untuk mengatakan bahwa sekarang, empat tahun kemudian, solusi ini berfungsi di semua browser utama. Baru diuji di sini dan 100% ok.
Daniel Lemes
23

Jika Anda dapat memasukkan file (PHP sertakan atau sertakan melalui CMS pilihan Anda) di halaman Anda, Anda dapat menambahkan kode SVG dan memasukkannya ke halaman Anda. Ini berfungsi sama seperti menempelkan sumber SVG ke halaman, tetapi membuat markup halaman lebih bersih.

Manfaatnya adalah Anda dapat menargetkan bagian-bagian SVG Anda melalui CSS untuk dibawa-bawa - tidak perlu javascript.

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

Anda hanya perlu menggunakan aturan CSS seperti ini:

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

Perhatikan bahwa !importantbit diperlukan untuk mengganti warna isian.

trebor1979
sumber
3
Bagi mereka yang menggunakan AngularJS:<div ng-include="'svg.svg'"></div>
Mikel
Bukan solusi yang sangat elegan menyimpan data svg dalam database sekalipun. Tidak salah, tetapi memompa data DOM xml / html / svg dari API atau CMS daripada menggunakan template atau aset lain hanya terasa salah.
ChristoKiwi
Terima kasih atas kontribusi ini ... Situs-situs paling canggih saat ini mengumpulkan data svg untuk memungkinkan semua jenis aktivitas, tanpa jawaban ini saya tidak akan dapat menebaknya!
webMan
Selain itu, jika SVG Anda memiliki area transparan, ini tidak akan dihitung sebagai melayang dan Anda mungkin mengalami "melayang mencolok". Untuk memperbaikinya, tambahkan saja elemen pembungkus (sebuah <a>, jika itu mudah) dan kemudian tambahkan itu ke aturan CSS. #pathidorclass:hover, .wrapperclass:hover #pathidorclass { fill: green; }Atau bahkan hanya menghilangkan hover asli dari jalur SVG karena Anda menargetkannya melalui elemen pembungkus sekarang.
Neil Monroe
18

@Rew Baker memberikan solusi yang bagus untuk menyelesaikan masalah. Kode berfungsi dengan baik. Namun, mereka yang menggunakan AngularJs mungkin menemukan banyak ketergantungan pada jQuery. Akibatnya, saya pikir itu adalah ide yang bagus untuk menempelkan untuk pengguna AngularJS, sebuah kode yang mengikuti solusi @Drew Baker.

Cara angularJs dari kode yang sama

1. Html : gunakan tag di bawah ini di file html Anda:

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

2. Petunjuk : ini akan menjadi arahan bahwa Anda perlu mengenali tag:

'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. Unit-test dengan karma-melati :

'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]);
  });
});
Maks
sumber
1
solusi Anda tidak berhasil, bisa jadi<div ng-include="/icons/my.svg" class="any-class-you-wish"></div>
Guillaume Vincent
@guillaumevincent jika Anda ingin menggunakannya ng-includemaka ubah saja baris ini var imgURL = element.attr('src');kevar imgURL = element.attr('ng-include');
Max
Ini adalah solusi yang sangat praktis, tetapi berhati-hatilah dalam menggunakannya secara berlebihan karena dapat menekan kinerja cukup keras - yaitu seperangkat 5 ikon berbagi yang diulang pada daftar artikel atau sesuatu seperti itu.
skxc
1
Ada masalah dengan kode Anda di IE. Anda dapat menggunakan if (typeof(imgClass) !== 'undefined') { $svg.setAttribute("class", imgClass); }alih-alih split dan untuk loop.
Robert Bokori
2
Kerja luar biasa! Tetapi untuk gambar tertentu Anda perlu mengambil elemen pertama svg ( angular.element(data)[0];) dan membuatnya berfungsi dengan penggunaan IE if ($svg.getAttribute('class')) { $svg.setAttribute('class', $svg.getAttribute('class') + ' ' + imgClass); } else { $svg.setAttribute('class', imgClass); }. Anda juga mungkin ingin menambahkan cache: trueopsi $http.getjika tidak, halaman Anda mungkin menjadi sangat lambat.
leo
16

Saya menyadari bahwa Anda ingin menyelesaikan ini dengan CSS, tetapi hanya pengingat jika itu adalah gambar kecil dan sederhana - Anda selalu dapat membukanya di Notepad ++ dan mengubah jalur / isi elemen apa pun:

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

Itu bisa menghemat satu ton skrip jelek. Maaf jika ini tidak masuk akal, tetapi kadang-kadang solusi sederhana dapat diabaikan.

... bahkan menukar banyak gambar svg mungkin lebih kecil daripada beberapa potongan kode untuk pertanyaan ini.

DShultz
sumber
7

Saya menulis arahan untuk mengatasi masalah ini dengan AngularJS. Ini tersedia di sini - ngReusableSvg .

Itu menggantikan elemen SVG setelah itu diberikan, dan menempatkannya di dalam divelemen, membuat CSS-nya mudah diubah. Ini membantu menggunakan file SVG yang sama di tempat yang berbeda menggunakan ukuran / warna yang berbeda.

Penggunaannya sederhana:

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

Setelah itu, Anda dapat dengan mudah memiliki:

.svg-class svg {
    fill: red; // whichever color you want
}
Omri Aharon
sumber
Hai, terima kasih telah menyediakan solusi ini. Saya sudah mencobanya dan menghasilkan: <div ng-klik = "eventHandler ()" ng-class = "classEventHandler ()" style = "height: 30px; lebar: 30px; float: left;" class = "svg-class" id = "my-svg" height = "30" width = "30"> [[objek SVGSVGElement]] </div> Dalam html itu hanya menempatkan [[objek SVGSVGElement]]. Apakah Anda tahu apa masalahnya? Pertanyaan lain, apakah itu berdampak besar pada kinerja atau dapatkah saya menggunakannya pada banyak svg di halaman? Dan terakhir, masih pada sudut 1,3 (bower).
bersling
Versi sudut mana yang Anda gunakan? Belum pernah menemui masalah Anda .. mungkin ada sesuatu dengan SVG? Dari segi kinerja sakelar ini relatif berat, saya sudah menggunakannya sendiri seperti 10 dan itu baik-baik saja .. Saya kira itu tergantung pada jumlah / ukuran, jadi coba dan bereksperimenlah dengannya. Apa masalah dengan bower? Apakah Anda menggunakan versi yang berbeda dan ada konflik?
Omri Aharon
5

TL / DR: PERGI di sini-> https://codepen.io/sosuke/pen/Pjoqqp

Penjelasan:

Saya berasumsi Anda memiliki html sesuatu seperti ini:

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

Pasti pergi rute filter, yaitu. svg Anda kemungkinan besar hitam atau putih. Anda dapat menerapkan filter untuk membuatnya menjadi warna apa pun yang Anda inginkan, misalnya, saya memiliki svg hitam yang saya inginkan hijau mint. Pertama-tama saya membalikkannya menjadi putih (yang secara teknis semua warna RGB penuh) kemudian bermain dengan saturasi rona dll. Untuk memperbaikinya:

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

Yang lebih baik adalah Anda bisa menggunakan alat untuk mengubah hex yang Anda inginkan menjadi filter untuk Anda: https://codepen.io/sosuke/pen/Pjoqqp

AhrenFullStop
sumber
Ini adalah satu-satunya solusi css yang bagus, ditambah codepen dari hex ke filter hanya mengagumkan.
Richi González
4

Ini versi untuk knockout.jsberdasarkan jawaban yang diterima:

Penting: Ini sebenarnya membutuhkan jQuery juga untuk penggantian, tapi saya pikir mungkin bermanfaat bagi sebagian orang.

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

        }
    };

Kemudian cukup terapkan data-bind="svgConvert: true"ke tag img Anda.

Solusi ini sepenuhnya mengganti imgtag dengan SVG dan ikatan tambahan apa pun tidak akan dihormati.

Simon_Weaver
sumber
2
Ini bagus! Jika Anda ingin membawanya ke level berikutnya, kami memiliki versi terbaru yang menyertakan caching, jadi SVG yang sama tidak diminta dua kali. github.com/funkhaus/style-guide/blob/master/template/js/…
Drew Baker
Saya agak khawatir tentang itu tetapi tidak punya waktu untuk memeriksanya sendiri. Hanya butuh sesuatu dengan cepat
Simon_Weaver
1
@BrewBaker sebenarnya saya lebih khawatir bahwa tag img akan meminta file dan kemudian getakan memintanya lagi. Aku dianggap mengubah srcke data-srcatribut pada imgtag, tetapi menyimpulkan bahwa browser modern cukup mungkin pintar untuk cache file pula
Simon_Weaver
3

Berikut adalah kode kerangka kerja, hanya js murni:

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)
        })
pengguna3144480
sumber
3

Ada pustaka sumber terbuka yang disebut SVGInject yang menggunakan onloadatribut untuk memicu injeksi. Anda dapat menemukan proyek GitHub di https://github.com/iconfu/svg-inject

Berikut adalah contoh minimal menggunakan SVGInject:

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

Setelah gambar dimuat, onload="SVGInject(this)akan memicu injeksi dan <img>elemen akan diganti dengan isi file SVG yang disediakan dalam srcatribut.

Ini memecahkan beberapa masalah dengan injeksi SVG:

  1. SVG dapat disembunyikan sampai injeksi selesai. Ini penting jika gaya sudah diterapkan selama waktu pemuatan, yang jika tidak akan menyebabkan "flash konten tanpa gaya" singkat.

  2. <img>Elemen - elemen menyuntikkannya sendiri secara otomatis. Jika Anda menambahkan SVG secara dinamis, Anda tidak perlu khawatir tentang memanggil fungsi injeksi lagi.

  3. String acak ditambahkan ke setiap ID dalam SVG untuk menghindari memiliki ID yang sama beberapa kali dalam dokumen jika SVG disuntikkan lebih dari satu kali.

SVGInject adalah Javascript biasa dan bekerja dengan semua browser yang mendukung SVG.

Penafian: Saya adalah rekan penulis SVGInject

Waruyama
sumber
1
Saya paling suka solusi ini, karena membutuhkan SVG yang ditambahkan secara dinamis.
VickyB
2

Jika kita memiliki lebih banyak gambar svg seperti itu, kita juga dapat mengambil bantuan file font.
Situs seperti https://glyphter.com/ bisa mendapatkan kita file font dari svgs kami.


Misalnya

@font-face {
    font-family: 'iconFont';
    src: url('iconFont.eot');
}
#target{
    color: white;
    font-size:96px;
    font-family:iconFont;
}
Abhishek Borar
sumber
5
Saya pribadi benci teknik "gambar sebagai font". Itu membuatnya sulit untuk menambah / mengedit gambar, menambahkan banyak markup tidak masuk akal. Font harus font, gambar harus gambar dll.
Drew Baker
Sepakat. Anda juga perlu mengingat / mencari gambar yang ditugaskan untuk karakter. tetapi untuk kasus khusus di mana gambar digunakan sebagai ikon / tombol / peluru, bertindak lebih sebagai teks daripada media, font-file juga bisa menjadi alternatif
Abhishek Borar
bahkan github tidak menggunakan font lagi untuk ikon github.com/blog/2112-delivering-octicons-with-svg
gagarine
2

Anda dapat menggunakan data-gambar untuk itu. menggunakan data-image (data-URI) Anda dapat mengakses SVG seperti inline.

Berikut adalah efek rollover menggunakan CSS murni dan SVG.

Saya tahu itu berantakan tetapi Anda bisa melakukannya dengan cara ini.

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

Anda dapat mengonversi svg Anda ke url data di sini

  1. https://codepen.io/elliz/full/ygvgay
  2. https://websemantics.uk/tools/svg-to-background-image-conversion/
patelarpan
sumber
Ini tidak akan berfungsi untuk SVG kompleks di mana Anda hanya ingin jalur / poligon tertentu / dll. Untuk berubah pada hover kan?
Drew Baker
Tidak bisa..tapi itu sangat kompleks
patelarpan
Itu hanya solusi untuk ikon
patelarpan
Jika beberapa bekerja dengan ikon. Itu bagus. Bootstrap 4 juga menggunakan teknik ini
patelarpan
2

Karena SVG pada dasarnya adalah kode, Anda hanya perlu konten. Saya menggunakan PHP untuk mendapatkan konten, tetapi Anda dapat menggunakan apa pun yang Anda inginkan.

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

Lalu, saya sudah mencetak konten "apa adanya" di dalam wadah div

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

Untuk menetapkan aturan untuk anak SVG kontainer di CSS

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

Saya mendapat hasil ini dengan ikon materi SVG:

  1. Mozilla Firefox 59.0.2 (64-bit) Linux

masukkan deskripsi gambar di sini

  1. Google Chrome66.0.3359.181 (Build oficial) (64 bit) Linux

masukkan deskripsi gambar di sini

  1. Opera 53.0.2907.37 Linux

masukkan deskripsi gambar di sini

Benjamin
sumber
1

Solusi yang dipilih baik-baik saja jika Anda ingin jQuery memproses semua elemen svg di DOM Anda dan DOM Anda memiliki ukuran yang masuk akal. Tetapi jika DOM Anda besar dan Anda memutuskan untuk memuat bagian DOM Anda secara dinamis, itu benar-benar tidak masuk akal harus menelusuri ulang seluruh DOM hanya untuk memperbarui elemen svg. Alih-alih, gunakan plugin jQuery untuk melakukan ini:

/**
 * 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));

Di html Anda, tentukan elemen svg sebagai berikut:

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

Dan terapkan plugin:

$(".mySVGClass").svgLoader();
AndroidDev
sumber
Ya pasti ada cara yang lebih efisien untuk menggunakan kode yang saya berikan. Inilah cara kami menggunakannya di lokasi produksi. Itu cache SVG! github.com/funkhaus/style-guide/blob/master/template/js/…
Drew Baker
1

untuk: hover animasi acara kita dapat meninggalkan gaya di dalam file svg, seperti a

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

periksa ini di svgshare

ghett
sumber