Issue with SVG marker not functioning properly when hovered over

I am having an issue with buttons containing SVG elements, here is an example code snippet:

<button>
 Checkout
 <ArrowSvg />
</button>

The ArrowSvg component looks like this (with the line having a class of "svg-line"):

<svg fill="none" stroke="#000">
  <defs>
    <marker id="m" overflow="visible">
      <path d="M-4,-4L0,0 -4,4" />
    </marker>
  </defs>
  <line x1="0" y1="50%" x2="100%" y2="50%" marker-end="url(#m)" class="svg-line" />
</svg>


When a button is hovered over, I change the stroke color of the arrow:

btn:hover > .svg-line {
  stroke: blue;
}

While this functionality works as expected when only one button is present, issues arise when multiple buttons are displayed. Hovering over one button causes all other button arrows to also change color. This seems to affect the arrow head part of all buttons.
I am unable to use paths instead of lines due to the need for adjusting the arrow width. What might I be missing here? Why is this hover effect spreading to other buttons?

Answer №1

Utilize a native JS Web Component, which is compatible with all modern browsers, to generate the <svg>

  • as each SVG necessitates a distinct marker ID

  • please note: an individual SVG is produced for every occurrence, rendering a marker unnecessary; utilize the path on its own

customElements.define("svg-button",class extends HTMLElement{
  connectedCallback(){
    let id = "id" + (Math.floor(Math.random() * 1e10));
    let stroke = this.getAttribute("stroke") || "#000";
    this.innerHTML = `
          <button> 
           Checkout
            <svg fill="none" stroke="${stroke}" viewBox="0 0 10 10">
              <defs>
                <marker id="${id}" overflow="visible">
                  <path d="M-4,-4L0,0 -4,4"/>
                </marker>
              </defs>
              <line x1="0" y1="5" x2="9" y2="5" marker-end="url(#${id})"/>
            </svg>
          </button>`
    }
});
<style>
  button:hover svg {
    stroke:gold;
  }
</style>

<svg-button></svg-button>
<svg-button stroke="red"></svg-button>
<svg-button stroke="green"></svg-button>
<svg-button stroke="blue"></svg-button>

Answer №2

It seems like the code you are working on resembles .JSX syntax, but there is a missing react tag in the question. I will assume it for this response, although other frameworks utilizing the same format should also perform similarly.

To create a unique id for the <marker> element, simply define the <ArrowSvg> as a function and enclose it in another factory function to generate a closure over an incrementing number:

const ArrowSvg = (() => {
  let id = 0;
  return function (props) {
    return (
      const ref = 'arrowMarker' + ++id;
      <svg fill="none" stroke="#000">
        <defs>
          <marker id=(ref) overflow="visible">
            <path d="M-4,-4L0,0 -4,4" />
          </marker>
        </defs>
        <line x1="0" y1="50%" x2="100%" y2="50%"
              marker-end=(`url(#${ref})`) class="svg-line" />
      </svg>
    );
  }
})();

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

Material UI: Popover malfunctions when utilizing the onMouseLeave property

I redid the basic popover example from this website, but this time using mouse hover properties: https://codesandbox.io/s/eager-dewdney-yt3v-yt3vb <Button variant="contained" onMouseEnter={e => setAnchorEl(e.currentTarget)} // onMou ...

Customize the progress bar color in Bootstrap by setting a unique color to it

