2013-08-25 24 views
52

Tôi có một số đồ họa SVG mà tôi muốn sửa đổi màu sắc thông qua các tờ mẫu ngoài của tôi - không trực tiếp trong mỗi tệp SVG. Tôi không đặt đồ họa trực tuyến, nhưng lưu trữ chúng trong thư mục hình ảnh của tôi và chỉ vào chúng.Làm cách nào để tạo kiểu SVG bằng CSS bên ngoài?

Tôi đã triển khai chúng theo cách này để cho phép các chú giải công cụ hoạt động và tôi cũng bao gồm mỗi thẻ trong một thẻ <a> để cho phép liên kết.

<a href='http://youtube.com/...' target='_blank'><img class='socIcon' src='images/socYouTube.svg' title='View my videos on YouTube' alt='YouTube' /></a> 

Và đây là mã của đồ họa SVG:

<?xml version="1.0" encoding="utf-8"?> 
<?xml-stylesheet href="stylesheets/main.css" type="text/css"?> 
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69"> 
<g> 
    <path d="M28.44......./> 
</g> 
</svg> 

tôi đặt sau trong file CSS bên ngoài của tôi (main.css):

.socIcon g {fill:red;} 

Tuy nhiên, nó không có ảnh hưởng đến đồ họa. Tôi cũng đã thử đường dẫn .socIcon g {} và .socIcon {}.

Có điều gì đó không đúng, có lẽ việc triển khai của tôi không cho phép sửa đổi CSS bên ngoài hoặc tôi đã bỏ lỡ một bước? Tôi thực sự đánh giá cao sự giúp đỡ của bạn! Tôi chỉ cần khả năng sửa đổi màu sắc của đồ họa SVG thông qua biểu định kiểu bên ngoài của tôi, nhưng tôi không thể mất khả năng chú giải công cụ và liên kết. (Tôi có thể sống mà không có chú giải công cụ mặc dù.) Cảm ơn!

+0

Xem http://stackoverflow.com/questions/12604095/security-restrictions-when-linking-to-external-stylesheet- từ-svg-khi-nhúng –

+0

Thử 'svg {fill: red; } 'hoặc đặt tên cho đường dẫn của bạn. Ví dụ. ' Dwza

Trả lời

53

file main.css của bạn sẽ chỉ có ảnh hưởng đến nội dung của SVG nếu các tập tin SVG được bao gồm nội tuyến trong HTML:

https://developer.mozilla.org/en/docs/SVG_In_HTML_Introduction

<html> 
    <body> 
    <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69"> 
    <g> 
     <path d="M28.44......./> 
    </g> 
    </svg> 
</html> 

Nếu bạn muốn giữ SVG của bạn trong các tệp, CSS cần được xác định bên trong tệp SVG.

Bạn có thể làm điều đó với một thẻ phong cách:

http://www.w3.org/TR/SVG/styling.html#StyleElementExample

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
    "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" 
    width="50px" height="50px" viewBox="0 0 50 50"> 
    <defs> 
    <style type="text/css"><![CDATA[ 
     .socIcon g { 
     fill:red; 
     } 
    ]]></style> 
    </defs> 
    <g> 
    <path d="M28.44......./> 
    </g> 
</svg> 

Bạn có thể sử dụng một công cụ ở phía máy chủ để cập nhật các tag style tùy thuộc vào phong cách hoạt động. Trong ruby ​​bạn có thể đạt được điều này với Nokogiri. SVG chỉ là XML. Vì vậy, có thể có nhiều thư viện XML sẵn có mà có thể đạt được điều này.

Nếu bạn không thể làm điều đó, bạn sẽ phải chỉ sử dụng chúng như thể chúng là PNG; tạo một tập hợp cho mỗi kiểu và lưu kiểu nội tuyến của chúng.

+10

Điều này có nghĩa là không có phương pháp nào được hưởng lợi từ việc lưu bộ nhớ đệm SVG và áp dụng kiểu dáng đa dạng? Nội tuyến dường như không có bộ nhớ cache tốt, trong khi các phương pháp khác sẽ yêu cầu tạo nhiều phiên bản của hình ảnh, loại bỏ bất kỳ lợi ích nào từ việc lưu chúng vào bộ đệm. – msg45f

+0

