CSS (jQuery SVG görüntü değiştirme) kullanarak SVG görüntüsünün rengi nasıl değiştirilir?


437

Bu, geldiğim kullanışlı bir kod parçasının kendi soru ve cevapları.

Şu anda, bir SVG görüntüsünü gömmenin ve ardından CSS aracılığıyla SVG öğelerine erişmenin kolay bir yolu yoktur. JS SVG çerçevelerini kullanmanın çeşitli yöntemleri vardır, ancak yaptığınız tek şey rollover durumuyla basit bir simge yapmaksa aşırı derecede karmaşıktır.

İşte size bir web sitesinde SVG dosyalarını kullanmanın en kolay yolu olduğunu düşünüyorum. Konseptini ilk metinden görüntüye değiştirme yöntemlerinden alıyor, ancak bildiğim kadarıyla SVG'ler için hiç yapılmadı.

Soru budur:

Bir SVG çerçevesini kullanmadan bir SVG'yi nasıl yerleştiririm ve rengini nasıl değiştiririm?


1
Ne yazık ki img etiketi IE'deki svg dosyalarıyla çalışmaz, bu yüzden unutmayın. IE, gömme etiketlerini tanır. Her neyse, iyi iş çıkardın!

2
Svg için "fill" css özelliğini kullanmalısınız. Resimler için "filtre" kullanmak uygundur. "Filtre" aslında her ikisi için de işe yarar, ancak tüm bu işleri bir vektör grafiği için yapmak gereksizdir.
Samy Bencherif

Yanıtlar:


536

Öncelikle, bir SVG grafiği gömmek için HTML'nizde bir IMG etiketi kullanın. Grafiği yapmak için Adobe Illustrator kullandım.

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

Bu normal bir görüntüyü nasıl yerleştirdiğinize benzer. IMG'yi bir svg sınıfına sahip olacak şekilde ayarlamanız gerektiğini unutmayın. 'Social-link' sınıfı sadece örnek amaçlıdır. Kimlik gerekli değildir, ancak kullanışlıdır.

Ardından bu jQuery kodunu kullanın (HEAD'de ayrı bir dosyada veya satır içi olarak).

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

        });

Yukarıdaki kodun yaptığı 'svg' sınıfına sahip tüm IMG'leri aramak ve onu bağlantılı dosyadan satır içi SVG ile değiştirmek. En büyük avantajı şu anda SVG'nin rengini değiştirmek için CSS'yi kullanmanıza izin vermesidir:

svg:hover path {
    fill: red;
}

Yazdığım jQuery kodu, orijinal görüntü kimliği ve sınıfları arasında da bağlantı noktaları. Yani bu CSS de çalışıyor:

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

Veya:

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

Burada çalışan bir örnek görebilirsiniz: http://labs.funkhausdesign.com/examples/img-svg/img-to-svg.html

Burada önbelleğe almayı içeren daha karmaşık bir sürümümüz var: https://github.com/funkhaus/style-guide/blob/master/template/js/site.js#L32-L90


6
Bazen Safari'de çalışmayabilir (örneğin), döndürülen verilerin okunabilir olmasını sağlamak için });$ .get ile yeniden kullanın}, 'xml');
Joan

29
Hatta seçiciyi sınıfla değiştirebilir img[src$=".svg"]ve svgsınıf ihtiyacını ortadan kaldırabilirsiniz .
Casey Chu

2
@LeonGaban Bir arka plan resminin dolgusunu hedeflemenin bir yolu olduğunu düşünmüyorum. Eğer olsa süper yararlı olurdu!
Drew Baker

3
Biraz geç @LeonGaban, ancak bunu yapmanın daha iyi bir yolu muhtemelen fill özniteliğini tamamen kaldırmak ve üst svg'ye dolgu eklemek için bir CSS dosyasına güvenmek olacaktır. $('#ico_company path').removeAttr('fill'). O zaman #ico_company { fill: #ccc }CSS dosyanızda yapabilirsiniz
bioball

2
@Soaku, jQuery'nin tüm yolları yazı tipi rengiyle aynı olacak şekilde ayarlaması `var renk = $ img.closest ('p'). Css ('color'); $ svg.find ('yol'). attr ('dolgu', renk); `` Ama bence bu CSS'ye daha iyi bırakılmış bir iş.
Drew Baker

