0

The following SVG does not display as I expect it to.

The brief description/ intent is:

  • I create a symbol which is a large square comprised of smaller rectangles
  • I then create "slices" of this large square in smaller symbols using viewBox and preserveAspectRatio
  • I then display some of these symbols with <use>

The problem is that the "sliced" symbols which touch the right or bottom edge are not full sized, and instead appear as small slivers.

How can I fix this?

What it looks like (click for full image):

symbol-sliced

Interestingly, if I change the main <symbol> to a <g> instead, I get a very different looking result, which suffers from the same problem

group-sliced

What it should look like (click for full image):

symbol-whole


Files available at this gist, also copied below for your convenience.

This illustrates the problem:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <symbol id="box">
        <!--top left-->
        <rect x="0" y="0" height="100" width="100"
          style="fill:#0000ff" />
        <!--top middle-->
        <rect x="100" y="0" height="100" width="300"
          style="fill:#008888" />
        <!--top right-->
        <rect x="400" y="0" height="100" width="100"
          style="fill:#00ff00" />
        <!--middle left-->
        <rect x="0" y="100" height="300" width="100"
          style="fill:#888800" />
        <!--middle middle-->
        <rect x="100" y="100" height="300" width="300"
          style="fill:#2a2a2a" />
        <!--middle right-->
        <rect x="400" y="100" height="300" width="100"
          style="fill:#ff0000" />
        <!--bottom left-->
        <rect x="0" y="400" height="100" width="100"
          style="fill:#000000" />
        <!--bottom middle-->
        <rect x="100" y="400" height="100" width="300"
          style="fill:#ff0088" />
        <!--bottom right-->
        <rect x="400" y="400" height="100" width="100"
          style="fill:#8800ff" />
    </symbol>
    <symbol id="box-top-left" viewBox="0 0 100 100" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-top-middle" viewBox="100 0 400 100" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-top-right" viewBox="400 0 500 100" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-middle-left" viewBox="0 100 100 400" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-middle-middle" viewBox="100 100 400 400" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-middle-right" viewBox="400 100 500 400" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-bottom-left" viewBox="0 400 100 500" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-bottom-middle" viewBox="100 400 400 500" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-bottom-right" viewBox="400 400 500 500" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
  </defs>

  <use xlink:href="#box-top-right" x="0" y="0" height="100" width="100" />
  <use xlink:href="#box-top-middle" x="100" y="0" height="100" width="300" />
  <use xlink:href="#box-top-middle" x="400" y="0" height="100" width="100" />

  <use xlink:href="#box-middle-right" x="0" y="100" height="300" width="100" />
  <use xlink:href="#box-middle-middle" x="100" y="100" height="300" width="300" />
  <use xlink:href="#box-middle-middle" x="400" y="100" height="300" width="100" />

  <use xlink:href="#box-bottom-right" x="0" y="400" height="100" width="100" />
  <use xlink:href="#box-bottom-middle" x="100" y="400" height="100" width="300" />
  <use xlink:href="#box-bottom-middle" x="400" y="400" height="100" width="100" />
</svg>

This is what it should look like:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <symbol id="box">
        <!--top left-->
        <rect x="0" y="0" height="100" width="100"
          style="fill:#0000ff" />
        <!--top middle-->
        <rect x="100" y="0" height="100" width="300"
          style="fill:#008888" />
        <!--top right-->
        <rect x="400" y="0" height="100" width="100"
          style="fill:#00ff00" />
        <!--middle left-->
        <rect x="0" y="100" height="300" width="100"
          style="fill:#888800" />
        <!--middle middle-->
        <rect x="100" y="100" height="300" width="300"
          style="fill:#2a2a2a" />
        <!--middle right-->
        <rect x="400" y="100" height="300" width="100"
          style="fill:#ff0000" />
        <!--bottom left-->
        <rect x="0" y="400" height="100" width="100"
          style="fill:#000000" />
        <!--bottom middle-->
        <rect x="100" y="400" height="100" width="300"
          style="fill:#ff0088" />
        <!--bottom right-->
        <rect x="400" y="400" height="100" width="100"
          style="fill:#8800ff" />
    </symbol>
    <symbol id="box-top-left" viewBox="0 0 100 100" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-top-middle" viewBox="100 0 400 100" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-top-right" viewBox="400 0 500 100" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-middle-left" viewBox="0 100 100 400" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-middle-middle" viewBox="100 100 400 400" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-middle-right" viewBox="400 100 500 400" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-bottom-left" viewBox="0 400 100 500" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-bottom-middle" viewBox="100 400 400 500" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-bottom-right" viewBox="400 400 500 500" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
  </defs>

  <use xlink:href="#box" x="0" y="0" height="500" width="500" />
</svg>
bguiz
  • 27,371
  • 47
  • 154
  • 243

1 Answers1

0

Solution found. My error was in not using the viewBox attribute in a <symbol> correctly.

  • It should be viewBox="minX minY width height"
  • Instead of viewBox="minx minY maxX maxY"

The working SVG is (click for full size):

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <g id="box">
        <!--top left-->
        <rect x="0" y="0" height="100" width="100"
          style="fill:#0000ff" />
        <!--top middle-->
        <rect x="100" y="0" height="100" width="300"
          style="fill:#008888" />
        <!--top right-->
        <rect x="400" y="0" height="100" width="100"
          style="fill:#00ff00" />
        <!--middle left-->
        <rect x="0" y="100" height="300" width="100"
          style="fill:#888800" />
        <!--middle middle-->
        <rect x="100" y="100" height="300" width="300"
          style="fill:#2a2a2a" />
        <!--middle right-->
        <rect x="400" y="100" height="300" width="100"
          style="fill:#ff0000" />
        <!--bottom left-->
        <rect x="0" y="400" height="100" width="100"
          style="fill:#000000" />
        <!--bottom middle-->
        <rect x="100" y="400" height="100" width="300"
          style="fill:#ff0088" />
        <!--bottom right-->
        <rect x="400" y="400" height="100" width="100"
          style="fill:#8800ff" />
    </g>
    <symbol id="box-top-left" viewBox="0 0 100 100" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-top-middle" viewBox="100 0 300 100" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-top-right" viewBox="400 0 100 100" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-middle-left" viewBox="0 100 100 300" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-middle-middle" viewBox="100 100 300 300" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-middle-right" viewBox="400 100 100 300" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-bottom-left" viewBox="0 400 100 100" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-bottom-middle" viewBox="100 400 300 100" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
    <symbol id="box-bottom-right" viewBox="400 400 100 100" preserveAspectRatio="none">
      <use xlink:href="#box" style="overflow:none;" />
    </symbol>
  </defs>

  <use xlink:href="#box-top-left" x="0" y="0" height="100" width="100" />
  <use xlink:href="#box-top-middle" x="100" y="0" height="100" width="300" />
  <use xlink:href="#box-top-right" x="400" y="0" height="100" width="100" />

  <use xlink:href="#box-middle-left" x="0" y="100" height="300" width="100" />
  <use xlink:href="#box-middle-middle" x="100" y="100" height="300" width="300" />
  <use xlink:href="#box-middle-right" x="400" y="100" height="300" width="100" />

  <use xlink:href="#box-bottom-left" x="0" y="400" height="100" width="100" />
  <use xlink:href="#box-bottom-middle" x="100" y="400" height="100" width="300" />
  <use xlink:href="#box-bottom-right" x="400" y="400" height="100" width="100" />
</svg>
bguiz
  • 27,371
  • 47
  • 154
  • 243