Chrome SVG background image aliasing bug? - html

I've been using an SVG background image on a textarea element to provide line numbering for the text displayed in the text area (the line numbers in the following images are from an SVG background image).
However, with Chrome 60.0.3112.113 on Windows 7 I get jagged SVG Display:
As I found out by fiddling, when I edit the style properties of the svg element to include opacity: 0.99, it renders as would be expected (and as Chrome did before):
The HTML code to reproduce this is as follows (change opacity to 0.99 to see the difference):
<!DOCTYPE html>
<html>
<title>SVG background image opacity/aliasing bug</title>
<style>
#ta {
font-size: 16px;
width: 100%;
height: 100%;
padding-left: 40px;
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" style="fill: red; opacity: 1.0"><text x="4" y="20">0001</text><text x="4" y="38">0002</text><text x="4" y="56">0003</text></svg>')
}
</style>
<body>
<textarea id="ta" cols="40" rows="4">Line 1
Line 2
Line 3</textarea>
</body>
</html>
If I just place the SVG code into a separate file and open it as plain SVG file (rather than as background in a data-URI) using Chrome it displays as expected.
So while there's the opacity: 0.99 workaround, I'd like to know why Chrome renders this simplistic SVG incorrectly, or if there's a better workaround, or if there's something fundamentally wrong with the aproach I'm using.

Related

Border Image gif doesn't animate for svg in Edge 42

I am using a gif file to show animated border using css border-image around a svg element.
#animated-gif-container {
width: 48px;
height: 48px;
border: 2px solid;
border-image: url(https://s3.gifyu.com/images/practiceHighlighBorder.gif) 2 round;
}
<svg id="animated-gif-container"></svg>
This works well in Chrome, Firefox, but not in Edge (Version 42)
Verified it is working in Edge 20 also. Verified it works for div element also. However I can not change it to div because of dependency in code.
One interesting thing, if I select element by dev tool, image starts animating. Not able to figure out the solution
URL to reproduce: https://plnkr.co/edit/IeVQf7mjTJuPdwFckumf?p=preview
You don't really have to use an image to achieve this effect. Source for my answer is a talk from Lea Verou.
Note if you run this here on the site it won't work, you would have to encode it. I chose to keep it more readable but to see the effect in action you have to include the CSS-part in a referenced stylesheet (e.g. styles.css) instead of just putting it into the head of your site.
.🦄 {
background: url('data:image/svg+xml,\
<svg xmlns="http://www.w3.org/2000/svg">\
<style> #keyframes ants {to {stroke-dashoffset: -15px;}} </style>\
<rect width="100%" height="100%" style="stroke: black; stroke-width: 4px; fill: none;\
stroke-dasharray: 10px 5px; animation: ants .4s infinite linear;" /> \
</svg>');
}
<div class="🦄" contenteditable> Look at my awesome border</div>

Cursor property with custom url not displaying correctly in Chrome

I am using the CSS cursor property with custom images specified with URLs.
However, when doing this on Chrome, white dots appear around the cursor image.
If we look at the image below, you can see the problem on google chrome.
This does not happen on other browsers. Such as firefox:
Here is the link to the cursor images used:
http://imgur.com/a/dooCC
I thought originally that the issue would be that semi-transparency is used in the image. But the image has no semi-transparency at all.
What is going on here, and how would I fix something like this?
Thanks.
I tried to reproduce this example using Chrome 52.0 on Mac OS X 10.11, but I am not seeing the jagged white edges. Does this snippet show the jagged white edges for you?
.cursor-test {
height: 200px;
width: 100%;
}
#cursor-test-1 {
background-color: red;
cursor: url('http://i.imgur.com/jaYSPxo.png'), auto;
}
#cursor-test-2 {
background-color: blue;
cursor: url('http://i.imgur.com/aFU13SN.png'), auto;
}
<div id="cursor-test-1" class="cursor-test"></div>
<div id="cursor-test-2" class="cursor-test"></div>
Update: Here's an animated gif screenshot of how it looks for me. I attempted to capture a regular screenshot, but OS X seems to hide custom CSS cursors in screenshots.

Apply an SVG filter to a div's background-color

