How to Set a Stroke-Width:1 on Only Certain Sides of Svg Shapes

Stroke left and right side of rect svg

It's another hack, but you can add a filter to your shape and clip the top and bottom by your strokewidth - which here I'm assuming is 1 unit.

<defs>
<filter id="clippy" x="0" y="1" height="248" width="356">
<feColorMatrix type="identity"/>
</filter>
</defs>
<rect filter="url(#clippy)" class="extent" width="356" height="250"
style="cursor: move;opacity: 0.2; fill: #FF9000;" x="578"></rect>

Update:

Here is the d3.js version of the answer created by Christopher Chiche (see original lower down):

svg.append("defs").append("filter")
.attr("id", "clippy")
.attr("x", "0")
.attr("y", "1")
.attr("height", "248")
.attr("width" "356")
.append("feColorMatrix")
.attr("type", "identity")

svg.append("rect")
.attr("filter", "url(#clippy)")
.attr("class", "extent")
.attr("style", "cursor:move; opacity:0.2; fill: #FF9000")
.attr("x", "578")
.attr("height", "250")
.attr("width" "356")

Why does a CSS svg rect / have a thicker stroke on the right and bottom sides?

What you encounter is indeed a case of surprising sub-pixel rendering. You see, SVG strokes are applied exactly on the path where they are specified. Example: If a path runs from the point (0,0) to (0,5) and is assigned a 1px wide stroke, the stroke covers the rectangle (-0.5,0), (0.5,0), (0.5,5), (-0.5,5). The first one of these images illustrates this: illustration of strokes from SVG spec

Your rectangle is drawn from (0,0) (the default position) to (36,36). Therefore the stroke is placed in such a way, that it lies exactly between the screen pixels. That’s the reason for the right and bottom edges to look blurry.

What’s up with the top and left edges? Well, since you didn’t define a size for your SVG image, the browser determined one for you. The default is to start at (0,0) (top-left corner) and make the SVG 300x150 pixels wide.

Since the top and left edges of the rectangle outline are directly on the edge of the image, they still are drawn blurry, but you don’t see the part outside the image. Hence it appears to be a sharp line, but if you look closely, you notice, that it is not fully black, but half transparent.

How to fix this? There are two options. Option 1 is to place the rectangular on half pixels:

<rect x="0.5" y="0.5" .../>

The other option is to move the viewport of your image around, so that the image as a whole is shifted for half a pixel:

<svg viewBox="-0.5 -0.5 37 37">

Note, that I’ve set width and height of the viewport to 37px. That’s because your rectangle will have a final size of 37px: 36px for the outline, and then 0.5px on every side, where the outer half of the 1px stroke rests.

For a general overview on scaling SVGs I suggest this post on CSS Tricks.

HTML SVG Stroke wider at edges

The edges of your shape consincide with the ouside boundary of your SVG. Strokes are drawn so that half their width is on either side of the line.

So whats happening is that half of the top, left and bottom lines are cut off because they are outside of the SVG.

Some solutions would be:

  1. Move your lines inside the SVG by half the stroke width.
  2. Add a viewBox that is half the stroke width bigger than your shape. This will have the effect of scaling down your shape so that all the stroke is drawn.
  3. Add overflow="visible" to your SVG so that that the parts of your shape that are outside the SVG are drawn, and not clipped (as suggested by @enxaneta)


Related Topics



Leave a reply



Submit