56

stil

svg path {
    fill: #000;
}

Senaryo

$(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
Bir genişlik attr değerine sahip değilseniz, yalnızca yanlış bir numaraya sahip bir tane oluşturur. width="170.667"benim durumumda
stallingOne

2
Önceki img boyutlarını kaybettiği için bu mükemmel değil.
RichieHH

Merhaba ben her difernet renk ile farklı svg varsayalım. Bu yöntemi kullanarak, tüm svg renklerim döngüdeki ilk svg ile aynı olur. Her rengin öncekiyle aynı kalması için bunun etrafında nasıl manevra yapabilirim?
tnkh

1
svg'niz de pathşekillerden (örneğin rect) yapılmışsa, bunları
Mugen

33

Artık kullanabilirsiniz CSS filterözelliği de en modern tarayıcılarda (Kenar dahil, fakat IE11). SVG görüntüleri ve diğer öğeler üzerinde çalışır. Renkleri bağımsız olarak değiştirmenize izin vermese de, renkleri kullanabilir hue-rotateveya invertdeğiştirebilirsiniz. Bir simge "devre dışı" sürümünü göstermek için aşağıdaki CSS sınıfını kullanın (burada orijinal doygun renk ile bir SVG resim):

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

Bu, çoğu tarayıcıda açık gri hale getirir. IE'de (ve muhtemelen test etmediğim Opera Mini), gri olmasa da, hala oldukça iyi görünen opaklık özelliği tarafından fark edilir bir şekilde solmuştur.

Twemoji zil simgesi için dört farklı CSS sınıfına sahip bir örnek : orijinal (sarı), yukarıdaki "devre dışı" sınıfı, hue-rotate(yeşil) ve invert(mavi).


Sadece simge fontları oluşturmak istemiyorsanız ters çevirmenin iyi bir çözüm olduğunu fark ettim. Bu jQuery kodunu web sitemin başlığında css renk özelliğine göre değiştirmek için kullandım (beyaz png simgeleri kullandığımı fark et):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 15:17

Harika bir yaklaşım. Hedef simge rengini eklemek için SVG xml'imi düzenledikten sonra gri renkli bir .icon devre dışı sınıfı kullandı.
SushiGuy

Eski araştırır filtreyi desteklemediği Uyarı: w3schools.com/cssref/css3_pr_filter.asp
JillAndMe

25

Alternatif olarak mask, CSS kullanabilirsiniz , verilen tarayıcı desteği iyi değil ancak bir yedek kullanabilirsiniz

.frame {
    background: blue;
    -webkit-mask: url(image.svg) center / contain no-repeat;
}

14
MDN belirtir-webkit-mask herhangi bir üretim web sitesinde kullanılmamalıdır.
vaindil

1
svg'yi

Belki şimdi, dört yıl sonra bu çözümün tüm büyük tarayıcılarda çalıştığını söylemek önemlidir. Sadece burada test edildi ve% 100 tamam.
Daniel Lemes

23

Sayfanıza dosya ekleyebiliyorsanız (PHP, seçtiğiniz CMS'niz aracılığıyla dahil edebilir veya ekleyebilir), SVG kodunu ekleyebilir ve sayfanıza ekleyebilirsiniz. Bu, SVG kaynağını sayfaya yapıştırmakla aynı şekilde çalışır, ancak sayfa işaretlemesini daha temiz hale getirir.

Bunun avantajı, fareyle üzerine gelmek için SVG'nizin bölümlerini CSS üzerinden hedefleyebilmenizdir - javascript gerekmez.

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

Bunun gibi bir CSS kuralı kullanmanız yeterlidir:

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

!importantDolgu rengini geçersiz kılmak için bitin gerekli olduğunu unutmayın .


3
AngularJS kullananlar için:<div ng-include="'svg.svg'"></div>
Mikel

Svg veri bir veritabanında depolamak değil çok zarif bir çözüm. Yanlış değil, ancak şablonlar veya diğer varlıkları kullanmak yerine xml / html / svg DOM verilerini bir API veya CMS'den pompalamak yanlış geliyor.
ChristoKiwi

Bu katkı için teşekkür ederim ... Bugün en gelişmiş siteler svg veri her türlü faaliyet için izin yuva, bu cevap olmadan ben tahmin olmaz!
webMan

Ayrıca, SVG'nizde saydam alanlar varsa, bunlar asılı gezinme olarak sayılmaz ve "gösterişli havada asılı kalma" yaşayabilirsiniz. Bunu düzeltmek için bir sarmalayıcı öğesi (uygunsa bir <a>) ekleyin ve ardından bunu CSS kuralına ekleyin. #pathidorclass:hover, .wrapperclass:hover #pathidorclass { fill: green; }Ya da şimdi zaten sarmalayıcı öğesi üzerinden hedeflediğiniz için SVG yolunun orijinal fareyle üzerine gelmeyin.
Neil Monroe

18

@Drew Baker sorunu çözmek için harika bir çözüm verdi. Kod düzgün çalışıyor. Ancak, AngularJ kullanan kullanıcılar jQuery'ye çok fazla bağımlılık bulabilirler. Sonuç olarak, @Drew Baker'ın çözümünü takip eden bir kod olan AngularJS kullanıcıları için yapıştırmanın iyi bir fikir olduğunu düşündüm.

Aynı kodun AngularJs yolu

1. Html : html dosyasındaki feryat etiketini kullanın:

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

2. Yönerge : Bu etiketi tanımanız gereken yönerge olacaktır:

'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. Karma-yasemin ile birim test :

'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
çözümünüz çalışmıyor, olabilir<div ng-include="/icons/my.svg" class="any-class-you-wish"></div>
Guillaume Vincent

@guillaumevincent ile kullanmak istiyorsanız ng-includebu satırı şu var imgURL = element.attr('src');şekilde değiştirin:var imgURL = element.attr('ng-include');
Max

Bu çok kullanışlı bir çözümdür, ancak performansı oldukça zorlayabileceği için aşırı kullanmamaya dikkat edin - IE, bir makale listesinde veya bunun gibi bir şeyde tekrarlanan 5 paylaşım simgeler kümesi.
skxc

1
IE'de kodunuzla ilgili bir sorun var. Sadece kullanabilirsiniz if (typeof(imgClass) !== 'undefined') { $svg.setAttribute("class", imgClass); }bölünmenin ve döngü yerine.
Robert Bokori

2
Mükemmel iş! Ancak belirli görüntü için svg ( angular.element(data)[0];) öğesinin ilk öğesini almanız ve IE kullanımı ile çalışmasını sağlamanız gerekir if ($svg.getAttribute('class')) { $svg.setAttribute('class', $svg.getAttribute('class') + ' ' + imgClass); } else { $svg.setAttribute('class', imgClass); }. Ayrıca cache: trueseçeneklere eklemek isteyebilirsiniz , $http.getaksi takdirde sayfanız çok yavaş olabilir.
leo

16

Bunu CSS ile başarmak istediğinizi anlıyorum, ancak küçük, basit bir görüntü olması durumunda bir hatırlatma - her zaman Notepad ++ 'da açıp yolu / her şeyin dolgusunu değiştirebilirsiniz:

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

Bir ton çirkin senaryoyu kurtarabilirdi. Tabanı özür dilerim, ama bazen basit çözümler göz ardı edilebilir.

... birden fazla svg görüntüsünü değiştirmek bile bu soru için bazı kod snippet'lerinden daha küçük olabilir.


7

AngularJS ile bu sorunu çözmek için bir direktif yazdım. Burada mevcuttur - ngReusableSvg .

SVG öğesini oluşturulduktan sonra değiştirir ve bir divöğenin içine yerleştirerek CSS'sini kolayca değiştirilebilir hale getirir. Bu, aynı SVG dosyasının farklı boyutlarda / renklerde farklı yerlerde kullanılmasına yardımcı olur.

Kullanımı basit:

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

Bundan sonra kolayca sahip olabilirsiniz:

.svg-class svg {
    fill: red; // whichever color you want
}

Merhaba, bu çözümü sağladığınız için teşekkürler. Ben denedim ve verir: <div ng-click = "eventHandler ()" ng-class = "classEventHandler ()" style = "yükseklik: 30px; genişlik: 30px; float: left;" class = "svg-class" id = "my-svg" height = "30" width = "30"> [[object SVGSVGElement]] </div> HTML'ye [[object SVGSVGElement]] koyar. Sorunun ne olduğunu biliyor musun? Başka bir soru, performans üzerinde büyük bir etkisi var mı yoksa bir sayfadaki birçok svg'de kullanabilir miyim? Ve son olarak, hala açısal 1.3'te (bower).
bersling

Hangi açısal sürümü kullanıyorsunuz? Sorununuzla karşılaşmadınız .. belki SVG ile ilgili bir şey var mı? Performans açısından anahtar nispeten ağır, kendimi 10 gibi kullandım ve iyiydi .. Sanırım bu miktar / boyuta bağlı, bu yüzden deneme ve onunla deneme. Bower ile ilgili sorun nedir? Farklı bir sürüm mü kullanıyorsunuz ve bir çakışma var mı?
Omri Aharon

5

TL / DR: Buraya gidin-> https://codepen.io/sosuke/pen/Pjoqqp

Açıklama:

Ben böyle bir şey html olduğunu varsayalım:

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

Kesinlikle filtre yoluna gidin, yani. svg'niz büyük olasılıkla siyah veya beyazdır. İstediğiniz rengin olmasını sağlamak için bir filtre uygulayabilirsiniz, örneğin, nane yeşili istediğim siyah bir svg var. Önce beyaz (tersine teknik olarak tüm RGB renkleri olan) tersine çeviririm, ardından renk doygunluğu vb.İle oynarım.

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

Daha da iyisi, istediğiniz altıgeni sizin için bir filtreye dönüştürmek için bir araç kullanabilmenizdir: https://codepen.io/sosuke/pen/Pjoqqp


Bu harika bir css sadece çözüm, artı altıgen gelen filtre kodunu sadece awesome.
Richi González

4

Kabul knockout.jsedilen cevaba dayanan bir sürüm :

Önemli: Aslında değiştirilmesi için de jQuery gerektirir, ancak bazıları için yararlı olabileceğini düşündüm.

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

        }
    };

