Размещение SVG-вывода непосредственно в строке с кодом страницы. Я могу просто изменить цвета заливки с помощью CSS следующим образом:
polygon.mystar {
fill: blue;
}
circle.mycircle {
fill: green;
}
Это отлично работает, однако я ищу способ изменить атрибут "fill" SVG, когда он будет использоваться как BACKGROUND-IMAGE.
html {
background-image: url(../img/bg.svg);
}
Как я могу изменить цвета сейчас? Возможно ли это?
Для справки, вот содержимое моего внешнего файла SVG:
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="320px" height="100px" viewBox="0 0 320 100" enable-background="new 0 0 320 100" xml:space="preserve">
<polygon class="mystar" fill="#3CB54A" points="134.973,14.204 143.295,31.066 161.903,33.77 148.438,46.896 151.617,65.43 134.973,56.679
118.329,65.43 121.507,46.896 108.042,33.77 126.65,31.066 "/>
<circle class="mycircle" fill="#ED1F24" cx="202.028" cy="58.342" r="12.26"/>
</svg>
Один из способов сделать это - обслуживать ваш svg с какого-либо серверного механизма. Просто создайте сторону сервера ресурсов, которая выводит ваш svg в соответствии с параметрами GET, и вы обслуживаете его по определенному URL.
Тогда вы просто используете этот URL в вашем CSS.
Потому что, как фоновое изображение, оно не является частью DOM, и вы не можете им манипулировать. Другой возможностью было бы использовать его регулярно, встраивать его в страницу обычным способом, но расположить его абсолютно, сделать его полной шириной и высотой страницы, а затем использовать свойство z-index css, чтобы поместить его позади всех других элементов DOM. на странице.
<?php header('Content-type: image/svg+xml'); ?>
Мне нужно было что-то похожее и хотелось придерживаться CSS. Здесь используются слайсы LESS и SCSS, а также простой CSS, который может помочь вам в этом. К сожалению, поддержка браузера немного слаба. Подробнее о поддержке браузера см. Ниже.
LESS mixin:
.element-color(@color) {
background-image: url('data:image/svg+xml;utf8,<svg ...><g stroke="@{color}" ... /></g></svg>');
}
МЕНЬШЕ использование:
.element-color(#fff);
SCSS mixin:
@mixin element-color($color) {
background-image: url('data:image/svg+xml;utf8,<svg ...><g stroke="#{$color}" ... /></g></svg>');
}
Использование SCSS:
@include element-color(#fff);
CSS
// color: red
background-image: url('data:image/svg+xml;utf8,<svg ...><g stroke="red" ... /></g></svg>');
Вот подробнее о внедрении полного SVG-кода в ваш файл CSS. В нем также упоминается совместимость с браузером, которая слишком мала, чтобы это было жизнеспособным вариантом.
Еще один подход - использовать маску. Затем вы меняете цвет фона маскируемого элемента. Это имеет тот же эффект, что и изменение атрибута заполнения svg.
HTML:
<glyph class="star"/>
<glyph class="heart" />
<glyph class="heart" style="background-color: green"/>
<glyph class="heart" style="background-color: blue"/>
CSS
glyph {
display: inline-block;
width: 24px;
height: 24px;
}
glyph.star {
-webkit-mask: url(star.svg) no-repeat 100% 100%;
mask: url(star.svg) no-repeat 100% 100%;
-webkit-mask-size: cover;
mask-size: cover;
background-color: yellow;
}
glyph.heart {
-webkit-mask: url(heart.svg) no-repeat 100% 100%;
mask: url(heart.svg) no-repeat 100% 100%;
-webkit-mask-size: cover;
mask-size: cover;
background-color: red;
}
Здесь вы найдете полный учебник: http://codepen.io/noahblon/blog/coloring-svgs-in-css-background-images (а не мой собственный). Он предлагает множество подходов (не ограничиваясь только маской).
mask
не поддерживается ни IE, ни Edge: caniuse.com/#search=mask
Вы можете использовать CSS-маски. С помощью свойства 'mask' вы создаете маску, которая применяется к элементу.
.icon {
background-color: red;
-webkit-mask-image: url(icon.svg);
mask-image: url(icon.svg);
}
Для получения дополнительной информации см. Эту замечательную статью: https://codepen.io/noahblon/post/coloring-svgs-in-css-background-images
Это возможно с Сасс! Единственное, что вам нужно сделать, это URL-код вашего кода svg. И это возможно с помощью вспомогательной функции в Sass. Я сделал код для этого. Посмотрите на это:
http://codepen.io/philippkuehn/pen/zGEjxB
// choose a color
$icon-color: #F84830;
// functions to urlencode the svg string
@function str-replace($string, $search, $replace: '') {
$index: str-index($string, $search);
@if $index {
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
}
@return $string;
}
@function url-encode($string) {
$map: (
"%": "%25",
"<": "%3C",
">": "%3E",
" ": "%20",
"!": "%21",
"*": "%2A",
"'": "%27",
'"': "%22",
"(": "%28",
")": "%29",
";": "%3B",
":": "%3A",
"@": "%40",
"&": "%26",
"=": "%3D",
"+": "%2B",
"$": "%24",
",": "%2C",
"/": "%2F",
"?": "%3F",
"#": "%23",
"[": "%5B",
"]": "%5D"
);
$new: $string;
@each $search, $replace in $map {
$new: str-replace($new, $search, $replace);
}
@return $new;
}
@function inline-svg($string) {
@return url('data:image/svg+xml;utf8,#{url-encode($string)}');
}
// icon styles
// note the fill="' + $icon-color + '"
.icon {
display: inline-block;
width: 50px;
height: 50px;
background: inline-svg('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 30 30" enable-background="new 0 0 30 30" xml:space="preserve">
<path fill="' + $icon-color + '" d="M18.7,10.1c-0.6,0.7-1,1.6-0.9,2.6c0,0.7-0.6,0.8-0.9,0.3c-1.1-2.1-0.4-5.1,0.7-7.2c0.2-0.4,0-0.8-0.5-0.7
c-5.8,0.8-9,6.4-6.4,12c0.1,0.3-0.2,0.6-0.5,0.5c-0.6-0.3-1.1-0.7-1.6-1.3c-0.2-0.3-0.4-0.5-0.6-0.8c-0.2-0.4-0.7-0.3-0.8,0.3
c-0.5,2.5,0.3,5.3,2.1,7.1c4.4,4.5,13.9,1.7,13.4-5.1c-0.2-2.9-3.2-4.2-3.3-7.1C19.6,10,19.1,9.6,18.7,10.1z"/>
</svg>');
}
Загрузите svg как текст.
Измените текст svg с помощью javascript, чтобы изменить цвет краски/штриха/заливки [s].
Затем вставьте модифицированную строку svg inline в ваш css, как описано здесь.
Теперь вы можете добиться этого на стороне клиента следующим образом:
var green = '3CB54A';
var red = 'ED1F24';
var svg = '<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="320px" height="100px" viewBox="0 0 320 100" enable-background="new 0 0 320 100" xml:space="preserve"> <polygon class="mystar" fill="#'+green+'" points="134.973,14.204 143.295,31.066 161.903,33.77 148.438,46.896 151.617,65.43 134.973,56.679 118.329,65.43 121.507,46.896 108.042,33.77 126.65,31.066 "/><circle class="mycircle" fill="#'+red+'" cx="202.028" cy="58.342" r="12.26"/></svg>';
var encoded = window.btoa(svg);
document.body.style.background = "url(data:image/svg+xml;base64,"+encoded+")";
Вы можете сохранить SVG в переменной. Затем манипулируйте строкой SVG в зависимости от ваших потребностей (т.е. Установите ширину, высоту, цвет и т.д.). Затем используйте результат для установки фона, например.
$circle-icon-svg: '<svg xmlns="http://www.w3.org/2000/svg"><circle cx="10" cy="10" r="10" /></svg>';
$icon-color: #f00;
$icon-color-hover: #00f;
@function str-replace($string, $search, $replace: '') {
$index: str-index($string, $search);
@if $index {
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
}
@return $string;
}
@function svg-fill ($svg, $color) {
@return str-replace($svg, '<svg', '<svg fill="#{$color}"');
}
@function svg-size ($svg, $width, $height) {
$svg: str-replace($svg, '<svg', '<svg width="#{$width}"');
$svg: str-replace($svg, '<svg', '<svg height="#{$height}"');
@return $svg;
}
.icon {
$icon-svg: svg-size($circle-icon-svg, 20, 20);
width: 20px; height: 20px; background: url('data:image/svg+xml;utf8,#{svg-fill($icon-svg, $icon-color)}');
&:hover {
background: url('data:image/svg+xml;utf8,#{svg-fill($icon-svg, $icon-color-hover)}');
}
}
Я тоже сделал демо, http://sassmeister.com/gist/4cf0265c5d0143a9e734.
Этот код делает несколько предположений о SVG, например. что элемент <svg />
не имеет существующего цвета заливки и не заданы ни свойства ширины, ни высоты. Поскольку вход жестко закодирован в документе SCSS, довольно легко обеспечить соблюдение этих ограничений.
Не беспокойтесь о дублировании кода. gzip сжатие делает незначительную величину незначительной.
.icon {
width: 48px;
height: 48px;
display: inline-block;
background: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/18515/heart.svg) no-repeat 50% 50%;
background-size: cover;
}
.icon-orange {
-webkit-filter: hue-rotate(40deg) saturate(0.5) brightness(390%) saturate(4);
filter: hue-rotate(40deg) saturate(0.5) brightness(390%) saturate(4);
}
.icon-yellow {
-webkit-filter: hue-rotate(70deg) saturate(100);
filter: hue-rotate(70deg) saturate(100);
}
Для этого вы можете создать свою собственную функцию SCSS. Добавьте в файл config.rb следующее.
require 'sass'
require 'cgi'
module Sass::Script::Functions
def inline_svg_image(path, fill)
real_path = File.join(Compass.configuration.images_path, path.value)
svg = data(real_path)
svg.gsub! '{color}', fill.value
encoded_svg = CGI::escape(svg).gsub('+', '%20')
data_url = "url('data:image/svg+xml;charset=utf-8," + encoded_svg + "')"
Sass::Script::String.new(data_url)
end
private
def data(real_path)
if File.readable?(real_path)
File.open(real_path, "rb") {|io| io.read}
else
raise Compass::Error, "File not found or cannot be read: #{real_path}"
end
end
end
Затем вы можете использовать его в своем CSS:
.icon {
background-image: inline-svg-image('icons/icon.svg', '#555');
}
Вам нужно будет отредактировать ваши SVG файлы и заменить любые атрибуты заполнения в разметке fill = "{color}"
Путь значков всегда относится к вашему параметру images_dir в том же файле config.rb.
Как и в некоторых других решениях, но это довольно чисто и сохраняет ваши файлы SCSS в порядке.
В некоторых (очень конкретных) ситуациях это может быть достигнуто с помощью filter. Например, вы можете изменить синее изображение SVG на фиолетовый, поворачивая оттенок 45 градусов с помощью filter: hue-rotate(45deg);
. Поддержка браузера минимальна, но это все еще интересная техника.
Поздно к показу здесь, НО, мне удалось добавить цвет заливки к полигону SVG, если вы можете напрямую редактировать SVG-код, так что, например, следующий svg отображает красный, а не по умолчанию черный. Я не тестировал вне Chrome, но:
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="500px" height="500px" viewBox="0 0 500 500" enable-background="new 0 0 500 500" xml:space="preserve">
<polygon
fill="red"
fill-rule="evenodd" clip-rule="evenodd" points="452.5,233.85 452.5,264.55 110.15,264.2 250.05,390.3 229.3,413.35
47.5,250.7 229.3,86.7 250.05,109.75 112.5,233.5 "/>
</svg>
Это мой любимый метод, но ваша поддержка браузера должна быть очень прогрессивной. С помощью свойства mask вы создаете маску, которая применяется к элементу. Повсюду маска непрозрачна, или сплошная, изображение ниже. Там, где его прозрачно, основное изображение маскируется или скрывается. Синтаксис маски-изображения CSS похож на background-image. посмотреть код > mask
Много IF, но если вы запустили SVG с кодировкой pre64:
<svg fill="#000000
Затем запустится строка с кодировкой base64:
PHN2ZyBmaWxsPSIjMDAwMDAw
если начинается предварительно закодированная строка:
<svg fill="#bfa76e
то это кодируется в:
PHN2ZyBmaWxsPSIjYmZhNzZl
Обе закодированные строки начинаются одинаково:
PHN2ZyBmaWxsPSIj
Причуда кодировки base64 - каждые 3 входных символа становятся 4 выходными символами. При запуске SVG, как это, тогда шестицветный шестицветный цвет начинается точно на границе "кодирования" блока кодирования. Поэтому вы можете легко сделать кросс-браузер JS replace:
output = input.replace(/MDAwMDAw/, "YmZhNzZl");
Но ответ tnt-rox выше - это способ двигаться вперед.