107

Setting a stroke-width: 1 on a <rect> element in SVG places a stroke on every side of the rectangle.

How does one place a stroke width on only three sides of an SVG rectangle?

TylerH
  • 20,799
  • 66
  • 75
  • 101
user782860
  • 2,689
  • 5
  • 18
  • 15

3 Answers3

181

If you need stroke or no-stroke then you can also use stroke-dasharray to do this, by making the dashes and gaps match up with the sides of the rectangle.

rect { fill: none; stroke: black; }
.top { stroke-dasharray: 0,50,150 }
.left { stroke-dasharray: 150,50 }
.bottom { stroke-dasharray: 100,50 }
.right { stroke-dasharray: 50,50,100 }
<svg height="300">
    <rect x="0.5" y="0.5" width="50" height="50" class="top"/>
    <rect x="0.5" y="60.5" width="50" height="50" class="left"/>
    <rect x="0.5" y="120.5" width="50" height="50" class="bottom"/>
    <rect x="0.5" y="180.5" width="50" height="50" class="right"/>
</svg>

See jsfiddle.

Erik Dahlström
  • 59,452
  • 12
  • 120
  • 139
  • How can we show the stroke only on top of the rect element ? – Suresh Aug 22 '18 at 07:48
  • 2
    Could you explain why certain numbers in certain positions give this effect? – JacobIRR Apr 30 '19 at 17:42
  • @JacobIRR refer to the definition of the 'stroke-dasharray' property (linked in the answer). The idea here is to match the dash lengths to the sides of the rectangle, and the dash gap with the side that should have no stroke. – Erik Dahlström May 06 '19 at 13:49
  • I just updated your solution , in this link https://codepen.io/shaswatatripathy/pen/oNgPpyd – tripathy Jan 16 '20 at 16:25
  • Here's a programmatic solution that generates `stroke-dasharray` given an object defining which borders should be shown. Reading the code might help you understand how it works: https://codepen.io/lazd/pen/WNweNwy?editors=1010 – lazd Aug 02 '20 at 20:14
  • You can stroke just the top by setting a dasharray of top, right+bottom+left. You can stroke just the left (for example) by setting a dasharray of 0 (draw nothing), top+right+bottom, left. In other words, the first number draws, the second number skips drawing, the next draws, etc. Playing with the jsfiddle helped me get just what I wanted (a left border). – moodboom Jan 26 '23 at 20:17
37

You cannot change the visual style of various parts of a single shape in SVG (absence the not-yet-available Vector Effects module). Instead, you will need to create separate shapes for each stroke or other visual style that you want to vary.

Specifically for this case, instead of using a <rect> or <polygon> element you can create a <path> or <polyline> that only covers three sides of the rectangle:

<!-- Move to 50,50 then draw a line to 150,50, to 150,150, and then to 50,150 -->
<path d="M50,50 L150,50 150,150 50,150" />
<polyline points="50,50 150,50 150,150 50,150" />

You can see the effect of these in action here: http://jsfiddle.net/b5FrF/3/

Red square with stroke on three sides

For more information, read about the <polyline> and more-powerful-but-more-confusing <path> shapes.

Phrogz
  • 296,393
  • 112
  • 651
  • 745
2

You could use a polyline for the three stroked sides, and just not put the stroke on the rectangle at all. I don't think SVG lets you apply different strokes to different parts of a path/shape, so you need to use multiple objects to get the same effect.

wdebeaum
  • 4,101
  • 1
  • 22
  • 12