Reputation: 34513
Is it possible to round a rectangle in SVG while ensuring the stroke obeys the roundedness of corners? The code below isn't working.
No Stroke:
stroke-width="0px"
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" stroke="red" stroke-width="0px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>
With Stroke:
stroke-width="10px"
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" stroke="red" stroke-width="10px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>
The stroke seems to follow the original sharp corners instead of the rounded corners.
Upvotes: 9
Views: 12895
Reputation: 14545
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" stroke="red" stroke-width="10px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>
A wide string extends beyond the svg border of the canvas SVG. Therefore, the string is partially cropped.
You must reduce the size of the rectangle so that the line is visible and shift the upper left corner of the rectangle right and down x="5"
and y="5"
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<rect x="5" y="5" width="90" height="90" stroke="red" stroke-width="10px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>
Update
ViewBox added. The coordinates of the rectangle x
andy
of the are increased, SVG wrapped in a container and can be embedded in an HTML page as a separate block. Adaptive application
.container {
width:30%;
height:30%
}
<div class="container">
<svg viewBox="0 0 110 110" xmlns="http://www.w3.org/2000/svg">
<rect x="10" y="10" width="90" height="90" stroke="red" stroke-width="10px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>
</div>
As you can see from the picture, a square with a wide stroke is completely inside the SVG canvas
Upvotes: 12
Reputation: 272965
The first trivial solution is to make the overflow visible and add some margin to rectify this
svg {
overflow:visible;
margin:5px; /*half the stroke*/
}
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" stroke="red" stroke-width="10px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>
<svg width="150" height="80" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" stroke="red" stroke-width="10px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>
<svg width="100" height="200" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" stroke="red" stroke-width="10px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>
Or you use calc()
like below:
svg rect{
height:calc(100% - 10px);
width:calc(100% - 10px);
x:5px;
y:5px;
}
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" stroke="red" stroke-width="10px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>
<svg width="150" height="80" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" stroke="red" stroke-width="10px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>
<svg width="100" height="200" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" stroke="red" stroke-width="10px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>
That can be used as background too:
.box {
background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" ><rect x="5" y="5" width="100%" height="100%" style="height:calc(100% - 10px);width:calc(100% - 10px)" stroke="red" stroke-width="10" rx="10" ry="10" stroke-linejoin="round" /></svg>');
color: #fff;
padding:25px;
display:inline-block;
margin: 75px 0;
}
<div class="box"> Some text here</div>
<div class="box"> text very loooooooooooong here</div>
<div class="box"> a text <br> two line here</div>
Upvotes: 4
Reputation: 4434
<svg width="400" height="180">
<rect x="50" y="20" rx="20" ry="20" width="150" height="150"
style="fill:red;stroke:black;stroke-width:5;opacity:0.5" />
</svg>
Upvotes: 0