2013-08-25 4 views
52

У меня есть несколько графических изображений SVG, которые я хотел бы изменить цвета через внешние таблицы стилей - не напрямую в каждом SVG-файле. Я не помещаю графику в строку, но сохраняю их в папке с изображениями и указывая на них.Как стиль SVG с внешним CSS?

Я реализовал их таким образом, чтобы всплывающие подсказки работали, и я также обернул их в тег <a>, чтобы разрешить ссылку.

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

Я поставил следующий в моем внешнем файле CSS (main.css):

.socIcon g {fill:red;} 

Тем не менее он не имеет эффект на графике. Я также пробовал путь .socIcon g path {} и .socIcon {}.

Что-то не так, возможно, моя реализация не разрешает внешние модификации CSS, или я пропустил шаг? Я бы очень признателен за вашу помощь! Мне просто нужно изменить цвета изображения SVG через мою внешнюю таблицу стилей, но я не могу потерять подсказку и способность ссылок. (Возможно, я смогу жить без подсказок.) Спасибо!

+0

См http://stackoverflow.com/questions/12604095/security-restrictions-when-linking-to-external-stylesheet- from-svg-when-embed –

+0

Попробуйте 'svg {fill: red; } 'или присвоить вашему пути имя класса. Например. ' Dwza

ответ

53

Ваш файл main.css будет иметь эффект только на содержание SVG, если файл SVG инлайн включен в 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> 

Если вы хотите сохранить SVG в файлах CSS должен быть определен внутри SVG-файла.

Вы можете сделать это со стилем тега:

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> 

Вы можете использовать инструмент на стороне сервера, чтобы обновить тег стиля в зависимости от активного стиля. В рубине вы могли добиться этого с Нокогири. SVG - это просто XML. Таким образом, возможно, существует много XML-библиотек, которые, возможно, могут это достичь.

Если вы не можете этого сделать, вам придется просто использовать их, как если бы они были PNG; создавая набор для каждого стиля и сохраняя их стили inline.

+10

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

+0

Я попытался выполнить это решение, но у меня есть встроенная анимация css, которая не работает с графикой SVG. Это ограничение этой техники? Я могу нацелить путь на заливку inline css просто отлично, но анимация css не работает. –

+0

EDIT: Ничего, просто обнаружил, что у SVG-файлов есть свой собственный «специальный» css (fill and stroke - не может найти много другого, что поддерживается) –

2

При использовании в теге <image> SVG должен содержаться в одном файле по соображениям конфиденциальности. У этого bugzilla bug есть более подробная информация о том, почему это так. К сожалению, вы не можете использовать другой тег, такой как , потому что это не будет работать как ссылка, поэтому вам придется встроить CSS в тег <style> внутри самого файла.

Еще один способ сделать это будет иметь данные SVG в основном HTML файл, т.е.

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

Вы можете стиль, который с помощью внешнего файла CSS с использованием HTML <link> тега.

+2

Я не могу поместить стили в файлы. Я на самом деле собираюсь изменить цвета этих изображений на основе на какой цветовой схеме пользователь выбрал мой сайт. Моя текущая реализация заключается в добавлении таблицы стилей на главную страницу, которая перезаписывает стили по умолчанию.Я хотел внести изменения цвета в этот файл, чтобы повлиять на встроенную графику SVG. Но это не сработает, потому что я должен ссылаться на таблицу стилей из SVG-файла (если не существует способа добавить эту ссылку ко всем файлам SVG, используя JavaScript). Конечно, есть возможность разрешить внешние SVG-файлы, внешние CSS, ссылки и всплывающие подсказки. – Joey

+1

Невозможно выполнить то, что вы хотите сделать из-за модели безопасности браузера. Вы не можете использовать javascript для управления SVG при использовании в качестве изображения. Подумайте о SVG при использовании в качестве изображения, как анимированный файл png или gif, все в одном файле и без доступа к сценариям. –

1

«Я намереваюсь изменить цвета этих изображений, исходя из того, какую цветовую схему пользователь выбрал для моего сайта». - Jordan10 hours ago

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

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

А позже вы могли бы использовать этот файл как filename.php?color=#ffffff получить файл Г в нужном цвете.

+6