Ardından data-bind="svgConvert: true"img etiketinize başvurun .

Bu çözüm, imgetiketi bir SVG ile tamamen değiştirir ve ek bağlantılara saygı duyulmaz.


2
Bu harika! Bir sonraki seviyeye taşımak istiyorsanız, önbelleğe alma içeren güncellenmiş bir sürümümüz var, bu yüzden aynı SVG iki kez talep edilmiyor. github.com/funkhaus/style-guide/blob/master/template/js/…
Drew Baker

Bu konuda biraz endişeliydim ama kendime bakacak zamanım yoktu. Hızlı bir şeye ihtiyacım vardı
Simon_Weaver

1
@DrewBaker aslında img etiketi dosyayı talep ve daha sonra gettekrar talep daha endişeliydi . Etiketteki srcbir data-srcözniteliği değiştirmeyi düşündüm img, ancak modern tarayıcıların dosyayı zaten önbelleğe alacak kadar akıllı olduğu sonucuna vardım
Simon_Weaver

3

İşte bir çerçeve kodu, sadece saf 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)
        })

3

onloadEnjeksiyonu tetiklemek için özniteliği kullanan SVGInject adında bir açık kaynak kitaplığı vardır . GitHub projesini https://github.com/iconfu/svg-inject adresinde bulabilirsiniz.