Tôi đã cố gắng làm theo giải pháp này nhưng tôi có một số css hoạt hình nội tuyến không hoạt động trên đồ họa SVG. Đây có phải là hạn chế của kỹ thuật này không? Tôi có thể nhắm mục tiêu đường dẫn đầy với css nội tuyến tốt nhưng hình ảnh động css dường như không hoạt động. –

+0

EDIT: Không sao, chỉ phát hiện ra rằng các tệp SVG có css 'đặc biệt' của riêng mình (điền và đột quỵ - không thể tìm thấy nhiều thứ khác được hỗ trợ) –

2

Khi được sử dụng trong thẻ <image> SVG phải được chứa trong một tệp duy nhất vì lý do bảo mật. Điều này bugzilla bug có thêm chi tiết về chính xác lý do tại sao điều này là như vậy. Rất tiếc, bạn không thể sử dụng một thẻ khác như là vì thẻ đó sẽ không hoạt động dưới dạng liên kết, do đó bạn sẽ phải nhúng CSS vào thẻ <style> trong chính tệp đó.

Một cách khác để làm điều này sẽ có dữ liệu SVG bên trong file html chính ví dụ:

<a href='http://youtube.com/...' target='_blank'> 
    <svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69"> 
    <g> 
     <path d="M28.44......./> 
    </g> 
    </svg> 
</a> 

Bạn có thể phong cách với một file CSS bên ngoài sử dụng thẻ HTML <link>.

+2

Tôi không thể đặt các kiểu trong các tệp. Tôi thực sự sẽ thay đổi màu của những hình ảnh này về cách phối màu mà người dùng đã chọn cho trang web của tôi. Triển khai hiện tại của tôi là thêm biểu định kiểu vào trang chính ghi đè kiểu mặc định.Tôi muốn đặt những thay đổi màu sắc trong tập tin đó để ảnh hưởng đến đồ họa SVG nhúng. Nhưng điều đó sẽ không hoạt động vì tôi phải liên kết đến biểu định kiểu từ bên trong tệp SVG (trừ khi có cách thêm liên kết đó vào tất cả các tệp SVG sử dụng JavaScript). Chắc chắn có một cách để cho phép các tệp SVG bên ngoài, CSS bên ngoài, liên kết và chú giải công cụ. – Joey

+1

Bạn không thể làm những gì bạn muốn làm vì mô hình bảo mật của trình duyệt. Bạn không thể sử dụng javascript để thao tác SVG khi được sử dụng làm hình ảnh. Hãy nghĩ về SVG khi được sử dụng làm hình ảnh giống như tệp png hoặc gif động, tất cả trong một tệp và không có quyền truy cập tập lệnh. –

1

"Tôi thực sự sẽ thay đổi màu của những hình ảnh này dựa trên màu sắc mà người dùng đã chọn cho trang web của tôi". - Jordan10 hours ago

Tôi đề nghị bạn sử dụng PHP cho việc này. Có thực sự không có cách nào tốt hơn để làm điều này mà không cần phông chữ biểu tượng, và nếu bạn chống lại việc sử dụng chúng, bạn có thể thử này:

<?php 

    header('Content-Type: image/svg+xml'); 
    echo '<?xml version="1.0" encoding="utf-8"?>'; 
    $color = $_GET['color']; 

?> 
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69"> 
    <g> 
     <path fill="<?php echo $color; ?>" d="M28.44..."/> 
    </g> 
</svg> 

Và sau đó bạn có thể sử dụng tập tin này như filename.php?color=#ffffff để tải tệp svg trong màu mong muốn.

+6

