Rounded rectangle with stroke -- svg quality compared to div - svg

I understand that there is a different render process, but why is the stroke so funky on rounded rectangles compared to a rounded div with a border?
body {
background: #1a1a1a;
display: flex;
justify-content: center;
padding-top: 50px;
}
.svg-square {
fill: #75604A;
stroke: white;
stroke-width: 1px;
}
.div-square {
background-color: #75604A;
margin-left: 10px;
width: 60px;
height: 60px;
border: 1px solid white;
border-radius: 10px;
}
span {
display: block;
margin: 20px;
color: white;
}
<span>svg</span>
<svg width="60" height="60">
<rect class="svg-square" width="60" height="60" rx="10" />
</svg>
<div class="div-square"></div>
<span>div</span>
FIDDLE: https://codepen.io/kirkbross/pen/gEGGvx
It seems like it's a half pixel stroke on the svg and even when I increase it to 2, the sides seem thinner than the top and bottom.
I want to understand the physics here. This example is an svg with a stroke of 1. These corners seem janky compared to a div with a border.

Well part of it is that you're cutting off half the stroke-width because your rect is exactly the size of your svg element. Look at:
<rect x="1" y="1" class="svg-square" width="58" height="58" rx="10" />
Still not as good at rounded corners as CSS drawing - but much more reasonable.

Related

Hover on nested elements using SASS and BEM

I try to use hover for button element and for SVG within button. But in here piece of code https://codepen.io/asssel/pen/wvrojOd It doesn't work for SVG. Help me how to implement it.
.tag {
width: 120px;
padding: 6px 12px;
border: 1px solid #1F1F1F;
border-radius: 18px;
cursor: pointer;
color: #1F1F1F;
background-color: white;
&_label {
font-size: 12px;
line-height: 12px;
letter-spacing: 1.2px;
text-transform: uppercase;
}
&_remove {
border: none;
background-color: transparent;
}
&:hover, &_icon path {
background-color: #1F1F1F;
color: white;
stroke: white;
}
}
<div class='tag'>
<span class='tag_label'>default tag</span>
<button class='tag_remove'>
<svg class='tag_icon' width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.5 1.5L1.5 8.5M8.5 8.5L1.5 1.5" stroke="#404040" stroke-width="2" stroke-linecap="square"/>
</svg>
</button>
</div>
First of all I changed your CSS to plain CSS to make it work in the snippet.
I guess that the main problem is the hover effect. To change the stroke of the <path> your CSS selector need to start from the element that is hovered. So, replace &_icon path with &:hover &_icon path.
And then you also make sure that you use fill and stroke properties for SVG elements.
.tag {
width: 120px;
padding: 6px 12px;
border: 1px solid #1F1F1F;
border-radius: 18px;
cursor: pointer;
color: #1F1F1F;
background-color: white;
display: flex;
align-items: center;
}
.tag_label {
font-size: 12px;
letter-spacing: 1.2px;
text-transform: uppercase;
white-space: nowrap;
}
.tag_icon path {
stroke: #1F1F1F;
}
.tag_remove {
border: none;
background-color: transparent;
}
.tag:hover,
.tag:hover .tag_icon path {
background-color: #1F1F1F;
color: white;
stroke: white;
}
<div class='tag'>
<span class='tag_label'>default tag</span>
<button class='tag_remove'>
<svg class='tag_icon' width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.5 1.5L1.5 8.5M8.5 8.5L1.5 1.5" stroke-width="2" stroke-linecap="square"/>
</svg>
</button>
</div>

SVG - stroke-dasharray with percentage units doesn't work as expected

I think I don't quite understand something here.
Percentage units in stroke-dasharray are realtive to what? I was thinking relative to the SVG viewbox, but I was probably wrong.
My problem:
I have an SVG with the width of 320px and the height of 160px.
In this SVG I draw a line from x1 = "0%" to x2 = "100%", so it has a width of 320px just like the SVG.
Then I give the line: stroke-dasharray: 100% 100%;
For me it is surprising that the line is not drawn with the full width of the SVG, but only about 80%.
I think I don't quite understand something here.
Pronounced units in stroke-dasharray are realtive to what? I was thinking relative to the SVG viewbox, but I was probably wrong.
My problem:
I have an SVG with the width of 320px and the height of 160px.
In this SVG I draw a line from x1 = "0%" to x2 = "100%", so it has a width of 320px just like the SVG.
Then I give the line: stroke-dasharray: 100% 100%;
For me it is surprising that the line is not drawn with the full width of the SVG, but only about 80%.
If someone has an idea, I would be happy to hear from you
Here the link to an example: https://codepen.io/stefka1210/pen/xxVwBom
html, body {
width: 100%;
height: 100%;
}
body {
display: flex;
align-items: center;
justify-content: center;
}
.container {
width: 320px;
height: 160px;
background: lightgrey;
}
svg {
width: 100%;
height: 100%;
}
line {
stroke-width: 2px;
}
#one {
stroke-dasharray: 100% 100%;
stroke: red;
}
#two {
stroke-dasharray: 320px 320px;
stroke: green;
}
<html>
<body>
<div class="container">
<svg x="0px" y="0px" viewBox="0 0 320 160" xmlns="http://www.w3.org/2000/svg">
<g>
<line id="one" x1="0%" y1="40%" x2="100%" y2="40%"></line>
<line id="two" x1="0%" y1="60%" x2="100%" y2="60%"></line>
</g>
</svg>
</div>
</body>
</html>
Since a line can go in any direction, it would not make sense to link "percentage of the viewport" to either its width or height. Instead, 100% is set to the root mean square of width and height:
For width = 320 and height = 160, that gives a length of 252.98.

