SVG Circle Scaling - css

I have a simple SVG circle:
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
x="0px" y="0px" width="100px" height="100px" viewBox="0 0 100 100" overflow="visible" enable-background="new 0 0 100 100"
xml:space="preserve">
<circle fill="#6E6F6F" cx="50" cy="50" r="49"/>
</svg>
This image is being used as a background, and resized to 22px:
background: transparent url('++resource++svg/star_neg.svg') no-repeat 0 0 / 22px 22px;
When I view this in the browser, the right and bottom sides of the circle appear flat in Firefox (Chrome looks fine). If I zoom in on Firefox, the circle appears complete as expected. How can I fix this?

Finally found a simple solution. The div displaying the svg as the background should be larger than the SVG. I had the box at 22px square, the same size I was setting the SVG. To fix the issue, I displayed the box as 25px, with the background image centered instead of set in a corner.

Related

svg line color does not match css border color

I've created this svg to use to style a dropdown.
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
<g>
<line x1="10" y1="10" x2="10" y2="117" stroke-width="1" stroke="#ccc"/>
<path fill="#00305e" d="M95.0603,45.0773l1.9872,2.025c1.9246,1.9611,1.906,5.1078-0.0415,7.0461L68.0522,82.9645
c-1.9507,1.9414-5.1035,1.9414-7.0542,0L32.0442,54.1483c-1.9475-1.9383-1.9661-5.0849-0.0415-7.0461l1.9872-2.025
c1.947-1.984,5.1386-1.9991,7.1042-0.0334l23.431,23.431l23.431-23.431C89.9218,43.0782,93.1133,43.0933,95.0603,45.0773z"/>
</g>
</svg>
As you can see the line color is #ccc. I've styled the dropdown to have this style:
select {
border: 1px solid #ccc;
}
My problem is that the svg line color is much brighter than the border color of the select.
This is the result in Chrome on a OSX Sierra:
The problem is that your SVG is getting scaled down. The grey line in your SVG has a width of one unit, which is not necessarily the same as 1 pixel.
It looks like you are scaling the SVG down to 44 pixels or so, so that grey line is ending up with a width of 1 * 44/128 = 0.34. So antialiasing will mean that it will get draw at about a third the darkness of the border lines.
You have a number of solution, including...
Make your line darker to compensate. It'd probably need to be #444 or so.
Or make your line thicker to compensate. Roughly 3x as thick.
Or use vector-effect: non-scaling-stroke;, so that the line width does not scale.
svg {
width: 44px;
border: solid 1px #ccc;
border-left: none;
}
line {
vector-effect: non-scaling-stroke;
}
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
<g>
<line x1="10" y1="10" x2="10" y2="117" stroke-width="1" stroke="#ccc"/>
<path fill="#00305e" d="M95.0603,45.0773l1.9872,2.025c1.9246,1.9611,1.906,5.1078-0.0415,7.0461L68.0522,82.9645
c-1.9507,1.9414-5.1035,1.9414-7.0542,0L32.0442,54.1483c-1.9475-1.9383-1.9661-5.0849-0.0415-7.0461l1.9872-2.025
c1.947-1.984,5.1386-1.9991,7.1042-0.0334l23.431,23.431l23.431-23.431C89.9218,43.0782,93.1133,43.0933,95.0603,45.0773z"/>
</g>
</svg>

Transparent background for SVG

I am working with SVGs, and would like to create one with a transparent background. The following example, should appear as just a white circle with a path in it. However, the whole 300px white canvas appears as a square, how do I get the result I want, as I can't really see where the canvas is defined?
<?xml version="1.0"?>
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" height="300" width="300" version="1.1" xml:space="preserve">
<circle fill="#FFFFFF" cx="150.267" cy="149.854" r="111.303" fill-opacity="1"/>
<g transform="translate(0.000000,632.000000) scale(0.100000,-0.100000)" fill-opacity="1">
<path fill="#54534A" d="M2204.344,4414.691v-122.67h81.643h81.642l-1.237,6.804c-0.619,3.505-1.649,10.515-2.474,15.462l-1.443,8.659
h-61.438h-61.644v38.141v38.141h54.635h54.635v16.493v16.494h-54.635h-54.635v36.079v36.08h60.613h60.407l1.443,10.515
c0.825,5.979,2.062,13.401,2.68,16.493l1.237,5.979h-80.818h-80.612V4414.691z"/>
<!-- Other paths omitted -->
</g>
</svg>
Appears as a 300 x 300px rectangle with a transparent background here with a smaller white circle inside and the letter E(path).
You sure you're not giving the svg element a white background with CSS by accident?
The canvas is the <svg> element itself, you can change its background using CSS:
svg {
background: red;
}