Is it possible to apply a custom color to the progress bar in Bootstrap that is not one of the standard options like success, info, warning or danger? I attempted adding the following code snippet to my bootstrap-theme.css file: .progress-bar-custom { b ...

Adjusting the size of text in a React app causes it to appear beneath the navigation

I recently created a React app for fun. The app includes a top navigation bar using react-bootstrap and a side navigation bar that I put together myself. Both components function properly, and the navbar is responsive as it switches to a hamburger menu whe ...

Learning to extract information from elements within components in a flexbox using Angular

Is there a way to access the element width of child components within a parent component that utilizes flex box? I am hoping to determine if the list is overflowed so I can adjust the visibility of elements accordingly. If an overflow occurs, I would like ...

Tips for concealing tick labels in d3 using TypeScript

When trying to hide tick labels by passing an empty string to the .tickFormat("") method, I encountered an issue with Typescript. The error message received was as follows: TS2769: No overload matches this call. Overload 1 of 3, '(format: null): Axi ...

react-intersection-observer is specifically designed to function with the final elements

I am currently working on implementing the Lazy Loading feature using react-intersection-observer. The main objective is to load images in the boxes only when they appear within the viewport. At the moment, as I scroll down to the last elements, all the i ...

Duplicating a concealed div and transferring it to a new div

I'm encountering an issue while trying to copy one div to another. The div I'm attempting to copy has a hidden parent div. The problem is that the destination div does not appear after copying, even though I changed its style display to block. ...

How to incorporate Django syntax into CSS styling

Imagine a scenario where a Django site is equipped with numerous stylesheets. CSS and JS files are located in the static/ directory within an app's folder or in the global site directory. Various color themes are employed across different pages, neces ...

Is there a way to produce random colors using this SCSS function?

The current function is returning an output in the color #ff0063, but my goal is to create a variety of colorful pixel dots on the screen. Could someone provide an explanation of what this code is doing? @function multiple-box-shadow ($n) { $value: &apos ...

CSS/Jade/HTML: struggling to get boxes to align properly on the same line

I'm currently working with a Jade template that looks like this: extends layout block content h2 Characters and Portraits div(id="portraitsBox") - var portraits = ["Clown-Fox", "Dragon-Bear", "Fish-Bear", "Deer-Wolf", "Salamander-Ant", "Sid ...

What is the proper way to utilize the 'shallow: true' parameter when using 'router.replace' in the latest version of Next.js?

Is there a workaround for using shallow: true with router.replace? I am currently working on Next 13 and have not been able to find any solution that replicates the behavior of shallow. I'm looking for a way to achieve the same result as using shallo ...

IE11 Experiencing Overflow Issue with List Item Pseudo Element Numbers

Having a simple unordered list of links and using pseudo elements to generate numbers for the list, I encountered an issue with centering the number vertically within its circle background in Internet Explorer 11. Here is the HTML code: <ul> < ...

conceal menu upon click (gradually disappear)

This is a basic HTML/CSS menu. Currently, it is functioning properly for page redirection (href). However, I would like it to hide after being clicked on. I plan to call a function that will initiate an AJAX request upon clicking. Here is the code on JS ...

Collection of categories within the drop-down menu

I'm currently utilizing Twitter Bootstrap and would like to create a collection of concealed fields within a dropdown menu: <li class="dropdown"> <a class="dropdown-toggle" data-toggle="dropdown" href="#"> Export <b class="ca ...

React - duplicating the identical object

Recently, I embarked on a React journey and enrolled in a course to expand my knowledge. As I delve into the exercises, something caught my attention - the instructor repeatedly cloned a specific object. Curiosity piqued, I decided to investigate further. ...

What is the best way to retrieve a single value in a React JS application?

api image Trying to store only the ChannelName value using a method, but facing an issue where every 4 values are being stored instead. I need to store only one value at a time. Index for (var x in setdata) { index.push(x); } Index = setdata[inde ...

Continuous Div Carousel with Looping in jQuery

I have developed a basic carousel to cycle through a series of divs, but I am facing some issues. I want the carousel to loop continuously so that after reaching "slide 07," it goes back to "slide 01." Unlike using a carousel plugin, I prefer having an ove ...

The autoComplete feature in my ReactJs form is not functioning properly

I have a form in React where I would like to enable auto complete so that when users input the same value again, it will be suggested as an auto complete option. Below is the code snippet: <form className={classes.container} noValidate> <Grid c ...

The MUI TextField doesn't register value changes when using the "ctrl + a" and "backspace/delete" keys

Need help with a coding problem? Check out this link: https://codesandbox.io/s/bold-hooks-ddce6c?file=/src/App.js Having trouble detecting changes in a textfield when using backspace or delete shortcuts? The issue arises when selecting all with ctrl + a ...

The localhost server in my Next.js project is currently not running despite executing the 'npm run dev' command. When trying to access the site, it displays an error message saying "This site can't be

I attempted to install Next.js on my computer and followed the documentation provided to set up a Next.js project. You can find the documentation here. The steps I took were: Ran 'npx create-next-app@latest' Was prompted for the name of my proj ...