2

I'm dynamically changing a cursor to a local svg on hover with

$(element).on('mouseover', function () {
    $(this).css('cursor', 'url(svgs/pointer.svg) 9 30 auto');
};

Thats working fine but I'd like to select that svg to manipulate its fill color.

Is there any way to do this so I don't have to make a bunch of different svgs with different fills?

Thanks

iwoodruff
  • 157
  • 1
  • 3
  • 10
  • No, when used as a cursor an SVG you can't interact with it. – Robert Longson Nov 30 '14 at 22:21
  • But you could have some server-side resource build you a colored cursor on demand. Don't ask me how but the jQuery would be something like `$(this).css('cursor', 'url(make_pointer.php?color=#FC6) 9 30 auto')`. Mmm, there's a MIME issue to overcome but I'm sure it's possible. – Roamer-1888 Nov 30 '14 at 22:30
  • If you want it to be done on the client-side then it should be possible to generate a new data uri for each fill you want. – Erik Dahlström Dec 01 '14 at 09:28

2 Answers2

4

You can use inline SVG. Just open your SVG file with your text editor. Copy the XML and use it instead. Just change the fill value and reassign it to the element.

cursor: url('data:image/svg+xml;utf8,<svg fill="%23FF0000" height="48" viewBox="0 0 24 24" width="48" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"/></svg>') 24 24, auto;

When using this technique you should escape special chars in the data. Some people prefer to Base64 their images but for SVG you don't need it. In the example above I only had to replace # in the fill value with %23.

button {
  cursor: url('data:image/svg+xml;utf8,<svg fill="%23FF0000" height="48" viewBox="0 0 24 24" width="48" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"/></svg>') 24 24, auto;
}

button { padding: 30px; }
<button>Hover<br>Here</button>
Gangula
  • 5,193
  • 4
  • 30
  • 59
Dara
  • 68
  • 6
  • Thanks it works great. I even does not replace # with %23 – Vishal Dec 11 '16 at 20:14
  • This is not working in Chrome browser, but its working in Firefox. Its mentioned here: https://stackoverflow.com/q/46706847/6908282 – Gangula Jun 21 '23 at 05:56
0

In addition to the answer provided by @Dara, I would like to add that, depending on the size of the SVG, the curosor may or may not work in different browsers

button {
  padding: 30px;
}

#btnSmall {
  cursor: url('data:image/svg+xml;utf8,<svg fill="%23FF0000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"/></svg>') 24 24, auto;
  background: mediumseagreen;
}

#btnLarge {
  cursor: url('data:image/svg+xml;utf8,<svg fill="%23FF0000" height="40" viewBox="0 0 24 24" width="40" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"/></svg>') 24 24, auto;
  background: orange;
}

#flex {
  display: flex;
  gap: 20px;
  text-align: center
}

#flex>div {
  padding: 5px;
  border: 1px solid darkgray;
  border-radius: 5px;
}
<div id="flex">
  <div>
    <p>Small SVG icons work</p>
    <button id="btnSmall">Hover<br>Here</button>
  </div>

  <div>
    <p>Large SVG icons don't work in chrome</p>
    <button id="btnLarge">Hover<br>Here</button>
  </div>
</div>

References:

Gangula
  • 5,193
  • 4
  • 30
  • 59
  • Note that you can add clampoints x, y, to center the icon, like this `cursor: url("") 16 16, pointer;` - [Optional x- and y-coordinates indicating the cursor hotspot](https://developer.mozilla.org/en-US/docs/Web/CSS/cursor#values:~:text=Optional%20x%2D%20and%20y%2Dcoordinates%20indicating%20the%20cursor%20hotspot) – Gangula Jun 21 '23 at 07:20