svgstroke

How to color SVG pattern when using `use`


I expect three diagonal stripe rectangles colored with red, green, yellow respectively, but it draws empty rectangles that colored only the border.

<svg width="100%" viewBox="0,0,100,100" >
  <defs>
    <pattern id="strip" viewBox="0,0,1,1"
      width=".25" height=".5"
      stroke-width="0.1"
    >
      <path d="M0,0 l1,1" />
    </pattern>
    
    <symbol id="stripe-rect">
      <rect x="0" y="0" width="100%" height="100%" fill="url(#strip)" />  
    </symbol>
  </defs>

  <use href="#stripe-rect" width="50" height="25" stroke="red" />
  <use href="#stripe-rect" y=30 width="50" height="25" stroke="green" />
  <use href="#stripe-rect" y=60 width="50" height="25" stroke="yellow" />
</svg>

Solution

  • You can use the pattern on a mask, and use the mask on a rectangle. The rectangle is in a group that makes up the "symbol" with both fill and a stroke.

    <svg width="100%" viewBox="0 0 100 100">
      <defs>
        <pattern id="strip" viewBox="0 0 1 1"
          width="1%" height="1%"
          stroke-width=".1">
          <path d="M0 0 l1 1" stroke="white"/>
        </pattern>
        <g id="stripe-rect" transform="translate(.5 .5)">
          <rect width="50" height="24" mask="url(#m1)"/>
          <rect width="50" height="24" fill="none" stroke-width="1" />
        </g>
        <mask id="m1">
          <rect width="100%" height="100%" fill="url(#strip)" />
        </mask>
      </defs>
      <use href="#stripe-rect" x="0" y="0" fill="red" stroke="red" />
      <use href="#stripe-rect" x="0" y="25" fill="green" stroke="green" />
      <use href="#stripe-rect" x="0" y="50" fill="yellow" stroke="yellow" />
    </svg>

    Btw. you pattern/the strip is not a "full" line. In the following example you can see the difference between you pattern (red) and a pattern (green) where the line is looks more like a line:

    <svg viewBox="0 0 100 50">
      <defs>
        <pattern id="strip" viewBox="0 0 1 1"
          width="30%" height="30%"
          stroke-width=".1">
          <path d="M0 0 l1 1" stroke="red" />
        </pattern>
        <pattern id="strip2" viewBox="0 0 1 1"
          width="30%" height="30%"
          stroke-width=".1">
          <path d="M1 0 l1 1 M0 0 l1 1 M0 1 l1 1"
            stroke="green" stroke-linecap="square"/>
          <!-- slightly shorter path, but does not start in the corner -->
          <!--<path d="M.5 0 l.5 .5 M0 .5 l.5 .5"
            stroke="green" stroke-linecap="square"/>-->
        </pattern>
      </defs>
      <rect width="50" height="50" fill="url(#strip)"/>
      <rect width="50" height="50" x="50" fill="url(#strip2)"/>
    </svg>