7

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?

user2989731
  • 1,299
  • 3
  • 17
  • 33
  • wow so I'm not going crazy. did anybody figure this out? it's not related to hover as such - and happens on iPad too which doesn't have hover. if you just set the src via a click event it will also not be sized properly. waiting 1 week for iOS8 to see if it's fixed! – Simon_Weaver Sep 14 '14 at 18:13

6 Answers6

5

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");
    }
);
Ian
  • 146
  • 1
  • 6
  • Wow, I can't believe this worked for me (Safari on Mac & iOS), but it did. I did, however, use '?' for the query delimiter, like any other URL. – cr0ybot Dec 17 '14 at 16:41
  • Yeah, forgot to mention that our Urls always have the ? already, hence the & char delimiter. Glad it worked for you as well! – Ian Dec 19 '14 at 16:02
  • I was also seeing this exact issue with showing SVGs though the IMG tag. The SVG would resize when I would swap the src through JavaScript. Adding the query parameter to the src fixed the issue! Good find and thanks for posting! – SharpMobileCode Mar 25 '15 at 19:24
  • This IS the answer. Excellent. – JimXC May 21 '15 at 09:21
  • So this works. Yay! But the parameter has to be exactly 'SafariFix' - anyone aware of why? – Sam K Jun 08 '15 at 11:09
0

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;
}
Loilo
  • 13,466
  • 8
  • 37
  • 47
  • btw I tried your code with two random images from google and it doesn't resize in Safari so I may not be able to retrace what exactly the issue is. – Loilo Feb 03 '14 at 20:43
0

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

Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
0

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.

sharkbait
  • 2,980
  • 16
  • 51
  • 89
Allon
  • 1
  • 1
  • Just to further elaborate: the width and height values as defined in your CSS should be identical to the values defined for the images in the image's SVG code. The bug will appear even if you're 1 pixel off. – Allon Nov 09 '15 at 11:49
0

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.

0

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.

Drarok
  • 3,612
  • 2
  • 31
  • 48