İşte SVGInject kullanarak minimal bir örnek:

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

Görüntü yüklendikten sonra onload="SVGInject(this)enjeksiyonu tetikler ve <img>eleman srcöznitelikte sağlanan SVG dosyasının içeriği ile değiştirilir .

SVG enjeksiyonuyla ilgili çeşitli sorunları çözer:

  1. SVG'ler enjeksiyon bitene kadar gizlenebilir. Yükleme sırasında bir stil zaten uygulanmışsa, aksi takdirde kısa bir "styled content flash" a neden olan bu önemlidir.

  2. <img>Unsurları otomatik kendi kendilerini tam enjekte edin. SVG'leri dinamik olarak eklerseniz, enjeksiyon işlevini tekrar çağırmak konusunda endişelenmenize gerek yoktur.

  3. Bir SVG birden çok kez enjekte edilirse, belgede birden çok kez aynı kimliğe sahip olmaktan kaçınmak için SVG'deki her kimliğe rastgele bir dize eklenir.

SVGInject düz bir Javascripttir ve SVG'yi destekleyen tüm tarayıcılarla çalışır.

Feragatname: SVGInject'in ortak yazarıyım


1
Bu çözümü en çok seviyorum, çünkü dinamik olarak eklenen SVG'lerle ilgileniyor.
19:21