Center Arrows Vertically On Both Sides of Div

I've got two items I can't figure out. I'm trying to center both arrows shown in the image on either side of the div box (no matter what the height, they are always centered). The box is min-height and I need the arrows to be centered depending on the height of the box.
Also, when the media screen kicks in, I want them to always display on the left and right no matter where the user has scrolled. I don't have a clue how to keep them in place when the user scrolls.
Any help you can provide is appreciated.
CSS
#recout{
text-align:center;
width: 80%;
margin: 0 auto;
text-align: center;
}
.recleft,
.recright{
display: inline-block;
width: 50px;
min-height: 550px;
margin: 5px;
}
.recin{
background: #000000;
display: inline-block;
vertical-align:top;
min-height: 550px;
margin: 0;
width: 550px;
border-radius: 70px 70px 0 0;
}
HTML
<div id= "recout">
<div class= "recleft">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve">
<circle fill="#9FA1A4" cx="25" cy="25" r="25"/>
<g>
<g>
<path fill="#FFFFFF" d="M31.2,8.4c1,0,2,0.4,2.8,1c0.9,0.7,1.4,1.8,1.4,2.9c0,1.1-0.5,2.2-1.4,2.9l-11.8,10l11.8,10
c0.9,0.7,1.4,1.8,1.4,2.9s-0.5,2.1-1.4,2.9c-1.5,1.3-4,1.3-5.5,0L13.2,28.1c-0.9-0.7-1.4-1.8-1.4-2.9c0-1.1,0.5-2.1,1.4-2.9
L28.4,9.4C29.2,8.8,30.2,8.4,31.2,8.4z"/>
</g>
</g>
</svg>
</div>
<div class= "recin"></div>
<div class= "recright">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve">
<circle fill="#9FA1A4" cx="25" cy="25" r="25"/>
<g>
<g>
<path fill="#FFFFFF" d="M20,42c-1,0-2-0.4-2.8-1c-0.9-0.7-1.4-1.8-1.4-2.9c0-1.1,0.5-2.2,1.4-2.9l11.8-10l-11.8-10
c-0.9-0.7-1.4-1.8-1.4-2.9s0.5-2.1,1.4-2.9c1.5-1.3,4-1.3,5.5,0L38,22.3c0.9,0.7,1.4,1.8,1.4,2.9c0,1.1-0.5,2.1-1.4,2.9L22.7,41
C22,41.7,21,42,20,42z"/>
</g>
</g>
</svg>
</div>
If I understand you right you want the svg to be vertically centerd inside the .recleft and .recright respectively.
To do that use position: absolute on a wrapper around the svg (it looks weird when applying it directly to the svg), set top: 50%, this will center the div, and finally apply position: relative to the parent so that the wrapper div is absolutely positioned relative to this parent. See this JSFiddle
For the problem with the mobile view you would need to set position: fixed; like so: https://jsfiddle.net/m9xqnh8y/1/
And for the problem that if the .recin gains in height. I made a flexbox containing recleft, recin and recright, this way the other divs automatically take up the full height and thus the arrows also remain in the middle. See here

Understanding svg's viewbox attribute

