Манипулирование внешними свойствами стиля svg файла с помощью CSS

Я пытаюсь манипулировать внешним .svg файлом через CSS.

HTML

<body>
    <div class="mysvg">
    <img src="decho.svg" alt="decho" width="200px"></img>
    </div>
</body>

CSS

div.mysvg img {
    opacity: .3;
    transition: opacity 1s linear 0s;
}
    div.mysvg img:hover {
    opacity: 1;
}

Этот код работает для непрозрачности, но не для fill или других специальных атрибутов svg, таких как stroke. Я знаю, что не могу сделать это с тегом img, но я искал часы, и я не могу найти правильный способ сделать это с помощью svg или object.

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

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


EDIT:

Мне удалось это сделать, добавив css внутри самого файла .svg. Он должен быть сразу после тега svg.

<svg ...>
<style type="text/css" media="screen">  
    <![CDATA[  
    g {  
        fill: yellow;  
        stroke: black;  
        stroke-width: 1;
        transition: fill 1s linear 0s;
    }
    g:hover {
        fill: blue;
    }
    ]]>  
</style> 
<g>
    <path ...>
</g>
</svg>

Вам также нужно вставить его в качестве object в html, иначе он не будет работать.

<object data="decho.svg" type="image/svg+xml">

Надеюсь, это поможет кому-то искать ответ, подобный моему в будущем. Это помогло мне http://www.hongkiat.com/blog/scalable-vector-graphic-css-styling/.

Ответ 1

Это, на мой взгляд, самый большой недостаток в svg: песочнице.

Файлы Svg изолированы песочницей: в собственном документе, поэтому типичный стиль "fill:" не применяется. Аналогично, css, который вы пишете в своем svg, не будет применяться к остальной части вашего сайта.

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

Реальное решение: "icon-system". Svg font-face или svg спрайты. Подробнее о них здесь.

Работа с непрозрачностью: Непрозрачность применяется к самому объекту/кадру svg, а не к содержимому svg (которые недоступны).

Я также должен отметить, что независимо от того, как вы загружаете эти svg, inline, по ссылке, в объекте, в качестве фона, вы не сможете попасть в песочницу. Вот почему преобразование их в шрифт или использование спрайтов необходимо для использования зависания, фокусировки и других эффектов/переходов.

Ответ 2

Это возможно, если в SVG не задан цвет заливки, а в CSS нет родительского селектора. Например:

У меня есть следующие файлы:

  • icon-sprite.svg (мой внешний спрайт SVG)
  • buttons.scss
  • test.html

Значок-sprite.svg

Я пропустил другие SVG для ясности.

<svg xmlns="http://www.w3.org/2000/svg" style="width:0;height:0;visibility:hidden;">
    <symbol viewBox="0 0 1500 828" id="icon-arrow-3pt-down">
        <title>arrow-3pt-down</title>
        <path d="M1500 0H0l738.9 827.7z"/>
    </symbol>
</svg>

test.html

<button class="button--large">
    Large button
    <svg class="svg" width="20px" height="20px">
        <use xlink:href="icon-sprite.svg#icon-arrow-3pt-down"></use>
    </svg>
</button>

buttons.scss

.svg {
    fill: red;
}

Это не будет работать, если я буду использовать body .svg из-за теневых границ DOM.

SVG external css styling

См. эту статью CSS Tricks для получения дополнительной информации.

Ответ 3

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

Совместим с любыми браузерами, поддерживающими SVG.

<svg width="100%" height="100%" class="draggable">
  <defs>
    <filter id="customColor1">
      <!-- Match hex color for #50A -->
      <feColorMatrix
        in="SourceGraphic"
        type="matrix"
        values="0 0 0 0 0.3333333333333333 0 0 0 0 0 0 0 0 0 0.6666666666666666 0 0 0 1 0"
      ></feColorMatrix>
    </filter>
    
    <filter id="customColor2">
      <!-- Match hex color for #0F0 -->
      <feColorMatrix
        in="SourceGraphic"
        type="matrix"
        values="0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0"
      ></feColorMatrix>
    </filter>
  </defs>
  <image href="#" onclick="location.href='https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/icon-bike-black.svg'; return false;" width="50" height="50"></image>
  <image href="#" onclick="location.href='https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/icon-bike-black.svg'; return false;" filter="url(#customColor1)" width="50" height="50" x="100"></image>
  <image href="#" onclick="location.href='https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/icon-bike-black.svg'; return false;" filter="url(#customColor2)" width="50" height="50" x="200"></image>
  
</svg>