Issue with Safari: Unable to trigger CSS :hover when tapping SVG element

On an iOS device in Safari, tapping this SVG element does not trigger the transition animation to fade in the replacement

<g id="training-sub-menu">
. The animation is confirmed to work, as there is a strange behavior where long-pressing where the links should be opens an iOS context menu that then fades in the <g> with a 2-second transition. It seems that the animation does not get triggered, unlike other browsers that respond to :hover.

<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 306.12 409.2">
  <defs>
    <style type="text/css">
      @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@500;600');

      .font-md {
        font-family: 'Poppins';
        font-size: 10px;
        font-weight: 500;
      }

      :root {
        --yellow: #f6b034;
      }

      .training {
        fill: var(--yellow);
      }

      .sub-menu {
        opacity: 0;
        visibility: hidden;
        height: 0;
      }

      .sub-menu > g {
        opacity: 0;
        -webkit-transition: opacity 2s ease-in-out;
      }

      .has-dropdown:hover + .sub-menu,
      .has-dropdown:hover + .sub-menu > g {
        opacity: 1;
        visibility: visible;
        height: auto;
        pointer-events: visiblePainted;
        transform: unset;
      }

      .has-dropdown:hover {
        opacity: 0;
        visibility: hidden;
        height: 0;
      }

      .sub-menu:hover {
        opacity: 1;
        visibility: visible;
        height: auto;
        pointer-events: none;
      }

      .sub-menu:hover > g {
        opacity: 1;
      }
    </style>
  </defs>
  
  <g id="training" class="has-dropdown">
    <path class="training" d="m0,256c0-27.61,22.39-50,50-50,27.61,0,50,22.38,50,49.99,0-.21.02-.42.02-.63v29.39c0,11.06,8.45,20.15,19.25,21.15.02,0,.04.09,0,.09-.04,0-62.38,0-69.27,0,0,0,0,0,0,0s0,0,0,0h-.62c.1,0,.21,0,.31,0C22.22,305.82,0,283.51,0,256Z"/>
    <text class="font-md" transform="translate(31 285)">Training</text>
  </g>
  <g id="training-sub-menu" class="sub-menu">
    <path class="training" d="m0,256c0-27.61,22.39-50,50-50,27.61,0,50,22.38,50,49.99,0-.21.02-.42.02-.63v29.39c0,11.06,8.45,20.15,19.25,21.15.02,0,.04.09,0,.09-.04,0-62.38,0-69.27,0,0,0,0,0,0,0s0,0,0,0h-.62c.1,0,.21,0,.31,0C22.22,305.82,0,283.51,0,256Z"/>
    <g id="text">
        <text class="font-md sub-menu-item" transform="translate(31 285)">
            <a href="https://google.com" target="_parent">Google</a>  
        </text>
        <text class="font-md sub-menu-item" transform="translate(31 265)">
            <a href="https://google.com" target="_parent">Google</a>  
        </text>
        <text class="font-md sub-menu-item" transform="translate(31 245)">
            <a href="https://google.com" target="_parent">Google</a>  
        </text>
    </g>
  </g>
</svg>

Efforts to apply the transition using <g> elements and -webkit-transition have been unsuccessful. Additionally, using onclick as suggested on the page has not resolved the issue either. Could the problem be related to the absence of a clickable element as mentioned on this page?

Answer №1

Ultimately, I decided to utilize JavaScript instead of pursuing a CSS solution, even though I believe the CSS approach would have been more elegant. I've developed a set of basic JavaScript functions within the parent HTML file, incorporating click event handlers to manipulate the SVG and toggle classes:

<script>
    function showSubMenu(e) {
        e.currentTarget.classList.toggle('hidden');
        e.currentTarget.nextElementSibling.classList.toggle('visible');
    }

    function closeAllMenus(e) {
        if (!e.target.parentElement.classList.contains('has-dropdown')) {
            var subMenus = svgDoc.querySelectorAll('.sub-menu');
            subMenus.forEach(subMenu => {
                subMenu.classList.add('hidden');
                subMenu.classList.remove('visible');
            })

            var dropdowns = svgDoc.querySelectorAll('.has-dropdown');
            dropdowns.forEach(dropdown => {
                dropdown.classList.remove('hidden');
                dropdown.classList.add('visible');
            })
        }
    }

    document.addEventListener('click', closeAllMenus);

    var svgObj;
    if (screen.width > 767) {
        svgObj = document.getElementById("svg-object-desktop");
    }
    else {
        svgObj = document.getElementById("svg-object-mobile");
    }
    
    var svgDoc;
    svgObj.addEventListener('load', function() {
        svgDoc = svgObj.contentDocument;

        var dropdowns = svgDoc.querySelectorAll('.has-dropdown');
        dropdowns.forEach(dropdown => {
            dropdown.addEventListener('click', showSubMenu)
        });
    });
</script>

Due to the use of different SVGs for mobile and non-mobile devices, the conditional check was necessary.

On a positive note, the corresponding CSS code has now been simplified:

.sub-menu > g {
  transition: opacity 0.5s ease-in-out;
}

.hidden,
.sub-menu {
  opacity: 0;
  visibility: hidden;
  height: 0;
  transition: opacity 0.5s ease-in-out;
}

