SVG rendering offset in Chrome - html

I've come across a strange behaviour (bug?) for rendering SVGs in Chrome. I want to use a SVG sprite in a background-image. This way I want to have access to multiple colors by just setting the background-position accordingly. While this seems to work Chrome is offsetting the SVG so it does not render at the correct position. It kinda looks like the background-position is not at (0, 0)...
Interesstingly Chrome is not always offsetting it... By changing the values of width/height of the div the SVG snaps back to the correct position for some widths/heights. Here is a pen I created to showcase the problem: https://codepen.io/thoro/pen/XpedPR
If you open the pen in Chrome, the arrow sprite will be offset and therefore the black arrow not fully visible. By changing the $box property to 66px the arrow will snap to the correct position just to be offset again when increasing the number...
In Firefox the arrow is rendering as expected. (IE is a whole other story but does not matter here)
My SVG I am trying to display:
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 120">
<title>grid-link</title>
<symbol id="my" viewBox="0 0 10 120">
<path d="M6.1 7.7l.6.6L10 5 6.7 1.7l-.6.6 2.3 2.3H0v.8h8.4L6.1 7.7z"/>
</symbol>
<use xlink:href="#my" y="0" fill="#000"/>
<use xlink:href="#my" y="110" fill="#fff"/>
</svg>
Am I doing something wrong? Is there any way to fix this?
The problem can be fixed by removing the viewBox and using width and height instead:
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="10" height="110">
<title>grid-link</title>
<symbol id="my">
<path d="M6.1 7.7l.6.6L10 5 6.7 1.7l-.6.6 2.3 2.3H0v.8h8.4L6.1 7.7z"/>
</symbol>
<use xlink:href="#my" y="0" fill="#000"/>
<use xlink:href="#my" y="110" fill="#fff"/>
</svg>

