The problem of SVG rendering order requires a solution that does not rely on javascript

I am new to experimenting with inline svg, and I wanted to share my code:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="350" height="350">
  <defs>
    <style>
      .ring {
        transform-origin: 175px 175px;
      }

      .ring.a {
        fill: #f2ca30;
      }
      .ring.b {
        fill: #31bc06;
      }
      .ring.c {
        fill: #11a0ad;
        }
      .ring.d {
        fill: #028d9e;
      }

      .btn.tap.area {
        z-index: 100;
        fill: transparent;
      }
      .btn.tap.area:hover + .ring.container .ring {
        animation-iteration-count: infinite;
        animation-timing-function: linear;
      }

      .btn.tap.area:hover + .ring.container .ring.a,
      .btn.tap.area:hover + .ring.container .ring.c {
        animation-name: clockwise;
      }
      .btn.tap.area:hover + .ring.container .ring.b,
      .btn.tap.area:hover + .ring.container .ring.d {
        animation-name: counter-clockwise;
      }

      .btn.tap.area:hover + .ring.container .ring.a {
        animation-duration: 1.33s;
      }
      .btn.tap.area:hover + .ring.container .ring.b {
        animation-duration: 1s;
      }
      .btn.tap.area:hover + .ring.container .ring.c {
        animation-duration: .67s;
      }
      .btn.tap.area:hover + .ring.container .ring.d {
        animation-duration: .33s;
      }

      @keyframes clockwise {
        from {
          transform: rotate(0deg);
        }
        to {
          transform: rotate(360deg);
        }
      }
      @keyframes counter-clockwise {
        from {
          transform: rotate(0deg);
        }
        to {
          transform: rotate(-360deg);
        }
      }
    </style>
  </defs>
  <title>ring btn</title>
  <rect class="btn tap area" width="350" height="350"/>
  <g class="ring container">
    <path class="ring a" d="M119.139,129.639a10.5,10.5,0,0,1-7.425-17.924,89.5,89.5,0,0,1,126.571,0,10.5,10.5,0,0,1-14.849,14.85,68.5,68.5,0,0,0-96.873,0A10.468,10.468,0,0,1,119.139,129.639Z"/>
    <path class="ring b" d="M104.29,114.79a10.5,10.5,0,0,1-7.425-17.924,110.5,110.5,0,0,1,156.269,0,10.5,10.5,0,1,1-14.849,14.85,89.5,89.5,0,0,0-126.57,0A10.468,10.468,0,0,1,104.29,114.79Z"/>
    <path class="ring c" d="M89.44,99.94a10.5,10.5,0,0,1-7.424-17.925,131.5,131.5,0,0,1,185.967,0,10.5,10.5,0,1,1-14.849,14.85,110.5,110.5,0,0,0-156.27,0A10.468,10.468,0,0,1,89.44,99.94Z"/>
    <path class="ring d" d="M74.591,85.091a10.5,10.5,0,0,1-7.425-17.925,152.5,152.5,0,0,1,215.667,0,10.5,10.5,0,1,1-14.849,14.85,131.5,131.5,0,0,0-185.968,0A10.468,10.468,0,0,1,74.591,85.091Z"/>
  </g>
</svg>

Upon initial inspection, this button appears to work well once you hover over the .btn.tap.area that I have specified. However, if your cursor intersects with one of the animated .ring paths, the animation seems to restart.

I wanted to resolve this issue of re-triggering the animation without using any JavaScript.

To address this problem, I decided to place the transparent .btn.tap.area on top of the other paths within the SVG.