.visible,
.has-dropdown {
  opacity: 1;
  visibility: visible;
  height: auto;
  pointer-events: visiblePainted;
  transform: unset;
}

Currently, the functionality works smoothly on iOS Safari.

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

What is the best way to refresh the slick jQuery plugin for sliders and carousels?

I am currently facing an issue with two buttons that have the same function. The purpose of these buttons is to retrieve data from an API, convert it to HTML, and then append it to a <div> using jQuery. Finally, the data is displayed using the slick ...

How can I integrate checkboxes in a list view with jQuery Mobile?

How can I display the status of users with three different levels in a list view? I need to show whether they are attending or not, similar to the image provided. The issue is that currently the checkbox appears below the name, but I want it to be at the r ...

Silhouette as the backdrop image

There is a span element that I am using in the following way - <span class="tick"></span> This creates a decorative "tick" for a checkbox. The CSS code used for this is - input[type="checkbox"] + span > span.tick { display: block; ...

Interactive text animation triggered by a click

jQuery ( function ( $ ) { console.log(">>Testing animation"); $('a.loveit').on('click',function(event){ event.preventDefault(); var text = $(this).find('div.love-text'); ...

Send the form via ajax

I am in the process of creating a unique application for my university, which is essentially a social network. One key feature I need to implement is the ability for users to add comments, which involves inserting a row into a specific database. To achieve ...

Tips for Positioning a Page Layout in the Center Using HTML and CSS

I'm a beginner in HTML and CSS and I'm trying to create a simple webpage layout from scratch. I want all the elements of the page (nav, header, section, footer, etc.) to be centered while still keeping the nav bar on the left side. I've set ...

Is it possible to automate the process of clicking the "next" or "previous" button on a webpage after a video has finished playing?

Is it possible to automate clicking the "next" or "previous" button on a specific website? The buttons are not labeled as such but instead show the cartoon name and episode number. For example, increasing episode numbers indicate the "next" episode while d ...

What is the best way to add a button over an image using Tailwind CSS in Next.js?

I've been trying to display a button on top of an image using Tailwind CSS and Next.js, but I'm having trouble getting it to align properly. Here is the code snippet I've been working with: <div> <Image src={projectAiWrite ...

``Need help hosting static HTML files on Google App Engine? Here's a step-by-step

Can I use App Engine to host a static HTML website? How can I set up my domain name to work with it? ...

Leveraging JSON in a pickerview to dynamically update options

I am fairly new to Xcode and Obj-C programming, so please bear with me as I try to figure things out. After browsing through this site and others, I was able to put together a pickerview with two components. Upon selecting an option in the first component ...

How can I eliminate the empty spaces around a bar chart in Kendo UI?

Struggling to eliminate the extra space surrounding the Kendo UI chart below. Could this be due to a gap or spacing issue? The goal is to create a single-line bar chart with only grey appearing on the right side. Access JSFiddle Codes Here $(doc ...

Understanding the Importance of CSS Specificity in Resolving Selector Conflicts

I need help with a specific pseudo-class selector issue. Even with !important, the text in the li:first-child element is not appearing in blue. The selector specificity for p is: (0, 0, 1) The selector specificity for li:first-child is: (0, 1, 1) I want ...

The onChange function is not triggered when the dropdown menu consists of only one item

I am facing an issue with my dynamically populated dropdown menu. When the dropdown contains only one element, the onChange() function of my select tag does not work as expected. It functions perfectly fine when there are multiple elements present. How c ...

The animation of a disappearing div with CSS is not stopping when hovering over it

Hello, I've been working on a snackbar feature that appears and disappears on a set timer but also needs to pause when hovered over. Unfortunately, the current setup with setTimeout and useState is causing issues with this functionality. I have looke ...

How can I include line breaks using HTML `<br>` tags in a textarea field that is filled with data from a MySQL

Within a modal, I am showcasing a log inside a read-only <textarea> field that contains data fetched from my MySQL database. Below this, there is a writable <textarea> field where users can input updates to the log, which are then added to the ...

assistance in incorporating CSS classes using jQuery

In an attempt to modify the bottom border color of my navigation bar based on the link being hovered over, I want the bottom border color to change to match that of the hovered link. When the link loses focus or hover, the navigation bottom-border should r ...

Tips for avoiding the initial rendering of react components on a page when styled-components are not yet loaded

I have developed a unique custom component library using React and styled-components for creating reusable components. I then imported this library into my nextJS project, but I noticed that the styles from the custom component library are not applied duri ...

What is the method for moving one div above or below another div using the scroll bar?

Here's the scenario I'm facing: I have rows with buttons that, when clicked, reveal a set of options. The challenge is that depending on where the row is located on the page, the settings need to open either above or below the button. When the b ...

Adjust the size of the div container while ensuring that all elements are aligned horizontally

My goal is to design a page where all elements remain perfectly aligned, even when the user resizes the window. However, the code I have written does not achieve this. <div style="display:flex; justify-content: left; padding: 3px;"> <div style="m ...

Encountering a 500 error when making a put/post/patch request in a React Native iOS app

I am encountering a 500 error while trying to perform a put request in my react native (0.60.4) iOS project. The same issue arises when using post or patch methods, as well as when attempting the request with Postman. Interestingly, my SQL update works pe ...