CSS backdrop-filter для элементов SVG

Я пытаюсь добавить фоновый фильтр к SVG <rect>, который находится поверх другого SVG <rect>.

Однако свойства CSS backdrop-filter: blur(10px) и -webkit-backdrop-filter: blur(10px), похоже, не влияют на элементы SVG. Когда я делаю то же самое для двух <div>, работает.

Как я могу добиться того же эффекта для двух <rect>?

body, html {
  margin: 0;
}

.outerrect {
  position: absolute;
  left: 0px;
  top: 120px;
}

.innerrect {
  position: absolute;
  
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}

.outerdiv {
  position: absolute;
  left: 0px;
  top: 120px;
  width: 200px;
  height: 100px;
  background-color: red;
}

.innerdiv {
  position: absolute;
  left: 140px;
  top: 20px;
  width: 120px;
  height: 60px;
  border: 1px solid;
  
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}
<svg>
  <rect class = "outerrect" fill = "red" x = "0" y = "0" width = "200" height = "100"></rect>
  <rect class = "innerrect" x = "140" y = "20" width = "120" height = "60"></rect>
</svg>
<div class = "outerdiv">
  <div class = "innerdiv"></div>
</div>

Со страницы MDN, на которую вы ссылаетесь: Applies to: all elements; In SVG, it applies to container elements excluding the <defs> element and all graphics elements

Morpheus 20.03.2018 11:49

Другими словами, невозможно достичь того, чего я хочу? Или мне нужно использовать группы и применять к ним?

SimonNick 20.03.2018 12:28

Может быть, неплохо поиграть с группами

Morpheus 20.03.2018 13:08
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
CSS: FlexBox
CSS: FlexBox
Ранее разработчики использовали макеты с помощью Position и Float. После появления flexbox сценарий полностью изменился.
2
3
3 201
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Учитывая, что модуль эффектов фильтра является в значительной степени экспериментальным и не так широко внедрен (новейшие Edge и Chrome за флагом), лучшее, что вы могли сделать, - это вернуться к фильтрам SVG 1.1. Следующий прием выглядит довольно безобидным, но все же у Firefox есть проблемы на границе содержимого фона:

<svg xmlns = "http://www.w3.org/2000/svg" xmlns:xlink = "http://www.w3.org/1999/xlink" width = "300" height = "200">
  <clipPath id = "clip">
    <rect id = "rect" x = "140" y = "20" width = "120" height = "100" />
  </clipPath>
  <filter id = "blur" width = "160%" height = "160%" x = "-30%" y = "-30%">
    <!-- insert a neutral background color to prevent the backdrop showing
         through blurred regions with alpa < 1 -->
    <feFlood flood-color = "#fff" result = "neutral"/>
    <feGaussianBlur in = "SourceGraphic" stdDeviation = "10" result = "blurred" />
    <feMerge>
      <feMergeNode in = "neutral" />
      <feMergeNode in = "blurred" />
    </feMerge>
  </filter>
  <!-- group everything you want to include in the backdrop -->
  <g id = "backdrop">
    <rect fill = "red" x = "0" y = "0" width = "200" height = "100" />
    <rect fill = "yellow" x = "120" y = "40" width = "40" height = "40" />
  </g>
  <!-- make sure the clip-path is applied after the filter -->
  <g style = "clip-path: url(#clip)">
    <use xlink:href = "#backdrop" style = "filter: url(#blur)" />
  </g>
  <use xlink:href = "#rect" style = "fill:none;stroke:black" />
</svg>

Пока вы остаетесь над областями достаточно далеко внутри фонового изображения и без учета альфа-значений, более короткая версия будет работать:

<svg xmlns = "http://www.w3.org/2000/svg" xmlns:xlink = "http://www.w3.org/1999/xlink" width = "400" height = "200">
  <clipPath id = "clip">
    <rect id = "rect" x = "140" y = "20" width = "120" height = "100" />
  </clipPath>
  <filter id = "blur">
    <feGaussianBlur in = "SourceGraphic" stdDeviation = "10" result = "blurred" />
  </filter>
  <image id = "backdrop" width = "400" height = "200" href = "https://lorempixel.com/400/200/" />
  <g style = "clip-path: url(#clip);">
    <use id = "overlay" xlink:href = "#backdrop" style = "filter: url(#blur);" />
  </g>
  <use xlink:href = "#rect" style = "fill:none;stroke:black" />
</svg>

Большое спасибо. Ваше решение работает хорошо. Однако это все еще похоже на обходной путь. Я надеюсь, что в будущем будут разработаны более эффективные решения этой проблемы.

SimonNick 21.03.2018 21:01

Например, я думаю, что до сих пор нет способа наложить несколько слоев этих размытых слоев друг на друга, как я хотел бы иметь для моей визуализации: pasteboard.co/HcYhYyX.png Но на данный момент я счастлив ...;)

SimonNick 21.03.2018 21:04

Другие вопросы по теме