Я тестирую метод стекирования SVG, чтобы включить несколько значков, сложенных в один файл, требуя только один HTTP-запрос из браузера. Техника описана довольно подробно здесь.
В основном идея состоит в том, что вы помещаете несколько элементов SVG в один SVG файл и используете стили CSS, чтобы скрыть все значки, за исключением иконки, которую вы сейчас хотите отобразить. Вы выбираете значок, который вы хотите отобразить с помощью селектора CSS :target
.
Техника работает для меня, за исключением того, что множество ярлыков вызывает странные искажения в отображаемом значке, даже если все остальные значки скрыты.
В примере, с которым я работаю, я упростил это для укладки только двух значков: значка флага США и значка флага Великобритании.
(упрощенный) SVG файл:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg153" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="480" width="640" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
<svg:style
xmlns:svg="http://www.w3.org/2000/svg" type="text/css">
.i { display: none; }
.i:target { display: block; }
</svg:style>
<svg:svg id="uk" xmlns:svg="http://www.w3.org/2000/svg" class = "i" height="480" width="640" version="1.1">
<!-- SVG elements to draw UK flag -->
</svg:svg>
<svg:svg id="us" xmlns:svg="http://www.w3.org/2000/svg" class = "i" height="480" width="640" version="1.1">
<!-- SVG elements to draw US flag -->
</svg:svg>
</svg>
Обратите внимание, что CSS встроен в файл SVG в элементе <svg::style>
. CSS просто:
.i { display: none; }
.i:target { display: block; }
Таким образом, любой элемент svg::svg
с class="i"
автоматически невидим, если мы специально не нацелим его на URL-адрес SVG. Таким образом, чтобы отобразить значок флага США, я бы использовал следующий фрагмент HTML:
<img
src="flags.svg#us"
width="80"
height="60"
alt="SVG Stacked Image"
/>
И, конечно, чтобы отобразить флаг Великобритании, я бы изменил его на src="flags.svg#uk"
В любом случае, все это прекрасно работает... за исключением странного искажения изображения, которое происходит как в Firefox, так и в Chrome, когда я складываю изображения.
Вот скриншот флага США, когда я удаляю (скрытый) флаг Великобритании из файла SVG:
Как вы можете видеть, это выглядит нормально.
Но когда я складываю его перед британским флагом, он выглядит так:
Как вы можете видеть, изображение становится странно искаженным - почти похоже на то, что происходит с низкокачественным JPEG, когда вы получаете много "артефактов" в сжатом изображении.
Так почему именно это происходит? Остальные изображения, сложенные значком флага США, невидимы, поэтому почему они должны воздействовать на видимый значок вообще?
Я много искал ответы на вопросы, и, несмотря на то, что есть много проблем и "gotchas" с использованием метода стекирования SVG, все они связаны с кросс-браузерной совместимостью. Тем не менее, эта технология отлично работает в большинстве новых браузеров вплоть до IE9. Кроме того, искажение происходит как в Firefox, так и в Chrome, поэтому это вряд ли будет проблемой с несколькими браузерами, но скорее я ошибаюсь.
Итак, что вызывает это странное искажение, когда я применяю метод стекирования SVG?