SVG плюс Angular минус Firefox

SVG удивительная технология, не в последнюю очередь благодаря своим оригинальным подводным камням. Если вы начали работать с SVG — скучно точно не будет.

Парочка свежих проблем была обнаружена при взаимодействии SVG с Angular, причем они возникали только в Firefox. Я решила описать проблемы и их решения здесь: себе на память, другим на пользу.

Проблема № 1.

Дано: SVG-иконки, подключаемые через use в нужные места страницы. Конструкция работает как часы во всех современных браузерах, но тут приходит Angular и меняет base. Во всех браузерах всё работает, кроме Firefox: в нем иконки исчезают, но только в случае, если ссылка в base не совпадает с адресом текущей страницы.

Про это даже есть баг от 2011 года, но проблема до сих пор существует.

Демо (смотреть в Firefox):

Ссылка на демо

Оба кружка находятся внутри одного SVG, по нажатию на кнопку он полностью копируется. Голубой кружок слева — просто фигура, чтобы видеть, что в SVG вообще что-то есть. Красный кружок справа — символ, вставленный через use. Символ объявлен выше внутри того же SVG.

Решение: если добавить тегу SVG атрибут xml:base и в нем задать URL текущей страницы, иконки начинают работать вне зависимости от ссылки в base.

Проверьте в Firefox:

Ссылка на демо

Проблема № 2.

Иконки, отрисовываемые внутри ng-repeat, могут не отображаться на странице. Код корректный, он есть на странице, но в use ничего нет, хотя тот же код, вынесенный из ng-repeat, прекрасно работает.

Решение:

  1. Взять содержимое атрибута xlink:href элемента use.
  2. Очистить xlink:href.
  3. Вставить в xlink:href старое значение.

После этого иконки начинают отображаться.

Способ странный, но он работает.

По правде сказать, оба решения выглядят не очень изящно, и всем было бы гораздо проще, если бы SVG в Firefox просто вел себя как в других браузерах, но вот нет.

Если вы знаете более красивые способы решить эти проблемы, расскажите мне о них, пожалуйста.

Если вы нашли ошибку или неточность, вы можете отредактировать статью с помощью prose.io, а также можно написать мне в комментариях или в Twitter.
Система комментирования от Disqus