Как динамически раскрасить импортированный значок SVG в Svelte без фильтров CSS?

У меня возникли проблемы при попытке решить простую задачу: с помощью значка, импортированного в компонент Svelte с помощью импорта активов Vite, как я могу изменить цвет значка?

<script>
  // This would be the usual Vite way to import the asset
  import icon from "../assets/icon.svg";
  // Our dynamic color
  export let iconColor = "#c0ffee";
</script>

Прочитав этот вопрос, кажется, что доступно несколько вариантов:

  • CSS-фильтры, которые я не хочу использовать, так как они слишком требовательны к производительности, как при рендеринге, так и при вычислении значений для фильтра (т. е., учитывая шестнадцатеричный цвет, получение значений фильтра требует много усилий). Дж.С.).
  • Использование свойства маски CSS. Маска должна быть URL-адресом SVG, поэтому кажется, что она не может работать с импортом ресурсов.
  • Хороший и простой подход: поместить fill = "currentColor" в исходный код значка и стилизовать его с помощью свойства CSS color. Это не работает по несколько сложной причине:

Поскольку значок является импортированным и предназначен для использования с <img src = {icon}/>, а не непосредственно с <svg> элементом, содержимое необходимо будет встроить. Это можно сделать так:

<script>
  import icon from "../assets/icon.svg?raw";
</script>

<div> {@html icon} </div>

Полученная скомпилированная страница действительно представляет собой SVG, вложенный в элемент div. Но теперь нет возможности его стилизовать: добавление CSS-селектора svg {} будет считаться «неиспользуемым». У Svelte нет возможности узнать, что находится внутри импортированной нами необработанной HTML-строки, поэтому дерево отбрасывает этот селектор. Кроме того, из-за этого мы не могли применить к значку какой-либо другой стиль, поэтому такие базовые вещи, как установка размера значка, также невозможны.

Использование :global в стиле , как предложено в этом вопросе , также не помогает: поскольку для каждого значка требуется динамический цвет, каждый новый экземпляр этого компонента будет перекрашивать все значки на странице.

Попытка заставить Svelte не трясти дерево терпит неудачу: такие правила, как div > *, также удаляются, и даже добавление пустого <svg style = "display:none"> в div не работает — стиль применяется только к скрытому заполнителю, но не к встроенному SVG.

Возможно, я слишком много об этом думаю, и существует простое решение, которое соответствует критериям «импортировать SVG-ресурс» и «динамически менять его цвет и размер». Буду признателен за любую помощь.

Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в 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. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
0
0
85
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Когда вы добавляете fill = "currentColor" в svg и встраиваете его через `@html' и div-оболочку, установка цвета в div повлияет на svg.

<script>
    const svg = '<svg viewBox = "0 0 100 100" fill = "currentColor" xmlns = "http://www.w3.org/2000/svg"><circle cx = "50" cy = "50" r = "50"></circle></svg>'

    export let color = 'teal'
</script>

<div style:color = {color}>
    {@html svg}
</div>

Без добавления fill = "currentColor" альтернативным способом было бы использование div-обертки в сочетании с модификатором :global и переменной CSS.

<script>
    const svg = '<svg viewBox = "0 0 100 100" xmlns = "http://www.w3.org/2000/svg"><circle cx = "50" cy = "50" r = "50"></circle></svg>'

    export let color = 'teal'
</script>

<div style:--color = {color}>
    {@html svg}
</div>

<style>
    div :global(svg) {
        fill: var(--color);
    }
</style>

Спасибо, решение 1 хорошее, но не позволяет стилизовать что-либо еще в самом SVG (например, высоту/ширину), но решение 2 — это именно то, что я искал. Я не знал, что :global можно использовать только для одной части селектора. Делает код читаемым и понятным, в отличие от обходных путей с фильтрами.

goose_lake 15.06.2024 13:33

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