Your problem is with ViewBox. You specify a ViewPort (via the div's width and height) of 65 by 65, but set the ViewBox height as 120.
If you remove ViewBox completely from your SVG it fixes the problem you describe (and makes the resulting icon scalable as you change $box).
Sara Soueidan has a very useful write-up of ViewPort, ViewBox and the SVG coordinate system on her blog: https://sarasoueidan.com/blog/svg-coordinate-systems/.

Related

Reduce the thickness of a svg image (arrow)

I am trying to reduce the thickness of an arrow SVG image.I tried with stroke="grey" stroke-width="-10".When I change the value of stroke-width it's only increasing the thickness without reducing.
<svg fill="#808080" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z" stroke="grey" stroke-width="-10"/>
<path d="M0-.25h24v24H0z" fill="none"/>
</svg>
The best way to demonstrate this is with a gif.
The shape has a mininum width, and increasing that width will result in a thicker shape.
But, as Paulie_D said:
The size of the image is not determined by the stroke...but rather the
path
The only way to actually decrease the width is to modify the path in a vector editor such as Inkscape. Clicking the second tool on the left (or pressing F2) will show boxes around the corners. The boxes can be dragged around to make the shape thinner.

Inaccurate SVG rendering in FireFox

My SVG image is pixel perfect, and all browsers render it OK, except FireFox.
Example 1 (Bootstrap markup):
https://codepen.io/anon/pen/gdVxJo
There are just two rectangles in Bootstrap columns. All the rectangles has pixel-aligned borders and border width=2px but FireFox adds antialiasing.
I guess it depends of area height, but do not know why. There is example with one rectangle without any CSS.
Example 2 (clean HTML):
https://codepen.io/anon/pen/OoKxEd
<body>
<svg xmlns="http://www.w3.org/2000/svg" width="396" height="100">
<rect x="0" y="0" width="396" height="100" fill="none" stroke="#000" stroke-width="2"></rect>
</svg>
</body>
You maybe need to change height of your render area on CodePen to reproduce the bug.
Anybody knows is it possible to force FireFox to draw lines correctly?

what is stroke and stroke width in SVG and how is it rendered in the HTML?

<svg width="400" height="400" style="background-color:green">
<circle cx="200" cy="200" r="50" stroke="red" stroke-width="5" fill="yellow"></circle></svg>
<svg width="400" height="400" style="background-color:green">
<circle cx="200" cy="200" r="50" stroke="red" stroke-width="50" fill="yellow"></circle></svg>
<svg width="400" height="400" style="background-color:green">
<circle cx="200" cy="200" r="50" stroke="red" stroke-width="100" fill="yellow"></circle></svg>
<svg width="400" height="400" style="background-color:green">
<circle cx="200" cy="200" r="50" stroke="red" stroke-width="150" fill="yellow"></circle></svg>
I've just started learning about SVGs and I am little confused about stroke and stroke width, and how they are rendered.
In the developer tools, it looks strange whenever I increase the stroke width, the circle holding area increases but the dimensions are 100x100 always.
I want to know if the stroke width is being added to the radius or am I confused on its rendering. Someone need to explain the concept behind the svgs or direct me to some pages so that i can learn deep
SVG stroke Property
The stroke property defines the color of a line, text or outline of
an element
SVG stroke-width Property
The stroke-width property defines the thickness of a line, text or
outline of an element
Check this w3schools article for svg properties
SVG is XML based, which means that every element is available within
the SVG DOM. You can attach JavaScript event handlers for an element.
In SVG, each drawn shape is remembered as an object. If attributes of
an SVG object are changed, the browser can automatically re-render the
shape.
That problem that is showing to you is because the maximum stroke-width that you can apply to a circle with the radius 50px is 100px so it's a simple math. Your max stroke-width for r=50px is 2*r so it's 100px.
When you add stroke-width = 150 it means that the stroke-width radius need to be bigger to hande that. Chrome shows the circle as 100x100 and that's true the circle radius doesn't change only the stroke radius changes.
To prove that just change your stroke-width to 500px and you will clearly see how this is working and you will understand this.
This is also known as bug so you have this open issue in this link

Allowing preserveAspectRatio="none" on svg without stretching image elements within, to allow for flexible image masking

I've been toying with using clipping masks on images for certain responsive layouts, but I'm getting a bit twisted up on the logic of the viewBox, preserveAspectRatio and the svg coordinate system.
Take for example:
<svg class="clipper" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" preserveAspectRatio="none">
<g>
<clipPath id="mask">
<polygon points="0,0 50,0 40,50 0,50 0,0" />
</clipPath>
</g>
<g clip-path="url(#mask)">
<image preserveAspectRatio="xMidYMid slice" height="50%" width="50%" xlink:href="http://lorempixel.com/1400/800" />
</g>
</svg>
This plots a polygonal clipping mask, a skewed quadrangle that reaches out to the halfway point of the svg element and halfway down the element. The image is inside a group, which is cropped by the mask.
I've put preserveAspectRatio="none" on the svg element, to make sure the clipping mask appears where I desire, but this causes the image to stretch.
The preserveAspectRatio logic on the svg element, appears to supersede the attribute applied to the image element, where I try to preserve and slice the aspect ratio.
If, instead, I put the "xMinYMid slice" value on the svg element instead, the image maintains its scale, but the clipping mask polygon no longer is positioned at the desired location as it is also scaling, in a manner I can't quite determine its logic.
Is there a way to preserve the co-ordinate system in the first example, but keep images from stretching? I have laid both variants side by side for a comparison on codepen here.

Image inside svg pattern is blurried after zoom in Chrome

I'm having rect inside svg and rect is filled with some pattern. This pattern is just png image. Zooming this rect work fantastic in FireFox, Safari etc, but not in Chrome and Chromium. Chrome is making this image a little bit blurry. I was searching for similiar problems, but i need svg, rect, pattern to be 100% width and height... it is they need to be 100% of container size and not some fixed size. I created fiddle to see the effect: http://jsfiddle.net/j5gfjnpd/2/
<div style="width: 100vw; height: 100vh">
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<g>
<defs>
<pattern id="floor" viewBox="0 0 3508 4962" width="100%" height="100%" patternContentUnits="objectBoundingBox" preserveAspectRatio="xMidYMid meet">
<image id="test" width="3508" height="4962" preserveAspectRatio="xMinYMin meet"></image>
</pattern>
</defs>
<g id="mapZoom">
<rect width="100%" height="100%" fill="url(#floor)">
</rect>
</g>
</g>
</svg>
</div>
To see this effect you have to zoom-scroll the image and search for some small captions. In Chrome they are blurried and in FireFox they are really clean and nice.
Is there some fix to this, because i'm losing my head trying to fix this. I will be really happy to see some help. Thanks in advance
My best guess is that the zoom is being done on the GPU by Chrome, in which case, it's not re-rasterizing the jpg, it's just doing pixel interpolation when it scales the asset. AFAIK, there is no reliable way to kick Chrome to re-rasterize, but you can try doing it by adding a transition/animation that can't be performed on the GPU (something that's not a scale/skew/position transform or opacity).