I am trying to use Turkey's map which was created before here.
I have changed the dimensions of svg element
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve"
width="800"
height="600"
style="shape-rendering:geometricPrecision;
text-rendering:geometricPrecision;
image-rendering:optimizeQuality;
fill-rule:evenodd;
clip-rule:evenodd"
viewBox="0 0 180 180">
When I change viewBox values to
viewBox="0 0 200 200"
the map is rendered in smaller size.
If I set the values to "0 0 10 10" image is not displayed.
If I set the values to "0 0 50 50" a huge image comes overflowing the page
If I set the values to "0 0 100 100" image is fine.
But I don't understand how it is working.
An SVG canvas is basically an endless plain, where you can put all your objects in.
The width and height you define the size of the image as shown in the browser. This works pretty much like with any other image you can include in HTML.
With the viewBox attribute on the other hand you select the part of that plain, you currently want to view.
So with a value of "0 0 10 10" you set the upper left point of the shown image to the point 0/0 and from there select 10 units to the right and bottom for your image. In your example in those upper 10 times 10 units area there is nothing, hence you see just a transparent area, which you perceive as "not being displayed".
With a value of "0 0 50 50" the shown area gets bigger and you'll start to see the upper left corner of the picture. The first parts of the map become visible.
Finally with "0 0 100 100" you can see pretty much half of the upper map.
The area you select using viewBox is the scaled to the height and width of the SVG element. With both combined you can enabled stuff like zooming into an SVG.
You can control the scaling with the attribute preserveAspectRatio.
You can add the following code at the bottom of the SVG file and see the displayed boxes (make sure to set the viewBox="0 0 180 180" before):
<rect x="0" y="0" width="100" height="100" style="stroke: blue; stroke-width: 1; fill: white; opacity: 0.8" />
<rect x="0" y="0" width="50" height="50" style="stroke: green; stroke-width: 1; fill: none;" />
<rect x="0" y="0" width="10" height="10" style="stroke: red; stroke-width: 1; fill: none;" />
<text x="5" y="97" style="fill: blue; font-size: 5px;">100x100</text>
<text x="5" y="47" style="fill: green; font-size: 5px;">50x50</text>
<text x="5" y="15" style="fill: red; font-size: 5px;">10x10</text>
So to conclude the purpose of viewBox is to select that part of the endless SVG plane, that should actually be rendered. If you choose the wrong values here, you might just see an empty space.
Links:
preserveAspectRatio #MDN
viewBox #MDN
Viewbox with the width and height values are how you can do zooming, and panning with SVG.
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve"
width="800"
height="600"
viewBox="0 0 800 600">
no scaling 800 pixels width in the viewbox equals 800 pixel width on the screen
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve"
width="800"
height="600"
viewBox="0 0 1600 1200">
Everything is scaled down so that a line 1600 pixels wide only shows up as 800 pixels wide.
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve"
width="800"
height="600"
viewBox="400 300 400 300">
Zoom into the bottom right hand 1/4 of the 800 by 600 screen making that portion fill the entire svg, don't show anything above the 300 pixel line or to the left of the 400 pixel line.

Inline SVG breaks in Safari and Mobile Safari

I recently launched a site which used a bit of inline SVG.
<svg class="divider-icon" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 55.221 58.079" enable-background="new 0 0 55.221 58.079" xml:space="preserve" preserveAspectRatio="xMidYMid meet">
<path d="[...]"/>
</svg>
Everything was perfect in Chrome and Firefox, but when I tested on an iPhone or in desktop Safari, the layout was completely broken and many of the SVGs were missing. I ran the source through the W3C validator and everything was find. I work with SVG a lot, so this was very confusing...
It turns out that Safari and Mobile Safari freak out if you omit the height and width attributes I was setting the dimensions with CSS, which worked fine in other browsers. But I had to add those attributes back in to make it behave consistently:
<svg class="divider-icon" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="55.221px" height="58.079px" viewBox="0 0 55.221 58.079" enable-background="new 0 0 55.221 58.079" xml:space="preserve" preserveAspectRatio="xMidYMid meet">
<path d="[...]"/>
</svg>
Notice the width and height attributes that were missing above.
Also, it's interesting to point out that the value of preserveAspectRatio matters. I had a couple other inline SVG elements that had preserveAspectRatio="none meet" and they were unaffected by this issue.
Another scenario / fix for this is if you're scaling your SVG via CSS, to make sure that you have both max-width and max-height declared.
.whatever svg {
vertical-align: middle;
max-height: 1rem;
max-width: 1rem;
}

Resources