Обратите внимание, что этот код не проверяет пользовательский ввод - все может быть предоставлено как цвет, и ваш SVG может отображаться очень интересными способами ... Не уверен, что это влияет на вас, но вы должны сделать это привычкой ** ВСЕГДА * * проверять ввод пользователя. Что-то вроде этого поможет: 'if (! Preg_match ('/^[#] [0-9a-f] {6} $/i', $ _GET ['color'])) die ('Oops!'); '(помещаем его где-то в начальный блок PHP). – johndodo

3

Должно быть возможно сделать сначала вложение внешних изображений svg. Посмотрите здесь, например:

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

+2

Это замечательная вещь, спасибо – eballeste

+2

Это importat, чтобы отметить, что это будет работать только в том случае, если у вас есть изображение, размещенное в том же домене, что и html, или на специально настроенной политике crossdomain на сервере изображений. $ .get будет использовать ajax и не сможет загрузить изображение с внешнего сервера, если нет допустимого заголовка допустимого доступа – user151496

25

Вы можете делать то, что вы хотите, с одной (важно) предостережением: пути в пределах вашего символа не могут быть стилизованы независимо друг от друга с помощью внешнего CSS - вы можете установить только свойство для всего символа с помощью этого метода. Итак, если у вас есть два пути в вашем символе и хотите, чтобы у них были разные цвета заливки, это не сработает, но если вы хотите, чтобы все ваши пути были одинаковыми, это должно работать.

В вашем HTML файл, вы хотите что-то вроде этого:

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

И во внешнем файле SVG вы хотите что-то вроде этого:

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

Поменять класс на svg тег (в ваш html) от fill-red до fill-blue и ta-da ... у вас синий, а не красный.

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

<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

. Я думаю, что предостережение должно быть действительно: поддержка браузера, хотя! Хорошая ссылка (более подробно, чем caniuse): https://css-tricks.com/svg-fragment-identifiers-work/ – ptim

+0

Поддержка браузера: http://caniuse.com/#feat=svg-fragment – Thomas

3

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

Например, если у вас есть SVG графики, которая использует цвет заливки красный в коде SVG, вы можете превратить его фиолетовый с оттенком поворота установки 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); 
} 

Эксперимент с другими hue-rotate, чтобы найти нужные цвета.

Чтобы быть ясным, приведенный выше CSS относится к CSS, который применяется к вашему HTML-документу. Вы создаете тег img в HTML-коде, не устраивая код SVG.

Обратите внимание, что это не будет работать с графикой, заполненной черным или белым или серым цветом. У вас должен быть фактический цвет, чтобы повернуть оттенок этого цвета.

5

Можно создать стиль SVG путем динамического создания элемента стиля в JavaScript и добавления его в элемент SVG. Хакки, но это работает.

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

Вы можете сгенерировать JavaScript динамически в PHP, если вы хотите - тот факт, что это возможно в JavaScript открывает множество возможностей.

+0

эй, я действительно люблю вы решили, и он работает, но мне нужно принять его на моем situtation, если вы готовы помочь os course, у меня есть внутри тег стиля, который я могу удалить их вручную и запустить этот код, чтобы он создавал стиль, есть ли путь я могу удалить defs, а затем воссоздать элемент, как вы это сделали, или просто обновить его, а также url получил ошибку url не определен, можете ли вы помочь, спасибо –

1

Очень быстрое решение для динамического стиля с внешней таблицей стилей CSS, если вы используете тег <object>, чтобы вставить свой svg.

В этом примере будет добавлен класс к корневому тегу <svg> при щелчке по родительскому элементу.

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"); 
    } 
}); 

на клик родительского элемента:

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

, то вы можете управлять вашим CSS

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

, похоже, не работает, не могли бы вы добавить рабочий пример ? –

0

Что работает для меня: стиль тег @import правило

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

Я знаю его старый пост, но только для устранения этой проблемы ... вы просто используете свои классы не в том месте: D

Прежде всего, вы можете использовать

svg { fill: red; } 

в вашем main.css, чтобы получить его красным. Это имеет эффект. Вы также можете использовать селектора узлов, чтобы получить конкретные шаблоны.

Во-вторых, вы объявили класс img -Tag.

<img class='socIcon'.... 

Вы действительно должны объявить его в своем 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 class="myClassForMyPath" d="M28.44......./> 
</g> 
</svg> 

Теперь вы можете изменить цвет в вашем main.css как

.myClassForMyPath { 
    fill: yellow; 
} 
Смежные вопросы