CSS selector rules are being ignored by the hover effect on SVG stop-color

Attempting to create a hover effect on a link with an SVG as a child element. Desire to alter the stop-color of the svg when hovering over the link.

Encountering issue where all the SVG icons change stop color when hovering specifically over the first .link element. However, if hovering over the second or third .link element, the stop color remains unchanged. Seeking a resolution without needing extra classes or JavaScript in the SVG component.

Issue: https://i.sstatic.net/jAuwe.png

Hovering over the first one: https://i.sstatic.net/bI55U.png

Hovering over the second one: https://i.sstatic.net/B2wc0.png

View CodePen example

The CSS class is defined using scss and appears as follows:

.link {
  & defs stop:first-child {
    stop-color: #393896;
  }
  & defs stop:last-child {
    stop-color: #181735;
  }
  &:hover defs stop:first-child {
    stop-color: #ffbbcc;
  }
  &:hover defs stop:last-child {
    stop-color: #0000ff;
  }
  &:hover {
    background-color: red; // test to see if the css selector is working
  }
}

SVG code:

<svg width="1em" height="1em" viewBox="0 0 84 115" fill="none" xmlns="http://www.w3.org/2000/svg">
  <path d="M41.977 0.397949C19.37 0.397949 0.869995 18.323 0.869995 40.242C0.869995 70.122 41.977 114.232 41.977 114.232C41.977 114.232 83.084 70.121 83.084 40.242C83.084 18.323 64.585 0.397949 41.977 0.397949ZM41.977 54.4689C40.0722 54.5265 38.1752 54.2011 36.3984 53.5119C34.6217 52.8227 33.0015 51.7838 31.6337 50.4568C30.266 49.1297 29.1786 47.5416 28.436 45.7865C27.6935 44.0315 27.3108 42.1452 27.3108 40.2394C27.3108 38.3337 27.6935 36.4474 28.436 34.6924C29.1786 32.9373 30.266 31.3492 31.6337 30.0221C33.0015 28.6951 34.6217 27.6562 36.3984 26.967C38.1752 26.2778 40.0722 25.9524 41.977 26.0099C43.8818 25.9524 45.7788 26.2778 47.5555 26.967C49.3323 27.6562 50.9525 28.6951 52.3203 30.0221C53.688 31.3492 54.7754 32.9373 55.518 34.6924C56.2605 36.4474 56.6431 38.3337 56.6431 40.2394C56.6431 42.1452 56.2605 44.0315 55.518 45.7865C54.7754 47.5416 53.688 49.1297 52.3203 50.4568C50.9525 51.7838 49.3323 52.8227 47.5555 53.5119C45.7788 54.2011 43.8818 54.5265 41.977 54.4689" fill="url(#paint0_linear_1_4257)" />
  <defs>
    <linearGradient id="paint0_linear_1_4257" x1="41.977" y1="0.397949" x2="41.977" y2="114.232" gradientUnits="userSpaceOnUse">
      <stop stopcolor="currentColor" />
      <stop offset="1" stopcolor="currentColor" />
    </linearGradient>
  </defs>
</svg>

The HTML structure looks like this:

<div id="main">
  <a class="link">
    <svg ...  />
  </a>
  <a class="link">
    <svg ... />
  </a>
</div>

Hoping for a solution that is also compatible with scss module in a react project. Appreciate any help!

Answer №1

Upon reviewing your CodePen, it seems that you duplicated the same SVG element for the second one. As a result, both elements possess identical id attribute values for the linearGradient element: paint0_linear_1_4257. This similarity can lead to unexpected behavior in SVG.

It is likely that the fill directive of the path (which utilizes the id as an argument) is triggering all matching ids from the first hover event with some abnormality due to multiple matching ids on a single page not causing the issue for any of those replicated links thereafter.

The simplest solution would be to ensure that all ids on a page are distinct. I adjusted the name of the first id to paint0_linear_1_4257_1 and the second to paint0_linear_1_4257_2, while also updating the corresponding values in the fill directives. This adjustment seems to have successfully resolved the problem on my end.

