What's the best way to update the fill color of an SVG dynamically?

Is it possible to change the color of an SVG image dynamically without using inline SVG tags? I want to create a code that allows users to specify the source for the SVG tag and a hexadecimal color value, enabling them to customize any SVG image with their preferred colors.

The idea is to have a component where users can input the SVG source and color, and the code will automatically adjust the fill colors of the SVG based on these parameters. Any ideas on how to achieve this would be greatly appreciated. Thank you!

Here is an example of how the user interaction might look:

import Frame from './Frame.svg';
...
<Icon src={Frame} color='purple' />

This is my suggested UI component code:

import React from 'react';
import styled from 'styled-components';

const Icon = ({ src, color }) => {
  const StyledSVGIcon = styled(src)`
    width: 67px;
    height: 72px; 
    fill: ${color};
  `;
  return <StyledSVGIcon />
};

Sample content of Frame.svg file:

<svg width="73" height="71" viewBox="0 0 73 71" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path d="M47.0139 71H40.8997C39.8807 71 39.541 70.332 39.541 69.664V63.6518C39.541 63.3178 39.8807 62.6498 39.8807 62.3157L64.3376 38.267C65.0169 37.599 65.6963 37.599 66.3756 38.267L72.4898 44.2792C73.1692 44.9472 73.1692 45.6152 72.4898 46.2833L48.033 70.332C47.6933 70.666 47.0139 71 47.0139 71ZM42.2584 67.9939H46.3346L69.0931 45.6152L65.0169 41.6071L42.2584 63.9858V67.9939Z" fill="#4B286D"/>
...
</g>
<defs>
<clipPath id="clip0">
<rect width="73" height="71" fill="white"/>
</clipPath>
</defs>
</svg>

Answer №1

Here is a demonstration of how to apply a color to an SVG element:

import React, { useState } from "react";
import styled from "styled-components";

export default function App() {
  const [selectedColor, setSelectedColor] = useState("blue");

  return (
    <div>
      <h1>Greetings from Stack Overflow!</h1>
      <StyledSVG 
        color={selectedColor} 
        src={'https://example.com/svg_image'}
        />
    </div>
  );
}

const StyledSVG = styled.svg`
  width: 500px;
  height: 500px;
  background-color: ${(props) => props.color};
  background-image: url(${(props) => props.src});
`;

The default color is blue, but you can customize it with RGB or hex values using sliders for the styled <svg />.

CodeSandbox: https://codesandbox.io/s/stack-63910588-pass-color-to-svg-birthday-card-ievg7?file=/src/App.js


The original poster mentioned they wanted to modify the children's color. You can achieve this by:

import React, { useState } from "react";
import styled from "styled-components";

export default function App() {
  const [chosenColor, setChosenColor] = useState("purple");

  return (
    <Container>
      <StyledSVG color={chosenColor} width="73" height="71" viewBox="0 0 73 71">
        <Frame />
      </StyledSVG>
    </Container>
  );
}

const Frame = () => {

  // This logic could be moved to a separate file.

  return (
  <>
  <g clip-path="url(#clip0)">
  <path d="M47.0139 71H40.8997C39.8807 71 39.541 70.332 39.541 69.664V63.6518C39.541 63.3178 39.8807 62.6498 39.8807 62.3157L64.3376 38.267C65.0169 37.599 65.6963 37.599 66.3756 38.267L72.4898 44.2792C73.1692 44.9472 73.1692 45.6152 72.4898 46.2833L48.033 70.332C47.6933 70.666 47.0139 71 47.0139 71ZM42.2584 67.9939H46.334…
  </g>
  <defs>
  <clipPath id="clip0">
  <rect width="73" height="71" fill="white"/>
  </clipPath>
  </defs>
  </>
  );
  
};

const Container = styled.div`
  height: 500px;
  width: 100%;

  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;

`;

const StyledSVG = styled.svg`
  & path {
    fill: ${props => props.color};
  }
`;

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error encountered: Unable to locate module 'psl'

I'm encountering an issue when trying to execute a pre-existing project. The error message I keep receiving can be viewed in the following error logs image Whenever I attempt to run "npm i", this error arises and I would greatly appreciate it if some ...

What are the best practices for preloading images, JavaScript, and CSS files?

Back in the late 90's, I was really passionate about creating websites from scratch. However, as I dove back into web development recently, I realized how much the landscape has changed since then. As more of a designer than a developer, I opted to us ...

How to sort WordPress RSS feed in alphabetical order using JavaScript