Since I rely on the rendering order of my SVG paths in the CSS (e.g.,

.btn.tap.area:hover + .ring.container .ring.a {
), I couldn't change the sequence of paths.

While z-index is not valid in the context of SVG, I came across a potential solution in this post. The alternate approach suggested was to use <use xlink:href="#btnID"/> to call a second instance of the .btn.tap.area, provided I added an ID of btnID to the existing element. Unfortunately, this method did not work as expected.

Is there another way to ensure that the .btn.tap.area remains in front of the other paths without relying on JavaScript?

You can view the issue for yourself on this fiddle.

Answer №1

To disable pointer events on the ring elements, include the following CSS:

  .ring {
    transform-origin: 175px 175px;
    pointer-events: none;
  }

Answer №2

When it comes to changing the order of SVG elements, z-index won't do the trick. However, you can achieve this using HTML elements instead. Here's a solution that works:

To start, place the tap-area within another absolutely-positioned SVG element.

.svg-stack {
    position: relative;
}

.svg-tap-area {
    position: absolute;
    z-index: 1;
}

.ring {
    transform-origin: 175px 175px;
}

/* Additional CSS classes */
<div class="svg-stack">
  <svg class="svg-tap-area" xmlns="http://www.w3.org/2000/svg" version="1.1" width="350" height="350">
    <title>ring area</title>
    <rect class="btn tap area" id="one" width="350" height="350"/>
  </svg>

  <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="350" height="350">
    <title>ring btn</title>
    <g class="ring container">
      <path class="ring a" d="(path data)"/>
      <path class="ring b" d="(path data)"/>
      <path class="ring c" d="(path data)"/>
      <path class="ring d" d="(path data)"/>
    </g>
    <rect class="btn tap area" id="one" width="350" height="350"/>
  </svg>
</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

Utilizing a Bootstrap grid system (or an IE-compatible CSS grid) to align elements on the provided

Looking for suggestions on achieving the following layout without using CSS grid, either with Bootstrap or IE compatible CSS grid. On large screens: Head and body stack on the left, with an image on the right covering the height of both. [&mdash ...

toggle the outer div along with its corresponding inner div simultaneously

On one of my pages (let's call it "page1"), I have multiple divs, some nested within others. These divs are initially hidden and toggle on when a specific link is clicked (and off when clicked again). To view a nested div, the outer div must be opened ...

What is the method for incorporating this effect into the final sentence of a text?

I am trying to create a unique design effect by applying a custom border to only the last line of text. You can see an example here. In this scenario, the target text is "2000 years old." (with that specific length) and not the entire width of the parent ...

What happens when a browser can support multiple versions of a font - which one does it choose

If I have two versions of a font, customFont1.woff2 and customFont1.woff, and I list the woff2 version first followed by the woff version in the font declaration file, what happens when the browser supports both formats? Will it download both fonts or ju ...

Flexbox grid implementation for a stylish Bootstrap 4 masonry layout

Can a masonry column layout be achieved using the flexbox grid provided by Bootstrap 4? It appears that all the columns have the same height. ...

The Bootstrap CDN is malfunctioning and displaying errors in the console

I attempted to incorporate Bootstrap 4.5 using the CDN provided on their main website. However, after adding all the code lines to my project, I encountered numerous issues with my custom CSS and the Bootstrap carousel failing to function. Upon inspecting, ...

I can't seem to shake off this constant error. Uncaught TypeError: Unable to access property 'classList' of null

I am facing an issue with the "Contact Me" tab as it does not display its content when clicked. Here is the code snippet: <body> <ul class="tabs"> <li data-tab-target="#home" class="active tab">Home< ...

Is it possible for Carousel to showcase a different layout other than tables or items? And is there a way to customize

I'm trying to use Bootstrap 5 to display items in a row, like sets of 3 or 12, and have them slide into view one set at a time. However, when I add a carousel, the items end up stacked on top of each other. Here is the code snippet: <div c ...

What is the best way to align text in the vertical center?

Trying to design a promotion layout with an image on the left and text on the right. How can I center the text vertically to appear in the middle of the picture? Attempts using margin and vertical-align have not been successful. Also, why does the text di ...

Overlapping background images of flex elements in Safari

This webpage is designed as a single-page layout using Gatsby: <div className='mainContent'> <section className='contentSection'> <h1 className='header'>Heading</h1> <div c ...

What is the best way to achieve vertical text box scrolling in CSS and HTML overflow?

I'm having an issue with a text box I created and I couldn't find a solution elsewhere. Here is the CSS script for the text box: css: .cln{ top:220px; width:680px; height:350px; text-align:left; overflow:scroll; white-space: nowrap; overflow: ...

`Center the image on top of the text`

Currently, I am working with Bootstrap 4 to create a component that includes two tiles. Each tile has an icon image on the left side and a hyperlink on the right side. On desktop view, the tiles should be displayed horizontally and vertically centered. How ...

Excessive screen height causes the CSS box layout to overflow

I am looking to create a screen layout similar to the one shown in this image. It should consist of a row with no overflow and include: A left box that contains: A fixed height header (20px), An aspect square box taking up the remaining height. ...

Trouble displaying data in Jquery JSON

I've been on the hunt for hours, trying to pinpoint where the issue lies within my code. Despite scouring different resources and sites, I can't seem to figure it out. Whenever I click "Get JSON Data," nothing seems to display below. Can someone ...

Issue with margin:auto in Internet Explorer 5

I have been experimenting with IE11's developer tools and discovered that when changing the browser mode, everything appears as expected in Edge, 10, 9, 8, and 7. However, in IE5, the div is forced to align to the left instead of the middle. Could so ...

Preventing Paste Function in Electron Windows

Currently, I am utilizing Electron and attempting to prevent users from pasting into editable content. While paste and match style remains enabled, the functionality is flawless on Mac devices. However, there seems to be an issue on Windows where regular ...

How can you trigger a modal to appear when an image is clicked?

There are images inside <div> tags. When one of the images is clicked, a modal appears to display information about the specific image. Each modal has a unique id or class, such as modal4. My example: <image type="image" src="Images/Drake.jpg" ...

Creating CSS-in-JS Components in React JS without External Stylesheet interference

import React, { Component } from "react"; import './navbar.css' class NavBar extends Component { render() { return ( <div> navbar content </div> ); } } export default NavBar; If I were to ...

I am looking for guidance on removing the bottom line from the ionic 4 segment indicator. Any advice or tips on

.segment-button-indicator { -ms-flex-item-align: end; align-self: flex-end; width: 100%; height: 2px; background-color: var(--indicator-color); opacity: 1; } I am a beginner in hybrid app development and ...

Using a personalized SVG file within Material UI's SVG ICON with ease

I have been attempting to utilize a chip with an SVG delete icon. The code for the icon is const icon = (props) => { return ( <SvgIcon> <img src={'ic_check.svg'} style={{width: '20px'}} width={&apos ...