Answer №2

To customize the colors, you have the option to utilize CSS custom properties. It may be a bit complex due to avoiding ID reuse (the initial inline SVG element has repeated linearGradient definitions). To address this, I recommend using the <symbol> element by embedding the linearGradient within it. By doing so, the symbol becomes reusable, and color changes can be achieved using either currentColor or a CSS variable.

.link {
  color: red;
}

.link svg {
  width: 4em;
  height: 4em;
  --stop01: currentColor;
  --stop02: currentColor;
}

.link:hover svg {
  --stop01: #ffbbcc;
  --stop02: #0000ff;
}
<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg">
  <symbol id="marker" viewBox="0 0 84 115">
    <path d="M41.977 0.397949C19.37 0.397949 0.869995 18.323 0.869995 40.242C0.869995 70.122 41.977 114.232 41.977 114.232C41.977 114.232 83.084 70.121 83.084 40.242C83.084 18.323 64.585 0.397949 41.977 0.397949ZM41.977 54.4689C40.0722 54.5265 38.1752 54.2011 36.3984 53.5119C34.6217 52.8227 33.0015 51.7838 31.6337 50.4568C30.266 49.1297 29.1786 47.5416 28.436 45.7865C27.6935 44.0315 27.3108 42.1452 27.3108 40.2394C27.3108 38.3337 27.6935 36.4474 28.436 34.6924C29.1786 32.9373 30.266 31.3492 31.6337 30.0221C33.0015 28.6951 34.6217 27.6562 36.3984 26.967C38.1752 26.2778 40.0722 25.9524 41.977 26.0099C43.8818 25.9524 45.7788 26.2778 47.5555 26.967C49.3323 27.6562 50.9525 28.6951 52.3203 30.0221C53.688 31.3492 54.7754 32.9373 55.518 34.6924C56.2605 36.4474 56.6431 38.3337 56.6431 40.2394C56.6431 42.1452 56.2605 44.0315 55.518 45.7865C54.7754 47.5416 53.688 49.1297 52.3203 50.4568C50.9525 51.7838 49.3323 52.8227 47.5555 53.5119C45.7788 54.2011 43.8818 54.5265 41.977 54.4689" fill="url(#paint0)" />
    <defs>
      <linearGradient id="paint0" x1="41.977" y1="0.397949" x2="41.977" y2="114.232" gradientUnits="userSpaceOnUse">
        <stop style="stop-color: var(--stop01)" />
        <stop offset="1" style="stop-color: var(--stop02)" />
      </linearGradient>
    </defs>
  </symbol>
</svg>

<div id="main">
  <a class="link">
    <svg xmlns="http://www.w3.org/2000/svg">
      <use href="#marker"/>
    </svg>
  </a>
  <a class="link">
    <svg xmlns="http://www.w3.org/2000/svg">
      <use href="#marker"/>
    </svg>
  </a>
</div>

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

Jest in combination with Next/Dynamic is causing an error that is not supported