Lưu ý rằng mã này không kiểm tra đầu vào của người dùng - bất kỳ thứ gì có thể được cung cấp dưới dạng màu và SVG của bạn có thể được hiển thị theo một số cách rất thú vị ... Không chắc chắn nếu nó ảnh hưởng đến bạn, nhưng bạn nên tạo thói quen ** LUÔN * * xác thực đầu vào của người dùng. Một cái gì đó như thế này sẽ giúp: 'if (! Preg_match ('/^[#] [0-9a-f] {6} $/i', $ _GET ['màu'])) chết ('Rất tiếc!'); '(đặt nó ở đâu đó trong khối PHP bắt đầu). – johndodo

3

Bạn có thể thực hiện bằng cách đầu tiên chèn hình ảnh svg bên ngoài. Nhìn đây ví dụ:

Replace All Svg Images With Inline Svg | JAVASCRIPT | Code Snippet Library by Jess Frazelle

+2

đây là một điều tuyệt vời, cảm ơn bạn – eballeste

+2

đó là importat cần lưu ý rằng điều này sẽ chỉ hoạt động nếu bạn có hình ảnh được lưu trữ trên cùng một miền với html hoặc có chính sách crossdomain được định cấu hình đặc biệt trên máy chủ hình ảnh. $ .get sẽ sử dụng ajax và không tải hình ảnh từ máy chủ bên ngoài nếu không có tiêu đề cho phép truy cập hợp lệ – user151496

25

Bạn có thể làm những gì bạn muốn, với một (quan trọng) caveat: các đường dẫn trong biểu tượng của bạn không thể theo kiểu một cách độc lập thông qua CSS bên ngoài - bạn chỉ có thể thiết lập các thuộc tính cho toàn bộ biểu tượng bằng phương pháp này. Vì vậy, nếu bạn có hai đường dẫn trong biểu tượng của bạn và muốn chúng có các màu tô khác nhau, điều này sẽ không hoạt động, nhưng nếu bạn muốn tất cả các đường dẫn của bạn giống nhau, điều này sẽ hoạt động.

Trong file html của bạn, bạn muốn một cái gì đó như thế này:

<style> 
    .fill-red { fill: red; } 
    .fill-blue { fill: blue; } 
</style> 

<a href="//www.example.com/"> 
    <svg class="fill-red"> 
    <use xlink:href="images/icons.svg#example"></use> 
    </svg> 
</a> 

Và trong file SVG bên ngoài bạn muốn một cái gì đó như thế này:

<svg xmlns="http://www.w3.org/2000/svg"> 
    <symbol id="example" viewBox="0 0 256 256"> 
    <path d="M120.... /> 
    </symbol> 
</svg> 

Swap lớp trên thẻ svg (trong html của bạn) từ fill-red đến fill-blue và ta-da ... bạn có màu xanh thay vì màu đỏ.

Bạn có thể vượt qua giới hạn của việc có thể nhắm mục tiêu đường dẫn riêng biệt với CSS bên ngoài bằng cách trộn và kết hợp CSS bên ngoài với một số CSS nội tuyến trên các đường dẫn cụ thể, vì CSS nội dòng sẽ được ưu tiên. Cách tiếp cận này sẽ hoạt động nếu bạn đang làm một cái gì đó giống như một biểu tượng màu trắng trên nền màu, nơi bạn muốn thay đổi màu nền sau qua CSS bên ngoài nhưng bản thân biểu tượng luôn trắng (hoặc ngược lại). Như vậy, với HTML tương tự như trước và một cái gì đó như mã svg này, bạn sẽ giúp bạn có được một nền màu đỏ và một con đường foreground trắng:

<svg xmlns="http://www.w3.org/2000/svg"> 
    <symbol id="example" viewBox="0 0 256 256"> 
    <path class="background" d="M120..." /> 
    <path class="icon" style="fill: white;" d="M20..." /> 
    </symbol> 
</svg> 
+0

câu trả lời hay .. tôi nghĩ rằng báo trước nên thực sự là: Hỗ trợ trình duyệt, mặc dù! tham khảo tốt (chi tiết hơn so với caniuse): https://css-tricks.com/svg-fragment-identifiers-work/ – ptim

+0

Hỗ trợ trình duyệt: http://caniuse.com/#feat=svg-fragment – Thomas

3

Một cách tiếp cận bạn có thể chỉ mất là sử dụng bộ lọc CSS để thay đổi sự xuất hiện của đồ họa SVG trong trình duyệt.

Ví dụ, nếu bạn có một đồ họa SVG có sử dụng một màu fill màu đỏ bên trong mã SVG, bạn có thể biến nó màu tím với một khung cảnh sắc xoay 180 độ:

#theIdOfTheImgTagWithTheSVGInIt { 
    filter: hue-rotate(180deg); 
    -webkit-filter: hue-rotate(180deg); 
    -moz-filter: hue-rotate(180deg); 
    -o-filter: hue-rotate(180deg); 
    -ms-filter: hue-rotate(180deg); 
} 

Thử nghiệm với khác cài đặt xoay màu để tìm các màu bạn muốn.

Để rõ ràng, CSS ở trên đi vào CSS được áp dụng cho tài liệu HTML của bạn. Bạn đang tạo kiểu thẻ img trong mã HTML, không tạo kiểu mã cho SVG.

Và lưu ý rằng thao tác này sẽ không hoạt động với đồ họa có màu đen hoặc trắng hoặc xám. Bạn phải có một màu sắc thực sự trong đó để xoay màu sắc của màu đó.