Currently using WP, but feeling limited due to restricted access to PHP and plugins. Searching for a JAVASCRIPT code solution to fetch RSS feed from a URL and organize the feed titles in ALPHABETICAL order. The JS code can be inserted into the footer and ...

What is the best method for transmitting all parameters via a URL?

$(document).ready(function () { $("#submitButton").click(function () { var name = $("#name").val(); var age = $("#age").val(); var gender = $('input:radio[name=gender]:checked').val(); v ...

Verify if the screen is in full view by monitoring document.fullscreenElement within Vue3

Is there a way to determine when the document is in fullscreen mode? I attempted to monitor document.fullscreen with the following code, but it was not successful: watch(document.fullscreenElement, (newValue) => { fullScreenActivated.value = newValue ...

Is it possible to utilize a JavaScript variable in this particular scenario and if so, what is the

let myVariable = <?php echo json_encode($a[i want to insert the JS variable here]); ?>; Your prompt response would be highly valued. Many thanks in advance. ...

Using Vuetify to display text fields in a single row

Check out this Vue component template (View it on CODEPEN): <div class="some-class"> <v-form > <v-container @click="someMethod()"> <v-row> <v-col cols="3" sm="3" v-for="p in placeholders" ...

Transforming a jQuery menu into an active selection with Vue JS

I am looking to transition away from using jQuery and instead utilize Vue for the front end of a menu. Specifically, I need to add an active class and a 'menu-open' state to the appropriate nested list items, similar to what is achieved in the pr ...

Enhance your webpage design with stylish CSS formatting using Bulma cards

My HTML output is as follows: https://i.stack.imgur.com/aBdEF.jpg It seems that the footer is not matching up with the cards... The CSS component I am using looks like this: .card-equal-height { display: flex; flex-direction: column; height: 100%; ...

Javascript function to deselect all items

One of my functions is designed to reset all checkbox values and then trigger an AJAX request. However, there are instances when the function initiates before the checkboxes have been unchecked. function clear() { $("#a").prop("checked", false); $("#b ...

Next.js App encounters a missing API route (The requested page is not found)

I have been working on a Next.js app and I created an api route for sending emails. Everything is functioning properly in my development environment. However, after deploying to production, I encountered a 404 error with the message "The page could not b ...

Effortless navigation through the document in both directions with seamless scrolling

To achieve a specific scrolling behavior on my webpage, I implemented the following function. Here is the code snippet: $(window).scroll(function(){ if ($(this).scrollTop() > 100) { $("html, body").animate({scrollTop: 700}, 500); re ...

Customizing the appearance of an input button in Internet Explorer 8

I've been trying to style my file input section using a method similar to the one outlined in this article: . However, I'm encountering issues specifically with compatibility in IE8; all I can see is the corner of an oversized button. Here' ...

The Next Js API is experiencing difficulties resolving

I'm just starting out with back-end development so I could use some assistance with my current project. I am working on a next.js application that applies a black and white filter to an image when it is uploaded. In the index.js file, once a file is s ...

Jquery: Pressing Enter will cause the input field to lose

Take a look at this fiddle I created: http://jsfiddle.net/7wp9rs2s/. This is the progress I have made on my project so far. In the fiddle above, you can double click on one of the 4 items and a textbox will appear for editing. Instead of clicking out of t ...

What is the proper way to encode image URLs for use in CSS?

For the div element in my code, I want to allow users to input a URL that will be applied as a CSS background image, like this: background-image: url("/* user specified URL here*/") I'm concerned about security. How can I properly escape the URL to ...

JavaScript class with callback function commonly used

I am looking to create a JavaScript class that can register multiple functions to run with a common callback. Each registered function should run asynchronously, and once they have all completed, the specified callback function should be executed. In addi ...

Issue encountered: When attempting to submit a form, an error is thrown stating "TypeError:

I encountered an issue while attempting to create a select form that toggles a boolean value in an object from true to false when a specific option is selected. Although my solution appeared promising, I kept running into errors. import { useState } from & ...

deliver a promise with a function's value

I have created a function to convert a file to base64 for displaying the file. ConvertFileToAddress(event): string { let localAddress: any; const reader = new FileReader(); reader.readAsDataURL(event.target['files'][0]); reader ...

What is the best way to transfer my saved bookmarks and import them into a database?

Over the years, I've amassed a large collection of bookmarks that I now want to organize in a searchable table with additional details like categories, types, and descriptions. My initial approach involved manually inputting them into a JSON file and ...