user2989731
user2989731

Reputation: 1359

SVG resizes on hover in safari only

I have this weird issue where an svg is resizing on hover in safari. I'm using jquery's hover to replace an svg on a page with a slightly different svg. This work's properly in all browsers except safari which for some reason completely resizes the svg on mouseover and mouseout.

My svg's height is set in the css

img.svg-graphic {
  height: 180px;
}

And displayed on the page as an image

<div class="container">
  <img class="svg-graphic" src="svg-icons/version1.svg">
</div>

When I hover over the container, I swap out the svg with another, and then return to the default when I hover off.

$('.container').hover(function() {
  $('.svg-graphic').attr('src', 'svg-icons/version2.svg');
}, function() {
  $('.svg-graphic').attr('src', 'svg-icons/version1.svg');
});

Any ideas on what could be causing safari to completely ignore the sizing?

Upvotes: 8

Views: 3633

Answers (6)

Drarok
Drarok

Reputation: 3809

I tried all the work-arounds in this thread to no avail on Safari 11.1, but did eventually find a new one.

The bug only appears to trigger where there is a CSS transition that affects the background – using transition: color is fine, but transition: all is not.

I've put together a CodePen demonstrating the issue.

Upvotes: 2

Chance Strickland
Chance Strickland

Reputation: 333

None of the proposed solutions here seemed to work for what I'm working on currently, as I'm loading SVGs as background images rather than in img or svg tags. I felt like the hover effects were more important for UX than having SVGs, so I targeted the elements containing SVG background images and added a safari class so I could force the use of PNG fallbacks using CSS. There certainly could be a better/more performant way of handling this, but this is my jQuery:

if ( navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1 )  {
  $('*').each( function() {
    if ( ! $(this).css('background-image') ) {
      return;
    } else if ( ~ $(this).css('background-image').indexOf(".svg") ) {
      $(this).addClass('safari');
    }
  });
}

Then I just set a few fallbacks using the safari helper class in CSS:

.element {
  background-image: url('img.png');
  background-image: url('img.svg');
}

.element:hover {
  background-image: url('img-hover.png');
  background-image: url('img-hover.svg');
}

.element.safari {
  background-image: url('img.png');
}

.element.safari:hover {
  background-image: url('img-hover.png');
}

While this wouldn't really help in this specific case, it may help others who stumble upon this answer through searching.

Upvotes: 0

Allon
Allon

Reputation: 1

I've had this bug and it took me a while and quite a bit of experimentation (and frustration) to finally find a solution.

Basically, if the width and height of the source and target SVG images aren't identical, then you will experience this bug.

I was able to overcome this bug by editing the width and height attributes in the SVG file itself:

width="20px" height="20px"

Screenshot:

enter image description here

If you ensure these values are identical on both the source and target SVG images, it should resolve this bug.

Upvotes: 0

Ian
Ian

Reputation: 146

This is definitely a weird Safari bug. I think it is related to how Safari restores the original image from the cache. At any rate, I've found a workaround that works in our hover code. If you make the URL of the restored image unique via an extra query string parameter, it seems to avoid the SVG resize bug. Here's the code from our site (note the "&SafariFix" query string parameter on restore):

// activate any img hovers based on the hover-src attribute
$("img[data-hover-src]").closest("a").hover(
    function () {
        var image = $(this).find("img[data-hover-src]");
        if (image.data("originalSrc") === undefined) {
            image.data("originalSrc", image.attr("src"));
        }
        image.attr("src", image.data("hoverSrc"));
    }, function () {
        var image = $(this).find("img[data-hover-src]");
        image.attr("src", image.data("originalSrc") + "&SafariFix");
    }
);

Upvotes: 5

Simon_Weaver
Simon_Weaver

Reputation: 145910

This is a nasty bug, plain and simple and there's likely nothing that can be done (I certainly cannot find any solutions after much searching).

The image reports the correct size, and even if you put a 1px border around the image it is only shrunk inside this bounding box. It also is very inconsistent and not repeatable. If you have a responsive design and resize the page then the images fix themselves.

Here's possible solutions

  • Wait for Safari 8 (or whatever the next version is) and just forget about it
  • Disable rollovers for Safari
  • Use png / jpg images
  • Overlay the two images on top of each other and show and hide them instead of doing a replace

I think I'm going to take the two images approach.

Note: I don't have Safari for Mac and have only been testing on a iPad with iOS7

Upvotes: 0

Loilo
Loilo

Reputation: 14685

I had a similar issue some days ago - try to give the SVG a "width: auto" in CSS and try if it works.

img.svg-graphic {
    width: auto;
    height: 180px;
}

Upvotes: 0

Related Questions