5

Có thể tạo kiểu SVG bằng cách tự động tạo phần tử kiểu trong JavaScript và thêm phần tử đó vào phần tử SVG. Hacky, nhưng nó hoạt động.

<object id="dynamic-svg" type="image/svg+xml" data="your-svg.svg"> 
    Your browser does not support SVG 
</object> 
<script> 
    var svgHolder = document.querySelector('object#dynamic-svg'); 
    svgHolder.onload = function() { 
     var svgDocument = svgHolder.contentDocument; 
     var style = svgDocument.createElementNS("http://www.w3.org/2000/svg", "style"); 

     // Now (ab)use the @import directive to load make the browser load our css 
     style.textContent = '@import url("/css/your-dynamic-css.css");'; 

     var svgElem = svgDocument.querySelector('svg'); 
     svgElem.insertBefore(style, svgElem.firstChild); 
    }; 
</script> 

Bạn có thể tạo JavaScript động trong PHP nếu bạn muốn - thực tế là điều này có thể trong JavaScript sẽ mở ra vô số khả năng.

+0

hey i thực sự thích bạn giải pháp và nó hoạt động nhưng tôi cần phải chấp nhận nó trên situtation của tôi nếu bạn sẵn sàng giúp os khóa học, tôi có bên trong một thẻ phong cách tôi có thể xóa chúng bằng tay và chạy mã này để nó sẽ tạo ra một phong cách, là có một cách tôi có thể xóa các defs sau đó tạo lại các yếu tố như bạn đã làm hoặc chỉ cần cập nhật nó, và cũng có url có một url lỗi không được định nghĩa bạn có thể vui lòng giúp đỡ, cảm ơn bạn –

1

Giải pháp rất nhanh để có kiểu động với biểu định kiểu css bên ngoài, trong trường hợp bạn đang sử dụng thẻ <object> để nhúng svg của mình.

Ví dụ này sẽ thêm lớp vào thẻ gốc <svg> khi nhấp vào phần tử gốc.

file.svg:

<?xml-stylesheet type="text/css" href="../svg.css"?> 
<svg xmlns="http://www.w3.org/2000/svg" viewBox=""> 
    <g> 
    <path/> 
    </g> 
</svg> 

html:

<a class="parent"> 
    <object data="file.svg"></object> 
</a> 

Jquery:

$(function() { 
    $(document).on('click', '.parent', function(){ 
    $(this).find('object').contents().find('svg').attr("class","selected"); 
    } 
}); 

trên nhấp chuột yếu tố phụ huynh:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="" class="selected"> 
.210

sau đó bạn có thể quản lý css của bạn

svg.css:

path { 
fill:none; 
stroke:#000; 
stroke-miterlimit:1.41; 
stroke-width:0.7px; 
} 

.selected path { 
fill:none; 
stroke:rgb(64, 136, 209); 
stroke-miterlimit:1.41; 
stroke-width:0.7px; 
} 
+0

dường như không hoạt động, bạn có thể thêm một ví dụ làm việc ? –

0

gì làm việc cho tôi: thẻ phong cách với @import quy tắc

<defs> 
    <style type="text/css"> 
     @import url("svg-common.css"); 
    </style> 
</defs> 
1

Tôi biết nó một bài cũ, nhưng chỉ để giải quyết vấn đề này ... bạn chỉ cần sử dụng các lớp học của mình tại địa điểm sai: D

Trước hết bạn có thể sử dụng

svg { fill: red; } 

trong số main.css để làm cho màu đỏ. Điều này không có hiệu lực. Bạn cũng có thể sử dụng các bộ chọn nút để có được các đường dẫn cụ thể.

Điều thứ hai là bạn đã hủy lớp học thành img -Tag.

<img class='socIcon'.... 

Bạn nên khai báo nó bên trong SVG của mình. nếu bạn có những con đường khác nhau, bạn có thể xác định thêm tất nhiên.

<?xml version="1.0" encoding="utf-8"?> 
<?xml-stylesheet href="stylesheets/main.css" type="text/css"?> 
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69"> 
<g> 
    <path class="myClassForMyPath" d="M28.44......./> 
</g> 
</svg> 

bây giờ bạn có thể thay đổi màu sắc trong bạn main.css như

.myClassForMyPath { 
    fill: yellow; 
} 
Các vấn đề liên quan