2

Daha fazla sayıda svg resmimiz varsa, font dosyalarının yardımını da alabiliriz. Https://glyphter.com/
gibi siteler bize SVG'larımızdan bir yazı tipi dosyası alabilir.


Örneğin

@font-face {
    font-family: 'iconFont';
    src: url('iconFont.eot');
}
#target{
    color: white;
    font-size:96px;
    font-family:iconFont;
}

5
Şahsen "yazı tipi olarak resim" tekniğinden nefret ediyorum. Görüntü eklemeyi / düzenlemeyi zorlaştırır, çok fazla saçma işaretleme ekler. Yazı tipleri yazı tipleri, resimler resim vb.
Drew Baker

Kabul. Karakterlere atanan görüntüleri de hatırlamanız / aramanız gerekir. ancak resimler medyadan daha metin olarak daha hareket, simgeler / düğme / mermilerle olarak kullanılan spesifik durum için, font-dosyaları da bir alternatif olabilir
Abhishek Borar

github bile artık simge için yazı tipi kullanmıyor github.com/blog/2112-delivering-octicons-with-svg
gagarine

2

Bunun için veri görüntüsünü kullanabilirsiniz. data-image (data-URI) kullanarak SVG'ye satır içi gibi erişebilirsiniz.

İşte saf CSS ve SVG kullanan rollover efekti.

Dağınık olduğunu biliyorum ama bu şekilde yapabilirsiniz.

 .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'nizi veri url'sine buradan dönüştürebilirsiniz

  1. https://codepen.io/elliz/full/ygvgay
  2. https://websemantics.uk/tools/svg-to-background-image-conversion/

Bu, yalnızca belirli yolların / çokgenlerin / vb. Fareyle üzerine gelindiğinde değişmesini istediğiniz karmaşık SVG'ler için işe yaramaz mı?
Drew Baker

Hayır yapabilirsin ... ama çok karmaşık
patelarpan

Sadece simge için çözümler
patelarpan

Bazıları simge ile çalışırsa. O zaman harika. Bootstrap 4 de bu tekniği kullanıyor
patelarpan

2

SVG temel olarak kod olduğundan, sadece içeriğe ihtiyacınız vardır. İçerik elde etmek için PHP kullandım, ancak istediğinizi kullanabilirsiniz.

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

Sonra, div kabının içine "olduğu gibi" içerik yazdırdım

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

CSS'de kabın SVG alt öğesi için kuralı sonlandırmak için

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

Bu sonuçları malzeme simgesi SVG ile aldım:

  1. Mozilla Firefox 59.0.2 (64 bit) Linux

resim açıklamasını buraya girin

  1. Google Chrome66.0.3359.181 (Derleme resmi) (64 bit) Linux

resim açıklamasını buraya girin

  1. Opera 53.0.2907.37 Linux

resim açıklamasını buraya girin


1

JQuery'nin DOM'nizdeki tüm svg öğelerini işlemesini ve DOM'nizin makul boyutta olmasını istiyorsanız, seçilen çözüm iyidir. Ancak DOM'niz büyükse ve DOM'nizin parçalarını dinamik olarak yüklemeye karar verirseniz, sadece svg öğelerini güncellemek için tüm DOM'u yeniden taramak gerçekten mantıklı değildir. Bunun yerine, bunu yapmak için bir jQuery eklentisi kullanın:

/**
 * 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'nizde bir svg öğesini aşağıdaki gibi belirtin:

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

Ve eklentiyi uygulayın:

$(".mySVGClass").svgLoader();

Evet, verdiğim kodu kullanmanın kesinlikle daha etkili yolları var. Üretim sitelerinde aslında bunu nasıl kullanıyoruz. SVG'leri önbelleğe alır! github.com/funkhaus/style-guide/blob/master/template/js/…
Drew Baker

1

için: vurgulu etkinlik animasyonları, stilleri svg dosyasının içinde bırakabiliriz,

<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'de kontrol et

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.