8.1 Patterns

To use a pattern, you define a graphic object that is replicated horizontally and vertically to fill another object (or stroke). This graphic object is called a tile, because the act of filling an object with a pattern is very much like covering an area of a floor with tile.

Example of a tile

<svg width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
    <!-- quadratic curves smoothly connected -->
    <path d="M 0 0 Q 5 20 10 10 T 20 20"
    style="fill:none; stroke:black;"/>
    <!-- square frame -->
    <path d=" M 0 0 h 20 v 20 h -10 Z" style="
    fill:none; stroke:gray;"/>
</svg>

7.1.1 Pattern and PatternUnits

To create a pattern tile, you must enclose the path elements that describe your tile in a pattern element, and then make several decisions. The first decision is how you wish to space the tiles, and this is reflected in the patternUnits attribute, which can be
patternUnits="objectBoundingBox" or patternUnits="userSpaceOnUse".

Example 1. A pattern with width="20%" height="20%" and with default patternUnits="objectBoundingBox"

 <svg width="200" height="400" viewBox="0 0 200 400" xmlns="http://www.w3.org/2000/svg">
    <defs>
        <pattern id="tile" x="0" y="0" width="20%" height="20%" patternUnits="objectBoundingBox">
            <!-- quadratic curves smoothly connected -->
            <path d="M 0 0 Q 5 20 10 10 T 20 20"
            style="fill:none; stroke:black;"/>
            <!-- square frame -->
            <path d=" M 0 0 h 20 v 20 h -20 z" style="
            fill:none; stroke:gray;"/>
        </pattern>
    </defs>
    <rect x="20" y="20" width="100" height="100" style="fill:url(#tile); stroke:black"/>
    <rect x="20" y="130" width="70" height="80" style="fill: url(#tile); stroke: black;"/>
    <rect x="20" y="220" width="150" height="130" style="fill: url(#tile); stroke: black;"/>
</svg>

Example 2. A pattern with user units x="0" y="0" width="20" height="20" and patternUnits="userSpaceOnUse"

To put tiles directly next to one another to fill the area, no matter what its size, without extra padding between tiles, and tiles are cut off only by the edge of the object they're filling you must:

 <svg width="200" height="400" viewBox="0 0 200 400" xmlns="http://www.w3.org/2000/svg">
    <defs>
        <pattern id="tile2" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
            <!-- quadratic curves smoothly connected -->
            <path d="M 0 0 Q 5 20 10 10 T 20 20"
            style="fill:none; stroke:black;"/>
            <!-- square frame -->
            <path d=" M 0 0 h 20 v 20 h -20 z" style="
            fill:none; stroke:gray;"/>
        </pattern>
    </defs>
    <rect x="20" y="20" width="100" height="100" style="fill:url(#tile2); stroke:black"/>
    <rect x="20" y="130" width="70" height="80" style="fill: url(#tile2); stroke: black;"/>
    <rect x="20" y="220" width="150" height="130" style="fill: url(#tile2); stroke: black;"/>
</svg>

7.1.2 Pattern and patternContentsUnits

The patternContentUnits attribute is assigned to units that are to be used to express the pattern data itself.
  1. By default patternContent Units = "userSpaceOnUse"
  2. If you set the patternContent Units = "objectBoundingBox", the path data points are expressed in terms of the object being filled. In this case you should draw any objects to be filled with upper left corner of this bounding boxes at the origin (0,0). Also reduce the stroke-width of the pattern data to 0.01, since these units are percentages, not user units.

Example 1 where patternContentUnits = "objectBoundingBox"

<svg width="190" height="380" viewBox="0 0 190 380" xmlns="http://www.w3.org/2000/svg">
 <defs>
     <pattern id="tile3"
              patternUnits="objectBoundingBox"
              patternContentUnits="objectBoundingBox"
              x="0" y="0" width="0.20" height="0.20">
              <path d="M 0 0 Q 0.05 0.20 0.10 0.10 T 0.20 0.20" style="fill:none; stroke:black; stroke-width:0.01;"/>
              <path d="M 0 0 h 0.20 v0.20 h -0.20 z" style="fill:none; stroke:black; stroke-width:0.01;"/>
     </pattern>
 </defs>
 <g transform="translate(20,20)">
     <rect x="0" y="0" width="100" height="100" style="fill:url(#tile3); stroke:black;"/>
 </g>
 <g transform="translate(20,140)">
     <rect x="0" y="0" width="70" height="80" style="fill:url(#tile3); stroke:black;"/>
 </g>
 <g transform="translate(20,230)">
     <rect x="0" y="0" width="150" height="130" style="fill:url(#tile3); stroke:black;"/>
 </g>

Using viewBox for defining a pattern

Example 2. Using viewBox to scale pattern

 <svg width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
            <defs>
        <pattern id="tile4"
                 patternUnits="userSpaceOnUse"
                 patternContentUnits="userSpaceOnUse"
                 x="0" y="0" width="20" height="20" viewbox="0 0 150 150">
                 <path d="M 30 100 C 50 50 70 20 100 100 110 130 50 150 60 100" style="fill:none; stroke:green; stroke-width:5;"/>
        </pattern>
    </defs>
    <rect x="20" y="20" width="100" height="100" style="fill:url(#tile4); stroke:black;"/>
</svg>

7.1.3 Nested Patterns

Example 3. Nested patterns

<svg width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
            <defs>
         <pattern id="stripe"
                  patternUnits="userSpaceOnUse"
                  x="0" y="0" width="6" height="6">
                  <path d="M 0 0 6 0" style="fill:none; stroke:black;"/>
         </pattern>
         <pattern id="polkadot"
                  patternUnits="userSpaceOnUse"
                  x="0" y="0" width="36" height="36">
                  <circle cx="12" cy="12" r="12" style="fill:url(#stripe); stroke:black;"/>
         </pattern>
     </defs>
     <rect x="36" y="36" width="96" height="96" style="fill:url(#polkadot); stroke:black;"/>
 </svg>