While working on testing for my component, I encountered an error involving the use of: ... const Rating = dynamic(import('components/Rating')); ... In addition, I am utilizing jest-next-dynamic: beforeAll(async () => { await preloadAll() ...

Chrome's CSS image transitions are causing interference with surrounding elements

I recently encountered an issue with my menu, where images used as backgrounds for buttons would animate on hover. Surprisingly, when I hovered over an image and it animated (by enlarging and rotating), other elements on the page would shift slightly witho ...

Dropdown submenu display issue with multiple selections

I've been working on a multi-level dropdown menu. It seems like there's a dropdown menu inside another dropdown menu. However, when I click on the inner dropdown menu, it doesn't open to the right as expected; instead, it opens below the men ...

Achieve the same height for an HTML table as its parent div by adjusting the table's height when the div's height is not explicitly defined

I am facing a challenge with an html table placed inside a div. The height of the div is determined by other elements within it. Is there a way to make the table's height match that of its parent div? (setting the table height to 100% is not effecti ...

React's Axios failing to properly handle HTTP responses outside the 200 range from a GoLang API

I have encountered an issue while trying to consume a GoLang API with Axios in my React application. It seems that Axios is only capturing HTTP 200 responses and not any other error status codes. Here is the Axios API call I am using on the React side: axi ...

When attempting to insert a date into a MySQL database using React.js, I encountered an issue with the date format

Hey everyone, I have set the input date to dd/mm/yyyy format using moment(donors.donateDate).format('DD-MM-YYYY'). However, when I click the submit button, an error is displayed in the console stating: The specified value "23-03-2022" ...

The Auth0 authentication status is perpetually set to false

I have been using React and following a tutorial on setting up Auth0 for user authentication. I have successfully added a login and logout button to my web app and connected it to the Auth0 universal login page. Despite signing up with both a Gmail and com ...

Encountering an issue on Windows 7 when running the command "npm run deploy" in an attempt to deploy my code to pages.github.com

An error occurred: failed to execute prompt script (exit code 1) fatal error: could not read Username for 'https://github.com': No such device or address ...

Responsive Material-UI horizontal navigation bar

Hey there! I'm working on developing a UI using Material-UI, and I want to make it so that the menu can be collapsed into a slide-in style menu when accessed on a mobile device. Currently, I'm using tabs which allow for sliding left and right, b ...

Display the JSX template in reverse order when the "add more" button is clicked in reactjs

I'm currently working on a feature where I need to dynamically add a child component when a click event occurs. Although the desired outcome is achieved, the new template is rendering below the previous one. const [branchArray, setBranchArray] = use ...

Looking for advice on using media queries to resize my background image - any tips?

I'm struggling to resize my background image using media queries. Can anyone offer suggestions or solutions? I've tried applying the media query for my background image like I do with other elements, and it's not working properly. The issue ...

Create a layered panel underneath a button that covers a separate element

I am working on a layout that consists of an editor and multiple buttons positioned above it on the right side. My goal is to add a panel just below "Button2" that will overlay the editor. This panel should expand and collapse when "Button2" is clicked, wh ...

Terminate a promise upon unmounting a component in ReactJS

In my code, there is a component called "Item" that creates and triggers a promise when it gets mounted. class Item extends React.Component{ constructor(props){ super(props) this.onClick = this.onClick.bind(this) this.prom = n ...

Guide on Organizing Information in Next.js

I have an online store and I am looking to organize my data by categories. Initially, I tried using APIs for this purpose but it ended up putting a strain on my server. So now, I am attempting to use Redux to store the data and filter it from there. Howeve ...

Encountering a problem when transitioning Bootstrap 3 code to version 5

After finding this template on github, I noticed it was a bit outdated with the use of Bootstrap 3. I decided to update it to Bootstrap 5 and replaced the Bootstrap 3 CDN accordingly. However, upon doing so, I encountered some issues. Can anyone help me ...

Executing MongoDB on a Global Scale Using Google App Engine

As a newcomer to GCP, I appreciate your patience if my question is basic. I am working on deploying a MERN application to Google App Engine. Currently, I have successfully uploaded my react files and everything is functioning smoothly. However, I encounter ...

Error in Compass Compilation when encountering Unicode Characters

After compiling with Compass, I noticed that if I don't include @charset "UTF-8"; in my root scss file, the output looks like this: @charset "IBM437"; Even though my CSS output still displays the correct Unicode characters, such as: content: "ĐĂN ...

Tips for organizing your JSON Structure within ReactJs

In the given example, I have a JSON structure with information about different airlines. The Airline Name is dynamic and we need to separate the JSON into an expected array format. const arr = [ { Airline: "Goair", Departure: "01:50" ...

What are the steps to passing props to a dynamically imported React component?

I'm currently working on a project using Next.js, React, and TypeScript. One of the challenges I faced was dynamically importing a React component into my page while setting ssr to false, as the component contains references to window. These window r ...

React JS - CORS error persists despite implementing cors settings

Currently utilizing Express and ReactJS Express Code: const Express = require('express'); const PORT = 5000; const cors = require('cors'); const server = Express(); server.use(cors()); // CORS added here server.get('/users&ap ...