I have a <div> that has a background-color sitting in front of an image. I'm trying to apply a multiply effect using an SVG so that the background image behind the div comes through:
<svg>
<filter id="multiply">
<feBlend mode="multiply"/>
</filter>
</svg>
Unfortunately, only the solid background color is being changed, and I get no transparency through to the background.
Here's the fiddle: https://jsfiddle.net/0p58bxsp/1/
The effect I'm expecting is something like this:
I know the visual effect could be fudged using an rgba value as the background color, but I'm very specifically looking for the combination of a solid color having a multiply filter applied to it.
Is this a limitation of the current SVG implementation?
Here's the definition of a multiply blend:
Multiply blend mode multiplies the numbers for each pixel of the top layer with the corresponding pixel for the bottom layer. The result is a darker picture. , where a is the base layer value and b is the top layer value.
As such, using opacity or alpha doesn't give me the exact result that I'm looking for.
This was supposed to be possible if you stayed completely within SVG 1.1 by using the BackgroundImage pseudo input - but only IE10 ever supported it for inline SVG (Opera supported it for .svg files). Firefox, Chrome & Safari never supported it, and it's now formally declared "not to be implemented" by folks who work on those browsers.
You can import a copy of the background image using feImage and position it just right to match the actual background exactly. But depending on your design - that could take extensive javascript. And url() filters can behave strangely. https://jsfiddle.net/0p58bxsp/3/ shows how to do this - but it also surfaces a regression bug in Chrome with positioned primitives which will be fixed in next Chrome.
<div id="background">
<div id="effect">
Effect goes here
</div>
</div>
<svg width="100%" height="100%" viewBox="0 0 200 200">
<defs>
<filter id="multiply" x="0%"
y="0%" height="300%" width="300%">
<feImage x="0" width="400" height="400" y="0" preserveAspectRatio="xMaxYMax meet" xlink:href="http://lorempixel.com/400/400/" />
<feOffset dx="-100" dy="-100"/>
<feBlend mode="multiply" in="SourceGraphic"/>
</filter>
</defs>
</svg>
Safari 9(and only Safari 9) has a "backdrop-filter" that will do this, and you can also specify a mix-blend-mode which has broader support, but this is still pretty edge.
If you need a multiply blend, it might be best to just keep everything in SVG.
You should add opacity: 0.4; into effect class. It will work fine.
#effect {
color: #fff;
height: 200px;
margin: 100px 0 0 100px;
width: 200px;
opacity: 0.4;
background-color: #3d3934;
filter: url(#multiply);
-webkit-filter: url(#multiply);
-moz-filter: url(#multiply);
}
As far as I know, svg effects are limited to the elements itself. You can't use it to mix with another element.
You can however get this effect with standard CSS mix-blend-mode
#background {
background-image: url(http://lorempixel.com/400/400/);
height: 400px;
padding: 1px;
width: 400px;
}
#effect {
color: #fff;
height: 200px;
margin: 100px 0 0 100px;
width: 200px;
background-color: gray;
mix-blend-mode: multiply;
}
<div id="background">
<div id="effect">
Effect goes here
</div>
</div>

Clip-path SVG polygon Internet Explorer

This code does not work in IE, I need to use it because I have to make an arrow that follows a point on the map.
div {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
right: 0px;
background: red;
clip-path: url(#cliparrow);
-webkit-clip-path: polygon(777px 285px, 0px 303px, 777px 315px);
}
svg {
width: 0;
height: 0;
float: left;
position: absolute;
}
<div></div>
<svg height="0" width="0">
<defs>
<clipPath id="cliparrow">
<polygon points="777,285 0,303 777,315" ></polygon>
</clipPath>
</defs>
</svg>
Any suggestions? Thanks.
Internet Explorer is not (currently) compatible with using clip-path via CSS on HTML elements (see can-i-use). clip-path is currently only a candidate recommendation for HTML and not yet in the spec (http://www.w3.org/TR/css-masking-1/).
You may, however, use clip-path as an SVG attribute on another SVG element (for example, if you load the MDN page on clipping and masking in SVG, it will work in IE).
If all you need to do is embed a colored shape, and not transform HTML content per se (e.g. apply clipping against HTML text, multiple elements, etc), you could even more simply just use an appropriately shaped SVG element (directly embedded in an otherwise transparent div if needed) instead of trying to clip an HTML element. This also removes the need for the browser specific webkit prefix.
<div>
<svg width="700px" height="700px" xmlns="http://www.w3.org/2000/svg">
<polygon id="arrow" points="777,285 0,303 777,315" ></polygon>
</svg>
</div>
example fiddle (with some extra helpers): http://jsfiddle.net/taswyn/cv6m76m7/
(You'll obviously need to set height and width appropriately, this was just a quick example using your shape. Note the use of SVG CSS to apply the color on the arrow, which this method allows)
Tested in IE 10 using IE 9 and 10 browser modes (and tested in Chrome). Probably won't work in 8 and below.
If you do need to clip against text, you'll need to use SVG text instead of HTML text elements.
Aside: If all you need to do is clip in a rectangle, you could temporarily use clip CSS, which is cross-browser compatible but deprecated, until the masking module hits recommendation status and clip-path becomes available for use on HTML as a W3C standard. (obviously this doesn't apply to your situation, but it may help someone else)

Using SVG as CSS3 background-image with scaling

When I use SVG in background property like this:
.svg-button {
-webkit-transform: scale(3.0) // root of the problem!
background: url(Button.svg) no-repeat;
width: 32px;
height: 32px;
}
I get blurred image as result. At the same time text in tag with this style is clear. Also if I scale page by using CTRL++ (browser zoom) instead transform property everything is clear.
If I replace CSS background property on:
<object type="image/svg+xml" data="Button.svg" width="32" height="32"></object>
the image is clear in any scale in any case.
Where is the problem?
Sample on jsfiddle
Update:
I found some more information about this problem:
StackOverflow question
Bug ticket for Chrome (I tried my test under Safari/Chrome/IE9/10 and behaviour is the same.
I was "playing" with this a while back and noticed this for fonts too. Although it seems to be fixed now (for the fonts at least).
As far as I understand the inner workings, the contents of the scaled element are mapped to a texture, which in turn is scaled.
As a workaround, try using a 3d translation and move the element on the z-axis to achieve the size change. This won't yield as much control over the final outcome though.
.svg-button {
-webkit-transform: perspective(800px) translateZ(-300px);
background: url(Button.svg) no-repeat;
width: 32px;
height: 32px;
}
For Chrome/Safari IE9/10 I have decided to use CSS zoom property instead scale property.
.svg-button {
zoom: 300%;
background: url(Button.svg) no-repeat;
width: 32px;
height: 32px;
}
For Firefox I still use CSS scale property because Firefox doesn't support zoom property. At the same time Firefox scales SVG background well. See result.
For IE9 I have written javascript which temporary modifies CSS width property and after small delay returns it back. In this way I force redraw CSS background.