Clip-Path vs Border-Radius issue when window is resized

I want to use an SVG as a clip-path to round the edges of an image. Yes, I must do it in this way for various reasons .
PROBLEM:
When the browser window is resized, the points and handles that form the rounded corners adjust to the changing size of the image (bounding box) because I'm using clipPathUnits="ObjectBoundingBox". This causes the rounded edges to loose their "roundness" and look overall really bad. The CSS border-radius property doesn't have this issue. No matter how you resize the browser window, the edges of a div clipped with border-radius never loose their round shape. The problem is most apparent when you resize the browser window to it's most narrow or widest possible state. Try that with this codepen and you'll see what I mean. The top image uses border-radius and the bottom image uses clip-path. Is there any way to force the ONLY rounded edges of the SVG clip-path to stay equally rounded no matter how the image is resized without sacrificing the responsiveness of the clip-path dimensions? Is this even possible? I'm totally open to a JavaScript solution if there is one. Thanks!
You can trick the <svg> element to have just the same dimensions as the image and then size the clip-path with relative units. The downside is that you cannot reuse these paths but have to define one for every individual image.
.box {
left: 5%;
height: 40%;
position: absolute;
background-color: blue;
overflow: hidden;
}
#box1 {
top: 5%;
width: 50%;
clip-path: url(#clipPath1);
}
#box2 {
top: 55%;
width: 90%;
clip-path: url(#clipPath2);
}
.flower{
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
}
svg {
width: 100%;
height: 100%;
position: absolute;
}
<div class="box" id="box1">
<img class="flower" src="https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500" alt="none">
<svg>
<clipPath id="clipPath1" clipPathUnits="userSpaceOnUse">
<rect width="100%" height="100%" rx="20" ry="20"/>
</clipPath>
</svg>
</div>
<div class="box" id="box2">
<img class="flower" src="https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500" alt="none">
<svg>
<clipPath id="clipPath2" clipPathUnits="userSpaceOnUse">
<rect width="100%" height="100%" rx="20" ry="20"/>
</clipPath>
</svg>
</div>

svg image not working in safari 5.1.7 (windows)

svg image not working in safari 5.1.7 (windows) . But when i open the svg image in safari and then visit the site, the image is displayed there.
Safari on Windows has known issues calculating the height of responsive inline SVGs.
You might try the intrinsic ratio technique, whereby you position the <svg> tag absolutely inside an <object> tag with bottom padding equal to the ratio of the viewBox (or height/width attributes) of the svg.
.my-responsive-svg {
width: 100%;
display: block;
height: auto;
position: relative;
/* for an svg with a 16:9 aspect ratio */
padding-top: 56.25%;
}
.my-responsive-svg svg {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
right: 0;
}
<object class="my-responsive-svg">
<svg width="160" height="90" viewBox="0 0 160 90">
<rect x="10" y="10" width="140" height="70" />
</svg>
</object>
Source: Hat tip to Sérgio Lopes who commented on this blog post.

SVG scales down to fit small screen height, why?

I have a simple SVG in a web page, and I'd like the SVG to be responsive to width only. The problem is, it scales down also when the screen height is less than the SVG height.
HTML:
<div class="container">
<svg version="1.1" width="100%" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500" preserveAspectRatio="xMinYMin">
<circle stroke="#000" stroke-width="10" fill="transparent" cx="250" cy="250" r="200"/>
</svg>
</div>
CSS:
svg {
max-height: 100%;
}
.container {
width:50%;
border: 1px solid black;
}
Here is the jsfiddle, where you can see the circle radius decreases when the window height is reduced. How can this be avoided ?
Thanks !
Here is what I wanted to achieve, sorry if my question wasn't clear enough:
width of the SVG depending only on the width left available to the container,
(width / height) ratio of the SVG preserved at all time,
container's height depending only on the width of the SVG and its (width / height) ratio.
I got it working this way:
HTML & SVG:
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 500 400" preserveAspectRatio="xMinYMin">
<circle fill="#F7941E" stroke="#231F20" stroke-width="10" cx="250" cy="200" r="150"/>
</svg>
</div>
<hr>
CSS:
.container {
position: relative;
width:50%;
padding-bottom: 40%;
border: 1px solid black;
}
svg {
position: absolute;
top: 0;
left: 0;
max-height: 100%;
}
Fiddle here
The only drawback I see is that the padding-bottom of the container needs to be defined, and to a value matching the w/h ratio of the SVG, which is redundant.
If what you want is for the circle to remain the same size even when the window size changes, then just get rid of the viewBox. Try removing : viewBox="0 0 500 500" preserveAspectRatio="xMinYMin" from the opening svg tag.
The default for height (like width) is 100%. Which means 100% of it's container height.
One solution is to give the container a very large height.
.container {
width:50%;
height: 9999px;
border: 1px solid black;
}
Fiddle here
You don't really say what you want to happen to the lower parts of the circle when the height scales up. If you want it to be hidden off the bottom of the div container, then you could do something like this:
svg {
height: 9999px;
}
.container {
width:50%;
height: 300px;
overflow: hidden;
border: 1px solid black;
}
Fiddle here

Resources