Отбрасывание SVG с помощью css3
Можно ли установить тень для элемента SVG с помощью CSS3, что-то вроде
box-shadow: -5px -5px 5px #888;
-webkit-box-shadow: -5px -5px 5px #888;
Я видел некоторые замечания по созданию тени с использованием эффектов фильтра. Есть ли пример использования только CSS? Ниже приведен рабочий код, в котором стиль Cusor применяется правильно, но без эффекта тени. Пожалуйста, помогите мне получить эффект тени с наименьшим количеством кода.
svg .shadow {
cursor:crosshair;
-moz-box-shadow: -5px -5px 5px #888;
-webkit-box-shadow: -5px -5px 5px #888;
box-shadow: -5px -5px 5px #888;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" viewBox="0 0 120 70">
<rect class="shadow" x="10" y="10" width="100" height="50" fill="#c66" />
</svg>
Ответы
Ответ 1
Вот пример применения drophadow к некоторому svg с использованием свойства filter. Если вы хотите контролировать прозрачность тени, взгляните на этот пример. Атрибут slope
определяет, сколько непрозрачности дать теням.
Соответствующие биты из примера:
<filter id="dropshadow" height="130%">
<feGaussianBlur in="SourceAlpha" stdDeviation="3"/> <!-- stdDeviation is how much to blur -->
<feOffset dx="2" dy="2" result="offsetblur"/> <!-- how much to offset -->
<feComponentTransfer>
<feFuncA type="linear" slope="0.5"/> <!-- slope is the opacity of the shadow -->
</feComponentTransfer>
<feMerge>
<feMergeNode/> <!-- this contains the offset blurred image -->
<feMergeNode in="SourceGraphic"/> <!-- this contains the element that the filter is applied to -->
</feMerge>
</filter>
<circle r="10" style="filter:url(#dropshadow)"/>
Box-shadow определен для работы с CSS-блоками (читай: прямоугольники), тогда как svg немного более выразителен, чем просто прямоугольники. Прочтите учебник по SVG, чтобы узнать больше о том, что вы можете делать с фильтрами SVG.
Ответ 2
Используйте новое свойство filter
CSS.
Поддерживается браузерами webkit, Firefox 34+ и Edge.
Вы можете использовать этот polyfill, который будет поддерживать FF <34, IE6+.
Вы бы использовали это так:
/* Use -webkit- only if supporting: Chrome < 54, iOS < 9.3, Android < 4.4.4 */
.shadow {
-webkit-filter: drop-shadow( 3px 3px 2px rgba(0, 0, 0, .7));
filter: drop-shadow( 3px 3px 2px rgba(0, 0, 0, .7));
/* Similar syntax to box-shadow */
}
<img src="https://upload.wikimedia.org/wikipedia/commons/c/ce/Star_wars2.svg" alt="" class="shadow" width="200">
<!-- Or -->
<svg class="shadow" ...>
<rect x="10" y="10" width="200" height="100" fill="#bada55" />
</svg>
Ответ 3
Итак, как упоминалось в скрытых комментариях принятого ответа Лоренцо Полидори, самый простой вариант, который работает для меня в Chrome (и я уверен, что другие браузеры Webkit):
-webkit-svg-shadow: 0 0 7px #53BE12;
Ответ 4
Самый простой способ, который я нашел, это с feDropShadow
. Я никогда не вернусь к использованию тех невероятно эзотерических имен тегов фильтров, которые я не понимаю.
<filter id="shadow" x="0" y="0" width="200%" height="200%">
<feDropShadow dx="40" dy="40" stdDeviation="35" flood-color="#ff0000" flood-opacity="1" />
</filter>
Ответ 5
Я не знаю о решении только для CSS.
Как вы упомянули, фильтры - это канонический подход к созданию эффектов тени в SVG. Спецификация SVG включает пример этого.
Ответ 6
Черный текст с белой тенью
Другой способ, который я использовал для белой тени (для текста): создать клон для тени:
Примечание: для этого требуется xmlns:xlink="http://www.w3.org/1999/xlink"
в объявлении SVG.
Настоящий текст находится в разделе <defs>
с позицией, стилем, но без определения fill
.
Реальный тест клонируется два раза: первый для тени и второй для самого текста.
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="70"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<filter id="Blur"><feGaussianBlur stdDeviation="0.8" /></filter>
<text style="font-family:sans,helvetica;font-weight:bold;font-size:12pt"
id="Text"><tspan x="12" y="19">
Black text with white shadow
</tspan></text>
</defs>
<rect style="fill:#8AB" width="640" height="70" />
<use style="fill:white;" filter="url(#Blur)" xlink:href="#Text"
transform="translate(1.8,.9)"/>
<use style="fill:black;" xlink:href="#Text"/>
</svg>
Ответ 7
Вероятно, эволюция, кажется, что встроенные фильтры CSS работают хорошо на элементах, определенным образом.
Объявление фильтра css-shadow в элементе svg как в классе, так и во встроенном НЕ работает, как указано ранее.
Но, по крайней мере, в Firefox, со следующим волшебством:
После объявления DOM добавление объявления фильтра в строке с javascript.
// Does not works, with regular dynamic css styling:
shadow0.onchange = () => {
rect1.style.filter = "filter:drop-shadow(0 0 " + shadow0.value + "rem black);"
}
// Okay! Inline styling, appending.
shadow1.onchange = () => {
rect1.style += " ;filter:drop-shadow(0 0 " + shadow1.value + "rem black);"
rect2.style += " ;filter:drop-shadow(0 0 " + shadow1.value + "rem black);"
}
<h4>
Does not works!
<input id="shadow0" type="number" min="0" max="100" step="0.1">
| Okay!
<input id="shadow1" type="number" min="0" max="100" step="0.1">
<svg viewBox="0 0 120 70">
<rect id="rect1" x="10" y="10" width="100" height="50" fill="#c66" />
<!-- Inline style declaration does NOT works at svg level, no shadow at loading: -->
<rect id="rect2" x="40" y="30" width="10" height="10" fill="#aaa" style="filter:drop-shadow(0 0 20rem black)" />
</svg>
Ответ 8
Вы можете легко добавить эффект drop-shadow к svg-элементу, используя CSS-функцию drop-shadow() и значения цвета rgba. Используя значения цвета rgba, вы можете изменить непрозрачность вашей тени.
img.light-shadow{
filter: drop-shadow(0px 3px 3px rgba(0, 0, 0, 0.4));
}
img.dark-shadow{
filter: drop-shadow(0px 3px 3px rgba(0, 0, 0, 1));
}
<img class="light-shadow" src="https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.svg" />
<img class="dark-shadow" src="https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.svg" />