SVG 2 – 09 April 2015 TopContentsPreviousNextElementsAttributesProperties

Chapter 7: Coordinate Systems, Transformations and Units

Contents

7.1. Introduction

canvas
A surface onto which graphics elements are drawn, which can be real physical media such as a display or paper or an abstract surface such as a allocated region of computer memory.
SVG canvas
The canvas onto which the SVG content is rendered.
SVG viewport
The viewport within the SVG canvas which defines the rectangular region into which SVG content is rendered. See the discussion of the SVG viewport in the chapter on Coordinate Systems, Transformations and Units.

For all media, the SVG canvas describes "the space where the SVG content is rendered." The canvas is infinite for each dimension of the space, but rendering occurs relative to a finite rectangular region of the canvas. This finite rectangular region is called the SVG viewport. For visual media ([CSS21], section 7.3.1) the SVG viewport is the viewing area where the user sees the SVG content.

The above paragraph and definitions need to be merged.

The size of the SVG viewport (i.e., its width and height) is determined by a negotiation process (see Establishing the size of the initial viewport) between the SVG document fragment and its parent (real or implicit). Once that negotiation process is completed, the SVG user agent is provided the following information:

Why are real world units relevant? Shouldn't we just be relying on CSS' fixed ratio of mm to px units?

Using the above information, the SVG user agent determines the viewport, an initial viewport coordinate system and an initial user coordinate system such that the two coordinates systems are identical. Both coordinates systems are established such that the origin matches the origin of the viewport (for the root viewport, the viewport origin is at the top/left corner), and one unit in the initial coordinate system equals one "pixel" in the viewport. (See Initial coordinate system.) The viewport coordinate system is also called viewport space and the user coordinate system is also called user space.

Lengths in SVG can be specified as:

The supported length unit identifiers are: em, ex, px, pt, pc, cm, mm, in, and percentages.

A new user space (i.e., a new current coordinate system) can be established at any place within an SVG document fragment by specifying transformations in the form of transformation matrices or simple transformation operations such as rotation, skewing, scaling and translation. Establishing new user spaces via coordinate system transformations are fundamental operations to 2D graphics and represent the usual method of controlling the size, position, rotation and skew of graphic objects.

New viewports also can be established. By establishing a new viewport, you can redefine the meaning of percentages units and provide a new reference rectangle for "fitting" a graphic into a particular rectangular area. ("Fit" means that a given graphic is transformed in such a way that its bounding box in user space aligns exactly with the edges of a given viewport.)

7.2. The initial viewport

Do we need to port over some more up-to-date definitions of sizing from SVG Tiny 1.2?

The SVG user agent negotiates with its parent user agent to determine the viewport into which the SVG user agent can render the document. In some circumstances, SVG content will be embedded (by reference or inline) within a containing document. This containing document might include attributes, properties and/or other parameters (explicit or implicit) which specify or provide hints about the dimensions of the viewport for the SVG content. SVG content itself optionally can provide information about the appropriate viewport region for the content via the width and height XML attributes on the outermost svg element. The negotiation process uses any information provided by the containing document and the SVG content itself to choose the viewport location and size.

Talking about a "parent user agent" really makes this sound like we have a separate plugin SVG implementation communicating with a browser hosting the plugin. These days, it's going to be the same user agent.

The width attribute on the outermost svg element establishes the viewport's width, unless the following conditions are met:

Under these conditions, the positioning properties establish the viewport's width.

Similarly, if there are positioning properties specified on the referencing element or on the outermost svg element that are sufficient to establish the height of the viewport, then these positioning properties establish the viewport's height; otherwise, the height attribute on the outermost svg element establishes the viewport's height.

If the width or height attributes on the outermost svg element are in user units (i.e., no unit identifier has been provided), then the value is assumed to be equivalent to the same number of "px" units (see Units).

In the following example, an SVG graphic is embedded inline within a parent XML document which is formatted using CSS layout rules. Since CSS positioning properties are not provided on the outermost svg element, the width="100px" and height="200px" attributes determine the size of the initial viewport:

<?xml version="1.0" standalone="yes"?>
<parent xmlns="http://some.url">
   
   <!-- SVG graphic -->
   <svg xmlns='http://www.w3.org/2000/svg'
      width="100px" height="200px">
      <path d="M100,100 Q200,400,300,100"/>
      <!-- rest of SVG graphic would go here -->
   </svg>   
   
</parent>

The initial clipping path for the SVG document fragment is established according to the rules described in The initial clipping path.

7.3. The initial coordinate system

For the outermost svg element, the SVG user agent determines an initial viewport coordinate system and an initial user coordinate system such that the two coordinates systems are identical. The origin of both coordinate systems is at the origin of the viewport, and one unit in the initial coordinate system equals one "pixel" (i.e., a px unit as defined in CSS 2.1 ([CSS21], section 4.3.2) in the viewport. In most cases, such as stand-alone SVG documents or SVG document fragments embedded (by reference or inline) within XML parent documents where the parent's layout is determined by CSS [CSS21] or XSL [XSL], the initial viewport coordinate system (and therefore the initial user coordinate system) has its origin at the top/left of the viewport, with the positive x-axis pointing towards the right, the positive y-axis pointing down, and text rendered with an "upright" orientation, which means glyphs are oriented such that Roman characters and full-size ideographic characters for Asian scripts have the top edge of the corresponding glyphs oriented upwards and the right edge of the corresponding glyphs oriented to the right.

If the SVG implementation is part of a user agent which supports styling XML documents using CSS 2.1 compatible px units, then the SVG user agent should get its initial value for the size of a px unit in real world units to match the value used for other XML styling operations; otherwise, if the user agent can determine the size of a px unit from its environment, it should use that value; otherwise, it should choose an appropriate size for one px unit. In all cases, the size of a px must be in conformance with the rules described in CSS 2.1 ([CSS21], section 4.3.2).

Example InitialCoords below shows that the initial coordinate system has the origin at the top/left with the x-axis pointing to the right and the y-axis pointing down. The initial user coordinate system has one user unit equal to the parent (implicit or explicit) user agent's "pixel".

<?xml version="1.0" standalone="no"?>
<svg width="300px" height="100px" version="1.1"
     xmlns="http://www.w3.org/2000/svg">
  <desc>Example InitialCoords - SVG's initial coordinate system</desc>

  <g fill="none" stroke="black" stroke-width="3" >
    <line x1="0" y1="1.5" x2="300" y2="1.5" />
    <line x1="1.5" y1="0" x2="1.5" y2="100" />
  </g>
  <g fill="red" stroke="none" >
    <rect x="0" y="0" width="3" height="3" />
    <rect x="297" y="0" width="3" height="3" />
    <rect x="0" y="97" width="3" height="3" />
  </g>
  <g font-size="14" font-family="Verdana" >
    <text x="10" y="20">(0,0)</text>
    <text x="240" y="20">(300,0)</text>
    <text x="10" y="90">(0,100)</text>
  </g>
</svg>
Example InitialCoords — SVG's initial coordinate system

Example InitialCoords

View this example as SVG (SVG-enabled browsers only)

7.4. Coordinate system transformations

A new user space (i.e., a new current coordinate system) can be established by specifying transformations in the form of a ‘transform’ property on a container element or graphics element or a viewBox attribute on an svg, symbol, marker, pattern and the view element. The ‘transform’ property and viewBox attribute transform user space coordinates and lengths on sibling attributes on the given element (see effect of the ‘transform’ attribute on sibling attributes and effect of the ‘viewBox’ attribute on sibling attributes) and all of its descendants. Transformations can be nested, in which case the effect of the transformations are cumulative.

The section "effect of the transform attribute on sibling attributes" has been removed since we now reference the ‘transform’ property, but we probably should still include a similar section on how the property affects attributes on the element.

Example OrigCoordSys below shows a document without transformations. The text string is specified in the initial coordinate system.

<?xml version="1.0" standalone="no"?>
<svg width="400px" height="150px"
     xmlns="http://www.w3.org/2000/svg">
  <desc>Example OrigCoordSys - Simple transformations: original picture</desc>
  <g fill="none" stroke="black" stroke-width="3" >
    <!-- Draw the axes of the original coordinate system -->
    <line x1="0" y1="1.5" x2="400" y2="1.5" />
    <line x1="1.5" y1="0" x2="1.5" y2="150" />
  </g>
  <g>
    <text x="30" y="30" font-size="20" font-family="Verdana" >
      ABC (orig coord system)
    </text>
  </g>
</svg>
Example OrigCoordSys — SVG's initial coordinate system

Example OrigCoordSys

View this example as SVG (SVG-enabled browsers only)

Example NewCoordSys establishes a new user coordinate system by specifying transform="translate(50,50)" on the third g element below. The new user coordinate system has its origin at location (50,50) in the original coordinate system. The result of this transformation is that the coordinate (30,30) in the new user coordinate system gets mapped to coordinate (80,80) in the original coordinate system (i.e., the coordinates have been translated by 50 units in X and 50 units in Y).

<?xml version="1.0" standalone="no"?>
<svg width="400px" height="150px"
     xmlns="http://www.w3.org/2000/svg">
  <desc>Example NewCoordSys - New user coordinate system</desc>
  <g fill="none" stroke="black" stroke-width="3" >
    <!-- Draw the axes of the original coordinate system -->
    <line x1="0" y1="1.5" x2="400" y2="1.5" />
    <line x1="1.5" y1="0" x2="1.5" y2="150" />
  </g>
  <g>
    <text x="30" y="30" font-size="20" font-family="Verdana" >
      ABC (orig coord system)
    </text>
  </g>
  <!-- Establish a new coordinate system, which is
       shifted (i.e., translated) from the initial coordinate
       system by 50 user units along each axis. -->
  <g transform="translate(50,50)">
    <g fill="none" stroke="red" stroke-width="3" >
      <!-- Draw lines of length 50 user units along 
           the axes of the new coordinate system -->
      <line x1="0" y1="0" x2="50" y2="0" stroke="red" />
      <line x1="0" y1="0" x2="0" y2="50" />
    </g>
    <text x="30" y="30" font-size="20" font-family="Verdana" >
      ABC (translated coord system)
    </text>
  </g>
</svg>
Example NewCoordSys — New user coordinate system

Example NewCoordSys

View this example as SVG (SVG-enabled browsers only)

Example RotateScale illustrates simple rotate and scale transformations. The example defines two new coordinate systems:

<?xml version="1.0" standalone="no"?>
<svg width="400px" height="120px"
     xmlns="http://www.w3.org/2000/svg">
  <desc>Example RotateScale - Rotate and scale transforms</desc>
  <g fill="none" stroke="black" stroke-width="3" >
    <!-- Draw the axes of the original coordinate system -->
    <line x1="0" y1="1.5" x2="400" y2="1.5" />
    <line x1="1.5" y1="0" x2="1.5" y2="120" />
  </g>
  <!-- Establish a new coordinate system whose origin is at (50,30)
       in the initial coord. system and which is rotated by 30 degrees. -->
  <g transform="translate(50,30)">
    <g transform="rotate(30)">
      <g fill="none" stroke="red" stroke-width="3" >
        <line x1="0" y1="0" x2="50" y2="0" />
        <line x1="0" y1="0" x2="0" y2="50" />
      </g>
      <text x="0" y="0" font-size="20" font-family="Verdana" fill="blue" >
        ABC (rotate)
      </text>
    </g>
  </g>
  <!-- Establish a new coordinate system whose origin is at (200,40)
       in the initial coord. system and which is scaled by 1.5. -->
  <g transform="translate(200,40)">
    <g transform="scale(1.5)">
      <g fill="none" stroke="red" stroke-width="3" >
        <line x1="0" y1="0" x2="50" y2="0" />
        <line x1="0" y1="0" x2="0" y2="50" />
      </g>
      <text x="0" y="0" font-size="20" font-family="Verdana" fill="blue" >
        ABC (scale)
      </text>
    </g>
  </g>
</svg>
Example RotateScale — Rotate and scale transforms

Example RotateScale

View this example as SVG (SVG-enabled browsers only)

Example Skew defines two coordinate systems which are skewed relative to the origin coordinate system.

<?xml version="1.0" standalone="no"?>
<svg width="400px" height="120px"
     xmlns="http://www.w3.org/2000/svg">
  <desc>Example Skew - Show effects of skewX and skewY</desc>
  <g fill="none" stroke="black" stroke-width="3" >
    <!-- Draw the axes of the original coordinate system -->
    <line x1="0" y1="1.5" x2="400" y2="1.5" />
    <line x1="1.5" y1="0" x2="1.5" y2="120" />
  </g>
  <!-- Establish a new coordinate system whose origin is at (30,30)
       in the initial coord. system and which is skewed in X by 30 degrees. -->
  <g transform="translate(30,30)">
    <g transform="skewX(30)">
      <g fill="none" stroke="red" stroke-width="3" >
        <line x1="0" y1="0" x2="50" y2="0" />
        <line x1="0" y1="0" x2="0" y2="50" />
      </g>
      <text x="0" y="0" font-size="20" font-family="Verdana" fill="blue" >
        ABC (skewX)
      </text>
    </g>
  </g>
  <!-- Establish a new coordinate system whose origin is at (200,30)
       in the initial coord. system and which is skewed in Y by 30 degrees. -->
  <g transform="translate(200,30)">
    <g transform="skewY(30)">
      <g fill="none" stroke="red" stroke-width="3" >
        <line x1="0" y1="0" x2="50" y2="0" />
        <line x1="0" y1="0" x2="0" y2="50" />
      </g>
      <text x="0" y="0" font-size="20" font-family="Verdana" fill="blue" >
        ABC (skewY)
      </text>
    </g>
  </g>
</svg>
Example Skew — Show effects of skewX and skewY

Example Skew

View this example as SVG (SVG-enabled browsers only)

7.5. Nested transformations

Transformations can be nested to any level. The effect of nested transformations is to post-multiply (i.e., concatenate) the subsequent transformation matrices onto previously defined transformations:

x prev y prev 1 = a 1 c 1 e 1 b 1 d 1 f 1 0 0 1 a 2 c 2 e 2 b 2 d 2 f 2 0 0 1 x curr y curr 1
current transformation matrix (CTM)
Transformation matrices define the mathematical mapping from one coordinate system into another using a 3x2 matrix or a 4x4 matrix. The current transformation matrix (CTM) defines the mapping from the user coordinate system into the viewport coordinate system. [CSS3TRANSFORMS].

For each given element, the accumulation of all transformations that have been defined on the given element and all of its ancestors up to and including the element that established the current viewport (usually, the svg element which is the most immediate ancestor to the given element) is called the current transformation matrix or CTM. The CTM thus represents the mapping of current user coordinates to viewport coordinates:

CTM = a 1 c 1 e 1 b 1 d 1 f 1 0 0 1 a 2 c 2 e 2 b 2 d 2 f 2 0 0 1 ... a n c n e n b n d n f n 0 0 1 x viewport y viewport 1 = CTM x userspace y userspace 1

Example Nested illustrates nested transformations.

<?xml version="1.0" standalone="no"?>
<svg width="400px" height="150px"
     xmlns="http://www.w3.org/2000/svg">
  <desc>Example Nested - Nested transformations</desc>
  <g fill="none" stroke="black" stroke-width="3" >
    <!-- Draw the axes of the original coordinate system -->
    <line x1="0" y1="1.5" x2="400" y2="1.5" />
    <line x1="1.5" y1="0" x2="1.5" y2="150" />
  </g>
  <!-- First, a translate -->
  <g transform="translate(50,90)">
    <g fill="none" stroke="red" stroke-width="3" >
      <line x1="0" y1="0" x2="50" y2="0" />
      <line x1="0" y1="0" x2="0" y2="50" />
    </g>
    <text x="0" y="0" font-size="16" font-family="Verdana" >
      ....Translate(1)
    </text>
    <!-- Second, a rotate -->
    <g transform="rotate(-45)">
      <g fill="none" stroke="green" stroke-width="3" >
        <line x1="0" y1="0" x2="50" y2="0" />
        <line x1="0" y1="0" x2="0" y2="50" />
      </g>
      <text x="0" y="0" font-size="16" font-family="Verdana" >
        ....Rotate(2)
      </text>
      <!-- Third, another translate -->
      <g transform="translate(130,160)">
        <g fill="none" stroke="blue" stroke-width="3" >
          <line x1="0" y1="0" x2="50" y2="0" />
          <line x1="0" y1="0" x2="0" y2="50" />
        </g>
        <text x="0" y="0" font-size="16" font-family="Verdana" >
          ....Translate(3)
        </text>
      </g>
    </g>
  </g>
</svg>
Example Nested — Nested transformations

Example Nested

View this example as SVG (SVG-enabled browsers only)

In the example above, the CTM within the third nested transformation (i.e., the transform="translate(130,160)") consists of the concatenation of the three transformations, as follows:

CTM = translate(50,90), rotate(-45), translate(130,160) = 1 0 50 0 1 90 0 0 1 .707 .707 0 -.707 .707 0 0 0 1 1 0 130 0 1 160 0 0 1 = .707 .707 255.03 -.707 .707 111.21 0 0 1 x initial y initial 1 = CTM x userspace y userspace 1

7.6. The ‘transform’ property

Name: transform
Animatable: yes

Do we need this blue box, and if so, should we expand it to include all of the property definition information? Some sections (such as for ‘color’) do not have the blue box. Others, like the one for ‘white-space’, have all the information from the CSS specification it comes from. Regardless, I think we don't need to mention whether the property is animatable since all properties are animatable.

The term <transform-list> used by this specification is equivalent to a list of <transform-functions>, the value of the ‘transform’ property.

See the CSS3 Transforms spec for the description of the ‘transform’ property and the value of <transform-functions> [CSS3TRANSFORMS].

7.7. The ‘viewBox’ attribute

The lacuna value for viewBox is not yet defined. Should we have an explicit 'none' keyword like in SVG Tiny 1.2?

Transform on the svg element is a bit special due to the viewBox attribute. The transform should be applied as if the svg had a parent element with that transform set.

RESOLUTION: transform property applies conceptually to the outside of the 'svg' element and there is no difference between presentation attribute and style property (in terms of the visual result).

Add an attribute table for the definition of viewBox.

It is often desirable to specify that a given set of graphics stretch to fit a particular container element. The viewBox attribute provides this capability.

All elements that establish a new viewport (see elements that establish viewports), plus the marker, pattern and view elements have attribute viewBox. The value of the viewBox attribute is a list of four numbers <min-x>, <min-y>, <width> and <height>, separated by whitespace and/or a comma, which specify a rectangle in user space which should be mapped to the bounds of the viewport established by the given element, taking into account attribute preserveAspectRatio. If specified, an additional transformation is applied to all descendants of the given element to achieve the specified effect.

A negative value for <width> or <height> is an error (see Error processing). A value of zero disables rendering of the element.

Proposal: combine the is-zero case with the negative case.

Proposal: disable rendering both for zero and negative width/height values inside the viewBox, but don't make it an error.

Example ViewBox illustrates the use of the viewBox attribute on the outermost svg element to specify that the SVG content should stretch to fit bounds of the viewport.

<?xml version="1.0" standalone="no"?>
<svg width="300px" height="200px"
     viewBox="0 0 1500 1000" preserveAspectRatio="none"
     xmlns="http://www.w3.org/2000/svg">
  <desc>Example ViewBox - uses the viewBox 
   attribute to automatically create an initial user coordinate
   system which causes the graphic to scale to fit into the
   viewport no matter what size the viewport is.</desc>
  <!-- This rectangle goes from (0,0) to (1500,1000) in user space.
       Because of the viewBox attribute above,
       the rectangle will end up filling the entire area
       reserved for the SVG content. -->
  <rect x="0" y="0" width="1500" height="1000" 
        fill="yellow" stroke="blue" stroke-width="12"  />
  <!-- A large, red triangle -->
  <path fill="red"  d="M 750,100 L 250,900 L 1250,900 z"/>
  <!-- A text string that spans most of the viewport -->
  <text x="100" y="600" font-size="200" font-family="Verdana" >
    Stretch to fit
  </text>
</svg>
Example ViewBox
Rendered into
viewport with
width=300px,
height=200px
      Rendered into
viewport with
width=150px,
height=200px
Example ViewBox - stretch to fit 300 by 200       Example ViewBox - stretch to fit 150 by 200

View this example as SVG (SVG-enabled browsers only)
 

The effect of the viewBox attribute is that the user agent automatically supplies the appropriate transformation matrix to map the specified rectangle in user space to the bounds of a designated region (often, the viewport). To achieve the effect of the example on the left, with viewport dimensions of 300 by 200 pixels, the user agent needs to automatically insert a transformation which scales both X and Y by 0.2. The effect is equivalent to having a viewport of size 300px by 200px and the following supplemental transformation in the document, as follows:

<?xml version="1.0" standalone="no"?>
<svg width="300px" height="200px"
     xmlns="http://www.w3.org/2000/svg">
  <g transform="scale(0.2)">
    <!-- Rest of document goes here -->
  </g>
</svg>

To achieve the effect of the example on the right, with viewport dimensions of 150 by 200 pixels, the user agent needs to automatically insert a transformation which scales X by 0.1 and Y by 0.2. The effect is equivalent to having a viewport of size 150px by 200px and the following supplemental transformation in the document, as follows:

<?xml version="1.0" standalone="no"?>
<svg width="150px" height="200px"
     xmlns="http://www.w3.org/2000/svg">
  <g transform="scale(0.1 0.2)">
    <!-- Rest of document goes here -->
  </g>
</svg>

(Note: in some cases the user agent will need to supply a translate transformation in addition to a scale transformation. For example, on an outermost svg element, a translate transformation will be needed if the viewBox attributes specifies values other than zero for <min-x> or <min-y>.)

Unlike the ‘transform’ property (see effect of the ‘transform’ attribute on sibling attributes), the automatic transformation that is created due to a viewBox does not affect the ‘x’, ‘y’, ‘width’ and ‘height’ attributes (or in the case of the marker element, the markerWidth and markerHeight attributes) on the element with the viewBox attribute. Thus, in the example above which shows an svg element which has attributes width, height and viewBox, the width and height attributes represent values in the coordinate system that exists before the viewBox transformation is applied. On the other hand, like the ‘transform’ property, it does establish a new coordinate system for all other attributes and for descendant elements.

Link to the "effect of the 'transform' attribute on sibling attributes" in the above paragraph needs to be update.

For the viewBox attribute:

    Animatable: yes.

7.8. The ‘preserveAspectRatio’ attribute

Add an attribute table for the definition of preserveAspectRatio.

Mention css object-fit/object-position as an alternative?

In some cases, typically when using the viewBox attribute, it is desirable that the graphics stretch to fit non-uniformly to take up the entire viewport. In other cases, it is desirable that uniform scaling be used for the purposes of preserving the aspect ratio of the graphics.

Attribute preserveAspectRatio="[defer] <align> [<meetOrSlice>]", which is available for all elements that establish a new viewport (see elements that establish viewports), plus the image, marker, pattern and view elements, indicates whether or not to force uniform scaling.

Is 'defer' supported in enough UAs and is it a compelling enough use-case to warrant it being kept?

For elements that establish a new viewport (see elements that establish viewports), plus the marker, pattern and view elements, preserveAspectRatio only applies when a value has been provided for viewBox on the same element. For these elements, if attribute viewBox is not provided, then preserveAspectRatio is ignored.

For image elements, preserveAspectRatio indicates how referenced images should be fitted with respect to the reference rectangle and whether the aspect ratio of the referenced image should be preserved with respect to the current user coordinate system.

If the value of preserveAspectRatio on an image element starts with 'defer' then the value of the preserveAspectRatio attribute on the referenced content if present should be used. If the referenced content lacks a value for preserveAspectRatio then the preserveAspectRatio attribute should be processed as normal (ignoring 'defer'). For preserveAspectRatio on all other elements the 'defer' portion of the attribute is ignored.

The <align> parameter indicates whether to force uniform scaling and, if so, the alignment method to use in case the aspect ratio of the viewBox doesn't match the aspect ratio of the viewport. The <align> parameter must be one of the following strings:

The <meetOrSlice> parameter is optional and, if provided, is separated from the <align> value by one or more spaces and then must be one of the following strings:

Example PreserveAspectRatio illustrates the various options on preserveAspectRatio. The example creates several new viewports by including svg sub-elements embedded inside the outermost svg element (see Establishing a new viewport).

<svg width="450px" height="300px"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">
  <desc>Example PreserveAspectRatio - illustrates preserveAspectRatio attribute</desc>
  <defs>
	<g id="smile">
<rect x='.5' y='.5' width='29' height='39' fill='black' stroke='red'/>
<g transform='translate(0, 5)'>
<circle cx='15' cy='15' r='10' fill='yellow'/>
<circle cx='12' cy='12' r='1.5' fill='black'/>
<circle cx='17' cy='12' r='1.5' fill='black'/>
<path d='M 10 19 A 8 8 0 0 0 20 19' stroke='black' stroke-width='2'/>
</g>
</g>
</defs>
  <rect x="1" y="1" width="448" height="298"
        fill="none" stroke="blue"/>
  <g font-size="9">
    <text x="10" y="30">SVG to fit</text>
    <g transform="translate(20,40)"><use xlink:href="#smile" /></g>
    <text x="10" y="110">Viewport 1</text>
    <g transform="translate(10,120)"><rect x='.5' y='.5' width='49' height='29' fill='none' stroke='blue'/>;</g>
    <text x="10" y="180">Viewport 2</text>
    <g transform="translate(20,190)"><rect x='.5' y='.5' width='29' height='59' fill='none' stroke='blue'/>;</g>

    <g id="meet-group-1" transform="translate(100, 60)">
      <text x="0" y="-30">--------------- meet ---------------</text>
      <g><text y="-10">xMin*</text><rect x='.5' y='.5' width='49' height='29' fill='none' stroke='blue'/>;
        <svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 30 40"
             width="50" height="30"><use xlink:href="#smile" /></svg></g>
      <g transform="translate(70,0)"><text y="-10">xMid*</text><rect x='.5' y='.5' width='49' height='29' fill='none' stroke='blue'/>;
        <svg preserveAspectRatio="xMidYMid meet" viewBox="0 0 30 40"
             width="50" height="30"><use xlink:href="#smile" /></svg></g>
      <g transform="translate(0,70)"><text y="-10">xMax*</text><rect x='.5' y='.5' width='49' height='29' fill='none' stroke='blue'/>;
        <svg preserveAspectRatio="xMaxYMax meet" viewBox="0 0 30 40"
             width="50" height="30"><use xlink:href="#smile" /></svg></g>
    </g>

    <g id="meet-group-2" transform="translate(250, 60)">
      <text x="0" y="-30">---------- meet ----------</text>
      <g><text y="-10">*YMin</text><rect x='.5' y='.5' width='29' height='59' fill='none' stroke='blue'/>;
        <svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 30 40"
             width="30" height="60"><use xlink:href="#smile" /></svg></g>
      <g transform="translate(50, 0)"><text y="-10">*YMid</text><rect x='.5' y='.5' width='29' height='59' fill='none' stroke='blue'/>;
        <svg preserveAspectRatio="xMidYMid meet" viewBox="0 0 30 40"
             width="30" height="60"><use xlink:href="#smile" /></svg></g>
      <g transform="translate(100, 0)"><text y="-10">*YMax</text><rect x='.5' y='.5' width='29' height='59' fill='none' stroke='blue'/>;
        <svg preserveAspectRatio="xMaxYMax meet" viewBox="0 0 30 40"
             width="30" height="60"><use xlink:href="#smile" /></svg></g>
    </g>

    <g id="slice-group-1" transform="translate(100, 220)">
      <text x="0" y="-30">---------- slice ----------</text>
      <g><text y="-10">xMin*</text><rect x='.5' y='.5' width='29' height='59' fill='none' stroke='blue'/>;
        <svg preserveAspectRatio="xMinYMin slice" viewBox="0 0 30 40"
             width="30" height="60"><use xlink:href="#smile" /></svg></g>
      <g transform="translate(50,0)"><text y="-10">xMid*</text><rect x='.5' y='.5' width='29' height='59' fill='none' stroke='blue'/>;
        <svg preserveAspectRatio="xMidYMid slice" viewBox="0 0 30 40"
             width="30" height="60"><use xlink:href="#smile" /></svg></g>
      <g transform="translate(100,0)"><text y="-10">xMax*</text><rect x='.5' y='.5' width='29' height='59' fill='none' stroke='blue'/>;
        <svg preserveAspectRatio="xMaxYMax slice" viewBox="0 0 30 40"
             width="30" height="60"><use xlink:href="#smile" /></svg></g>
    </g>

    <g id="slice-group-2" transform="translate(250, 220)">
      <text x="0" y="-30">--------------- slice ---------------</text>
      <g><text y="-10">*YMin</text><rect x='.5' y='.5' width='49' height='29' fill='none' stroke='blue'/>;
        <svg preserveAspectRatio="xMinYMin slice" viewBox="0 0 30 40"
             width="50" height="30"><use xlink:href="#smile" /></svg></g>
      <g transform="translate(70,0)"><text y="-10">*YMid</text><rect x='.5' y='.5' width='49' height='29' fill='none' stroke='blue'/>;
        <svg preserveAspectRatio="xMidYMid slice" viewBox="0 0 30 40"
             width="50" height="30"><use xlink:href="#smile" /></svg></g>
      <g transform="translate(140,0)"><text y="-10">*YMax</text><rect x='.5' y='.5' width='49' height='29' fill='none' stroke='blue'/>;
        <svg preserveAspectRatio="xMaxYMax slice" viewBox="0 0 30 40"
             width="50" height="30"><use xlink:href="#smile" /></svg></g>
    </g>   
  </g>
</svg>
Example PreserveAspectRatio — demonstrate available options

Example PreserveAspectRatio

View this example as SVG (SVG-enabled browsers only)

For the preserveAspectRatio attribute:

    Animatable: yes.

7.9. Establishing a new viewport

At any point in an SVG drawing, you can establish a new viewport into which all contained graphics is drawn by including an svg element inside SVG content. By establishing a new viewport, you also implicitly establish a new viewport coordinate system, a new user coordinate system, and, potentially, a new clipping path (see the definition of the ‘overflow’ property). Additionally, there is a new meaning for percentage units defined to be relative to the current viewport since a new viewport has been established (see Units).

The bounds of the new viewport are defined by the ‘x’, ‘y’, ‘width’ and ‘height’ attributes on the element establishing the new viewport, such as an svg element. Both the new viewport coordinate system and the new user coordinate system have their origins at (‘x’, ‘y’), where ‘x’ and ‘y’ represent the value of the corresponding attributes on the element establishing the viewport. The orientation of the new viewport coordinate system and the new user coordinate system correspond to the orientation of the current user coordinate system for the element establishing the viewport. A single unit in the new viewport coordinate system and the new user coordinate system are the same size as a single unit in the current user coordinate system for the element establishing the viewport.

Here is an example:

<?xml version="1.0" standalone="no"?>
<svg width="4in" height="3in"
     xmlns="http://www.w3.org/2000/svg">
  <desc>This SVG drawing embeds another one,
    thus establishing a new viewport
  </desc>
  <!-- The following statement establishing a new viewport
       and renders SVG drawing B into that viewport -->
  <svg x="25%" y="25%" width="50%" height="50%">
     <!-- drawing B goes here -->
  </svg>
</svg>

For an extensive example of creating new viewports, see Example PreserveAspectRatio.

The following elements establish new viewports:

Whether a new viewport also establishes a new additional clipping path is determined by the value of the ‘overflow’ property on the element that establishes the new viewport. If a clipping path is created to correspond to the new viewport, the clipping path's geometry is determined by the value of the ‘clip’ property. Also, see Clip to viewport vs. clip to ‘viewBox’.

7.10. Units

All coordinates and lengths in SVG can be specified with or without a unit identifier.

This is misleading – path data for example takes values that look like coordinates and lengths yet does not allow units.

When a coordinate or length value is a number without a unit identifier (e.g., "25"), then the given coordinate or length is assumed to be in user units (i.e., a value in the current user coordinate system). For example:

<text font-size="50">Text size is 50 user units</text>

Alternatively, a coordinate or length value can be expressed as a number followed by a unit identifier (e.g., "25cm" or "15em"). (Note that CSS defined properties used in a CSS style sheet or the style attribute require units for non-zero lengths, see SVG's styling properties.) The list of unit identifiers in SVG matches the list of unit identifiers in CSS: em, ex, px, pt, pc, cm, mm and in. The <length> type can also have a percentage unit identifier. The following describes how the various unit identifiers are processed:

Note that use of px units or any other absolute unit identifiers can cause inconsistent visual results on different viewing environments since the size of "1px" may map to a different number of user units on different systems; thus, absolute units identifiers are only recommended for the width and the height on outermost svg elements and situations where the content contains no transformations and it is desirable to specify values relative to the device pixel grid or to a particular real world unit size.

That's wrong. 1px always corresponds to one user unit, and the "absolute" units must be interpreted as CSS says to, i.e. as fixed multiples of the CSS px, and not anything to do with the display's resolution. The recommendation to use the absolute units (apart from px) only for width and height on root svg is a good one, however. Defining the size of a document in mm and then using mm units for shapes within it is going to give counterintuitive results, since they'll be converted to user units to resolve against the view box.

For percentage values that are defined to be relative to the size of viewport:

Example Units below illustrates some of the processing rules for different types of units.

<?xml version="1.0" standalone="no"?>
<svg width="400px" height="200px" viewBox="0 0 4000 2000"
     xmlns="http://www.w3.org/2000/svg">
  <title>Example Units</title>
  <desc>Illustrates various units options</desc>

  <!-- Frame the picture -->
  <rect x="5" y="5" width="3990" height="1990" 
        fill="none" stroke="blue" stroke-width="10"/>

  <g fill="blue" stroke="red" font-family="Verdana" font-size="150">
    <!-- Absolute unit specifiers -->
    <g transform="translate(400,0)">
      <text x="-50" y="300" fill="black" stroke="none">Abs. units:</text>
      <rect x="0" y="400" width="4in" height="2in" stroke-width=".4in"/>
      <rect x="0" y="750" width="384" height="192" stroke-width="38.4"/>
      <g transform="scale(2)">
        <rect x="0" y="600" width="4in" height="2in" stroke-width=".4in"/>
      </g>
    </g>

    <!-- Relative unit specifiers -->
    <g transform="translate(1600,0)">
      <text x="-50" y="300" fill="black" stroke="none">Rel. units:</text>
      <rect x="0" y="400" width="2.5em" height="1.25em" stroke-width=".25em"/>
      <rect x="0" y="750" width="375" height="187.5" stroke-width="37.5"/>
      <g transform="scale(2)">
        <rect x="0" y="600" width="2.5em" height="1.25em" stroke-width=".25em"/>
      </g>
    </g>

    <!-- Percentages -->
    <g transform="translate(2800,0)">
      <text x="-50" y="300" fill="black" stroke="none">Percentages:</text>
      <rect x="0" y="400" width="10%" height="10%" stroke-width="1%"/>
      <rect x="0" y="750" width="400" height="200" stroke-width="31.62"/>
      <g transform="scale(2)">
        <rect x="0" y="600" width="10%" height="10%" stroke-width="1%"/>
      </g>
    </g>
  </g>
</svg>
Example Units — demonstrate available options

Example Units

View this example as SVG (SVG-enabled browsers only)

The three rectangles on the left demonstrate the use of one of the absolute unit identifiers, the "in" unit (inch). The reference image above was generated on a 96dpi system (i.e., 1 inch = 96 pixels). Therefore, the topmost rectangle, which is specified in inches, is exactly the same size as the middle rectangle, which is specified in user units such that there are 96 user units for each corresponding inch in the topmost rectangle. (Note: on systems with different screen resolutions, the top and middle rectangles will likely be rendered at different sizes.) The bottom rectangle of the group illustrates what happens when values specified in inches are scaled.

The example needs to be changed in light of the issue above about absolute units.

The three rectangles in the middle demonstrate the use of one of the relative unit identifiers, the "em" unit. Because the ‘font-size’ property has been set to 150 on the outermost g element, each "em" unit is equal to 150 user units. The topmost rectangle, which is specified in "em" units, is exactly the same size as the middle rectangle, which is specified in user units such that there are 150 user units for each corresponding "em" unit in the topmost rectangle. The bottom rectangle of the group illustrates what happens when values specified in "em" units are scaled.

The three rectangles on the right demonstrate the use of percentages. Note that the width and height of the viewport in the user coordinate system for the viewport element (in this case, the outermost svg element) are 4000 and 2000, respectively, because processing the viewBox attribute results in a transformed user coordinate system. The topmost rectangle, which is specified in percentage units, is exactly the same size as the middle rectangle, which is specified in equivalent user units. In particular, note that the ‘stroke-width’ property in the middle rectangle is set to 1% of the sqrt((actual-width)**2 + (actual-height)**2) / sqrt(2), which in this case is .01*sqrt(4000*4000+2000*2000)/sqrt(2), or 31.62. The bottom rectangle of the group illustrates what happens when values specified in percentage units are scaled.

7.11. Bounding boxes

bounding box

The bounding box (or "bbox") of an element is the tightest fitting rectangle aligned with the axes of that element's user coordinate system that entirely encloses it and its descendants.

Three kinds of bounding boxes can be computed for an element:

  1. The object bounding box is the bounding box that contains only an element's geometric shape. For basic shapes, this is the area that is filled. Unless otherwise specified, this is what is meant by the unqualified term "bounding box".
  2. The stroke bounding box is the bounding box that contains an element's geometric shape and its stroke shape.
  3. The decorated bounding box is the bounding box that contains an element's geometric shape, its stroke shape and its markers.

Note that the values of the ‘opacity’, ‘visibility’, ‘fill’, ‘fill-opacity’, ‘fill-rule’, ‘stroke-dasharray’ and ‘stroke-dashoffset’ properties on an element have no effect on the bounding box of an element.

For curved shapes, the bounding box must enclose all portions of the shape along the edge, not just end points. Note that control points for a curve which are not defined as lying along the line of the resulting curve (e.g., the second coordinate pair of a Cubic Bézier command) must not contribute to the dimensions of the bounding box (though those points may fall within the area of the bounding box, if they lie within the shape itself, or along or close to the curve). For example, control points of a curve that are at a further distance than the curve edge, from the non-enclosing side of the curve edge, must be excluded from the bounding box.

Image showing the object bounding box of a quadratic Bézier curve.

The path 'M20,50 L35,100 H120 V50 Q70,10 20,50' is shown in light blue. On the left, a correct object bounding box of the path is shown. Note that it does not include the top-most control point of the curve, but it does include all of the blue shape, even the parts that lie outside of the convex hull of the control points.

Even if an element is not in the rendering tree – due to it being 'display: none', within a defs element, not usually rendered like a symbol element or not currently present in the document tree – it still has a bounding box. A call to getBBox on the element will return the same rectangle as if the element were rendered. However, an element that is not in the rendering tree does not contribute to the bounding box of any ancestor element.

The following example defines a number of elements. The expected object bounding box for each element with an ID is shown below.

<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">

  <title>Bounding Box Calculation</title>
  <desc>Examples of elements with different bounding box results based on context.</desc>

  <defs id="defs-1">
     <rect id="rect-1" x="20" y="20" width="40" height="40" fill="blue" />
  </defs>

  <g id="group-1">
    <use id="use-1" xlink:href="#rect-1" x="10" y="10" />

    <g id="group-2" display="none">
      <rect id="rect-2" x="10" y="10" width="100" height="100" fill="red" />
    </g>
  </g>
</svg>
Element ID Bounding Box Result
"defs-1" {0, 0, 0, 0}
"rect-1" {20, 20, 40, 40}
"group-1" {30, 30, 40, 40}
"use-1" {30, 30, 40, 40}
"group-2" {10, 10, 100, 100}
"rect-2" {10, 10, 100, 100}

For text content elements, for the purposes of the bounding box calculation, each glyph must be treated as a separate graphics element. he calculations must assume that all glyphs occupy the full glyph cell. For example, for horizontal text, the calculations must assume that each glyph extends vertically to the full ascent and descent values for the font. An exception to this is when the extent attribute has been specified on the text element, in which case the element's content area is its bounding box.

Because declarative or scripted animation can change the shape, size, and position of an element, the bounding box is mutable. Thus, the bounding box for an element shall reflect the current values for the element at the snapshot in time at which the bounding box is requested, whether through a script call or as part of a declarative or linking syntax.

An element which has zero width, zero height, or both (such as a vertical or horizontal line, or a rect element with an unspecified width or height) still has a bounding box, with a positive value for the positive dimension, or with '0' for both the width and height if no positive dimension is specified. Similarly, subpaths segments of a path element with zero width and height must be included in that element's geometry for the sake of the bounding box.

An element with no position specified (such as a path element with a value of (none) for the d attribute) is positioned at the point (0,0) for the purposes of calculating a bounding box.

Note that elements whose DOM object does not derive from SVGGraphicsElement (such as gradient elements) do not have a bounding box, and thus have no interface to request a bounding box.

Elements in the rendering tree which reference unresolved resources shall still have a bounding box, defined by the position and dimensions specified in their attributes, or by the lacuna value for those attributes if no values are supplied. For example, the element <use xlink:href="#bad" x="10" y="10"/> would have a bounding box with an x and y of 10 and a width and height of 0.

The following algorithm defines how to compute a bounding box for a given element. The inputs to the algorithm are:

Need to define what the union of rectangles with no area means.

The algorithm to compute the bounding box is as follows, depending on the type of element:

a shape
a text content element
an a element within a text content element
  1. Let box be a rectangle initialized to (0, 0, 0, 0).
  2. Let fill-shape be the equivalent path of element if it is a shape, or a shape that includes each of the glyph cells corresponding to the text within the elements otherwise.

    Need to update this take into account extent on text.

  3. If fill is true, then set box to the tightest rectangle in the coordinate system space that contains fill-shape.

    The values of the ‘fill’, ‘fill-opacity’ and ‘fill-rule’ properties do not affect fill-shape.

  4. If stroke is true and the element's ‘stroke’ is anything other than none, then set box to be the union of box and the tightest rectangle in coordinate system space that contains the stroke shape of the element, with the assumption that the element has no dash pattern.

    The values of the ‘stroke-opacity’, ‘stroke-dasharray’ and ‘stroke-dashoffset’ do not affect the calculation of the stroke shape.

  5. If markers is true, then for each marker marker rendered on the element:
    1. For each descendant graphics element child of the marker element that defines marker's content:
      1. If child has an ancestor element within the marker that is 'display: none', has a failing conditional processing attribute, or is not an a, g, svg or switch element, then continue to the next descendant graphics element.
      2. Otherwise, set box to be the union of box and the result of invoking the algorithm to compute a bounding box with child as the element, space as the target coordinate space, true for fill, stroke and markers, and clipped for clipped.

        Need to determine whether 'display: none' on the marker element itself has any effect here.

  6. If clipped is true and the value of ‘clip-path’ on element is not none, then set box to be the tighest rectangle in coordinate system space that contains the intersection of box and the clipping path.
  7. Return box.
a container element
use
  1. Let box be a rectangle initialized to (0, 0, 0, 0).
  2. Let parent be the container element if it is one, or the root of the use element's shadow tree otherwise.
  3. For each descendant graphics element child of parent:
    1. If child has an ancestor element within parent that is 'display: none', has a failing conditional processing attribute, or is not an a, g, svg or switch element, then continue to the next descendant graphics element.
    2. Otherwise, set box to be the union of box and the result of invoking the algorithm to compute a bounding box with child as the element and the same values for space, fill, stroke, markers and clipped as the corresponding algorithm input values.
  4. Return box.
canvas
foreignObject
iframe
image
video
  1. Return the tightest rectangle in coordinate space space that contains the rectangle defined by the ‘x’, ‘y’, ‘width’ and ‘height’ attributes of the element.

    The fill, stroke and markers input arguments to this algorithm do not affect the bounding box returned for these elements.

The object bounding box, stroke bounding box or decorated bounding box of an element is the result of invoking the bounding box computation algorithm above with the following arguments: element is the element itself; space is the element's user coordinate system; fill is true; stroke is true if we are computing the stroke bounding box or decorated bounding box, and false othwerise; markers is true if we are computing the decorated bounding box, and false otherwise; and clipped is false.

7.12. Object bounding box units

The following elements offer the option of expressing coordinate values and lengths as fractions (and, in some cases, percentages) of the bounding box, by setting a specified attribute to 'objectBoundingBox' on the given element:

Need a line for meshGradient.

Need to invoke the bounding box computation algorithm from the previous section with fill = true and the other options false.

Element Attribute Effect
linearGradient gradientUnits Indicates that the attributes which specify the gradient vector (x1, y1, x2, y2) represent fractions or percentages of the bounding box of the element to which the gradient is applied.
radialGradient gradientUnits Indicates that the attributes which specify the center (cx, cy), the radius (r) and focus (fx, fy) represent fractions or percentages of the bounding box of the element to which the gradient is applied.
pattern patternUnits Indicates that the attributes which define how to tile the pattern (x, y, width, height) are established using the bounding box of the element to which the pattern is applied.
pattern patternContentUnits Indicates that the user coordinate system for the contents of the pattern is established using the bounding box of the element to which the pattern is applied.
clipPath clipPathUnits Indicates that the user coordinate system for the contents of the clipPath element is established using the bounding box of the element to which the clipping path is applied.
mask maskUnits Indicates that the attributes which define the masking region (x, y, width, height) is established using the bounding box of the element to which the mask is applied.
mask maskContentUnits Indicates that the user coordinate system for the contents of the mask element are established using the bounding box of the element to which the mask is applied.
filter filterUnits Indicates that the attributes which define the filter effects region (x, y, width, height) represent fractions or percentages of the bounding box of the element to which the filter is applied.
filter primitiveUnits Indicates that the various length values within the filter primitives represent fractions or percentages of the bounding box of the element to which the filter is applied.

In the discussion that follows, the term applicable element is the element to which the given effect applies. For gradients and patterns, the applicable element is the graphics element which has its ‘fill’ or ‘stroke’ property referencing the given gradient or pattern. (See Inheritance of Painting Properties. For special rules concerning text elements, see the discussion of object bounding box units and text elements.) For clipping paths, masks and filters, the applicable element can be either a container element or a graphics element.

When keyword objectBoundingBox is used, then the effect is as if a supplemental transformation matrix were inserted into the list of nested transformation matrices to create a new user coordinate system.

First, the (minx,miny) and (maxx,maxy) coordinates are determined for the applicable element and all of its descendants. The values minx, miny, maxx and maxy are determined by computing the maximum extent of the shape of the element in X and Y with respect to the user coordinate system for the applicable element. The bounding box is the tightest fitting rectangle aligned with the axes of the applicable element's user coordinate system that entirely encloses the applicable element and its descendants. The bounding box is computed exclusive of any values for clipping, masking, filter effects, opacity and stroke-width. For curved shapes, the bounding box encloses all portions of the shape, not just end points. For ‘text’ elements, for the purposes of the bounding box calculation, each glyph is treated as a separate graphics element. The calculations assume that all glyphs occupy the full glyph cell. For example, for horizontal text, the calculations assume that each glyph extends vertically to the full ascent and descent values for the font.

Then, coordinate (0,0) in the new user coordinate system is mapped to the (minx,miny) corner of the tight bounding box within the user coordinate system of the applicable element and coordinate (1,1) in the new user coordinate system is mapped to the (maxx,maxy) corner of the tight bounding box of the applicable element. In most situations, the following transformation matrix produces the correct effect:

[ (maxx-minx) 0 0 (maxy-miny) minx miny ]

When percentages are used with attributes that define the gradient vector, the pattern tile, the filter region or the masking region, a percentage represents the same value as the corresponding decimal value (e.g., 50% means the same as 0.5). If percentages are used within the content of a pattern, clipPath, mask or filter element, these values are treated according to the processing rules for percentages as defined in Units.

Any numeric value can be specified for values expressed as a fraction or percentage of object bounding box units. In particular, fractions less are zero or greater than one and percentages less than 0% or greater than 100% can be specified.

Keyword objectBoundingBox should not be used when the geometry of the applicable element has no width or no height, such as the case of a horizontal or vertical line, even when the line has actual thickness when viewed due to having a non-zero stroke width since stroke width is ignored for bounding box calculations. When the geometry of the applicable element has no width or height and objectBoundingBox is specified, then the given effect (e.g., a gradient or a filter) will be ignored.

7.13. Intrinsic sizing properties of the viewport of SVG content

SVG needs to specify how to calculate some intrinsic sizing properties to enable inclusion within other languages. The intrinsic width and height of the viewport of SVG content must be determined from the ‘width’ and ‘height’ presentation attributes. If either of these are not specified, a value of 'auto' must be assumed. Specifically, percentage values do not provide an intrinsic width or height..

The intrinsic aspect ratio of the viewport of SVG content is necessary for example, when including SVG from an ‘object’ element in HTML styled with CSS. It is possible (indeed, common) for an SVG graphic to have an intrinsic aspect ratio but not to have an intrinsic width or height. The intrinsic aspect ratio must be calculated based upon the following rules:

Examples:

Example: Intrinsic Aspect Ratio 1
<svg xmlns="http://www.w3.org/2000/svg"
     width="10cm" height="5cm">
  ...
</svg>

In this example the intrinsic aspect ratio of the viewport is 2:1. The intrinsic width is 10cm and the intrinsic height is 5cm.

Example: Intrinsic Aspect Ratio 2
<svg xmlns="http://www.w3.org/2000/svg"
     width="100%" height="50%" viewBox="0 0 200 200">
  ...
</svg>

In this example the intrinsic aspect ratio of the outermost viewport is 1:1. An aspect ratio calculation in this case allows embedding in an object within a containing block that is only constrained in one direction.

Example: Intrinsic Aspect Ratio 3
<svg xmlns="http://www.w3.org/2000/svg"
     width="10cm" viewBox="0 0 200 200">
  ...
</svg>

In this case the intrinsic aspect ratio is 1:1.

Example: Intrinsic Aspect Ratio 4
<svg xmlns="http://www.w3.org/2000/svg"
     width="75%" height="10cm" viewBox="0 0 200 200">
  ...
</svg>

In this example, the intrinsic aspect ratio is 1:1.

Add more examples for the new auto value? E.g some of the examples provided by David Vest.

7.14. DOM interfaces

7.14.1. Interface SVGPointList

This interface defines a list of DOMPoint objects.

SVGPointList has the same attributes and methods as other SVGxxxList interfaces. Implementers may consider using a single base class to implement the various SVGxxxList interfaces.

The supported property indices of an SVGPointList object is all non-negative integers less than the length of the list.

interface SVGPointList {

  readonly attribute unsigned long length;
  readonly attribute unsigned long numberOfItems;

  void clear();
  DOMPoint initialize(DOMPoint newItem);
  getter DOMPoint getItem(unsigned long index);
  DOMPoint insertItemBefore(DOMPoint newItem, unsigned long index);
  DOMPoint replaceItem(DOMPoint newItem, unsigned long index);
  DOMPoint removeItem(unsigned long index);
  DOMPoint appendItem(DOMPoint newItem);
  setter void (unsigned long index, DOMPoint newItem);
};
Attributes:
length (readonly unsigned long)
The number of items in the list.
numberOfItems (readonly unsigned long)
The number of items in the list.
Operations:
void clear()
Clears all existing current items from the list, with the result being an empty list.
Exceptions
DOMException, code NO_MODIFICATION_ALLOWED_ERR
Raised when the list cannot be modified.
DOMPoint initialize(DOMPoint newItem)
Clears all existing current items from the list and re-initializes the list to hold a single item specified by the parameter. If newItem is in a list, then a new SVGPoint object is created with the same values as newItem and this item is inserted into the list. Otherwise, newItem itself is inserted into the list.
Parameters
  1. DOMPoint newItem
    The item which should become the only member of the list.
Returns
The item being inserted into the list.
Exceptions
DOMException, code NO_MODIFICATION_ALLOWED_ERR
Raised when the list cannot be modified.
DOMPoint getItem(unsigned long index)
Returns the specified item from the list. The returned item is the item itself and not a copy. Any changes made to the item are immediately reflected in the list.
Parameters
  1. unsigned long index
    The index of the item from the list which is to be returned. The first item is number 0.
Returns
The selected item.
Exceptions
DOMException, code INDEX_SIZE_ERR
Raised if the index number is greater than or equal to numberOfItems.
DOMPoint insertItemBefore(DOMPoint newItem, unsigned long index)
Inserts a new item into the list at the specified position. The first item is number 0. If newItem is already in a list, then a new SVGPoint object is created with the same values as newItem and this item is inserted into the list. Otherwise, newItem itself is inserted into the list.
Parameters
  1. DOMPoint newItem
    The item which is to be inserted into the list.
  2. unsigned long index
    The index of the item before which the new item is to be inserted. The first item is number 0. If the index is equal to 0, then the new item is inserted at the front of the list. If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.
Returns
The inserted item.
Exceptions
DOMException, code NO_MODIFICATION_ALLOWED_ERR
Raised when the list cannot be modified.
DOMPoint replaceItem(DOMPoint newItem, unsigned long index)
Replaces an existing item in the list with a new item. If newItem is already in a list, it is removed from its previous list before it is inserted into this list. The inserted item is the item itself and not a copy. If the item is already in this list, note that the index of the item to replace is before the removal of the item.
Parameters
  1. DOMPoint newItem
    The item which is to be inserted into the list.
  2. unsigned long index
    The index of the item which is to be replaced. The first item is number 0.
Returns
The inserted item.
Exceptions
DOMException, code NO_MODIFICATION_ALLOWED_ERR
Raised when the list cannot be modified.
DOMException, code INDEX_SIZE_ERR
Raised if the index number is greater than or equal to numberOfItems.
DOMPoint removeItem(unsigned long index)
Removes an existing item from the list.
Parameters
  1. unsigned long index
    The index of the item which is to be removed. The first item is number 0.
Returns
The removed item.
Exceptions
DOMException, code NO_MODIFICATION_ALLOWED_ERR
Raised when the list cannot be modified.
DOMException, code INDEX_SIZE_ERR
Raised if the index number is greater than or equal to numberOfItems.
DOMPoint appendItem(DOMPoint newItem)
Inserts a new item at the end of the list. If newItem is already in a list, it is removed from its previous list before it is inserted into this list. The inserted item is the item itself and not a copy.
Parameters
  1. DOMPoint newItem
    The item which is to be inserted. The first item is number 0.
Returns
The inserted item.
Exceptions
DOMException, code NO_MODIFICATION_ALLOWED_ERR
Raised when the list cannot be modified.
setter void (unsigned long index, DOMPoint newItem)
Replaces the item at index index with newItem.

7.14.2. Interface SVGTransform

SVGTransform is the interface for one of the component transformations within an SVGTransformList; thus, an SVGTransform object corresponds to a single component (e.g., 'scale(…)' or 'matrix(…)') within a ‘transform’ attribute specification.

[Constructor,
 Constructor(DOMMatrixReadOnly matrix),
 Constructor(DOMString value)]
interface SVGTransform {

  // Transform Types
  const unsigned short SVG_TRANSFORM_UNKNOWN = 0;
  const unsigned short SVG_TRANSFORM_MATRIX = 1;
  const unsigned short SVG_TRANSFORM_TRANSLATE = 2;
  const unsigned short SVG_TRANSFORM_SCALE = 3;
  const unsigned short SVG_TRANSFORM_ROTATE = 4;
  const unsigned short SVG_TRANSFORM_SKEWX = 5;
  const unsigned short SVG_TRANSFORM_SKEWY = 6;

  readonly attribute unsigned short type;
  readonly attribute DOMMatrixReadOnly matrix;
  readonly attribute float angle;

  void setMatrix(DOMMatrixReadOnly matrix);
  void setTranslate(float tx, float ty);
  void setScale(float sx, float sy);
  void setRotate(float angle, float cx, float cy);
  void setSkewX(float angle);
  void setSkewY(float angle);
};
Constructors:
SVGTransform()
Creates a new SVGTransform object whose type attribute is set to SVG_TRANSFORM_MATRIX and whose matrix attribute is set to an DOMMatrixReadOnly object that represents the identity matrix.
SVGTransform(DOMMatrixReadOnly matrix)
Creates a new SVGTransform object whose type attribute is set to SVG_TRANSFORM_MATRIX and whose matrix attribute is set to an DOMMatrixReadOnly object whose attributes are all initialized to be the same as the corresponding attributes in matrix.
SVGTransform(DOMString value)

Creates a new SVGTransform object whose type and matrix attributes are set to values determined by parsing value as a <transform-function>.

If value could not be parsed as a <transform-function>, then a SyntaxError is thrown.

Constants in group “Transform Types”:
SVG_TRANSFORM_UNKNOWN (unsigned short)
The unit type is not one of predefined types. It is invalid to attempt to define a new value of this type or to attempt to switch an existing value to this type.
SVG_TRANSFORM_MATRIX (unsigned short)
A 'matrix(…)' transformation.
SVG_TRANSFORM_TRANSLATE (unsigned short)
A 'translate(…)' transformation.
SVG_TRANSFORM_SCALE (unsigned short)
A 'scale(…)' transformation.
SVG_TRANSFORM_ROTATE (unsigned short)
A 'rotate(…)' transformation.
SVG_TRANSFORM_SKEWX (unsigned short)
A 'skewX(…)' transformation.
SVG_TRANSFORM_SKEWY (unsigned short)
A 'skewY(…)' transformation.
Attributes:
type (readonly unsigned short)
The type of the value as specified by one of the SVG_TRANSFORM_* constants defined on this interface.
matrix (readonly DOMMatrixReadOnly)

The matrix that represents this transformation. The matrix object is live, meaning that any changes made to the SVGTransform object are immediately reflected in the matrix object and vice versa. In case the matrix object is changed directly (i.e., without using the methods on the SVGTransform interface itself) then the type of the SVGTransform changes to SVG_TRANSFORM_MATRIX.

  • For SVG_TRANSFORM_MATRIX, the matrix contains the a, b, c, d, e, f values supplied by the user.
  • For SVG_TRANSFORM_TRANSLATE, e and f represent the translation amounts (a=1, b=0, c=0 and d=1).
  • For SVG_TRANSFORM_SCALE, a and d represent the scale amounts (b=0, c=0, e=0 and f=0).
  • For SVG_TRANSFORM_SKEWX and SVG_TRANSFORM_SKEWY, a, b, c and d represent the matrix which will result in the given skew (e=0 and f=0).
  • For SVG_TRANSFORM_ROTATE, a, b, c, d, e and f together represent the matrix which will result in the given rotation. When the rotation is around the center point (0, 0), e and f will be zero.
angle (readonly float)

A convenience attribute for SVG_TRANSFORM_ROTATE, SVG_TRANSFORM_SKEWX and SVG_TRANSFORM_SKEWY. It holds the angle that was specified.

For SVG_TRANSFORM_MATRIX, SVG_TRANSFORM_TRANSLATE and SVG_TRANSFORM_SCALE, angle will be zero.

Operations:
void setMatrix(DOMMatrixReadOnly matrix)

Sets the transform type to SVG_TRANSFORM_MATRIX, with parameter matrix defining the new transformation. The values from the parameter matrix are copied, the matrix parameter does not replace SVGTransform::matrix.

Parameters
  1. The new matrix for the transformation.
void setTranslate(float tx, float ty)
Sets the transform type to SVG_TRANSFORM_TRANSLATE, with parameters tx and ty defining the translation amounts.
Parameters
  1. float tx
    The translation amount in X.
  2. float ty
    The translation amount in Y.
void setScale(float sx, float sy)
Sets the transform type to SVG_TRANSFORM_SCALE, with parameters sx and sy defining the scale amounts.
Parameters
  1. float sx
    The scale amount in X.
  2. float sy
    The scale amount in Y.
void setRotate(float angle, float cx, float cy)
Sets the transform type to SVG_TRANSFORM_ROTATE, with parameter angle defining the rotation angle and parameters cx and cy defining the optional center of rotation.
Parameters
  1. float angle
    The rotation angle.
  2. float cx
    The x coordinate of center of rotation.
  3. float cy
    The y coordinate of center of rotation.
void setSkewX(float angle)
Sets the transform type to SVG_TRANSFORM_SKEWX, with parameter angle defining the amount of skew.
Parameters
  1. float angle
    The skew angle.
void setSkewY(float angle)
Sets the transform type to SVG_TRANSFORM_SKEWY, with parameter angle defining the amount of skew.
Parameters
  1. float angle
    The skew angle.

7.14.3. Interface SVGTransformList

This section needs to be updated to describe how it reflects the value of the ‘transform’ property, or just defer to css3-tranforms if everything is defined there.

This interface defines a list of SVGTransform objects.

The SVGTransformList and SVGTransform interfaces correspond to the various attributes which specify a set of transformations, such as the ‘transform’ property which is available for many of SVG's elements.

SVGTransformList has the same attributes and methods as other SVGxxxList interfaces. Implementers may consider using a single base class to implement the various SVGxxxList interfaces.

The supported property indices of an SVGTransformList object is all non-negative integers less than the length of the list.

An SVGTransformList object can be designated as read only, which means that attempts to modify the object will result in an exception being thrown, as described below.

interface SVGTransformList {

  readonly attribute unsigned long length;
  readonly attribute unsigned long numberOfItems;

  void clear();
  SVGTransform initialize(SVGTransform newItem);
  getter SVGTransform getItem(unsigned long index);
  SVGTransform insertItemBefore(SVGTransform newItem, unsigned long index);
  SVGTransform replaceItem(SVGTransform newItem, unsigned long index);
  SVGTransform removeItem(unsigned long index);
  SVGTransform appendItem(SVGTransform newItem);
  SVGTransform createSVGTransformFromMatrix(DOMMatrixReadOnly matrix);
  SVGTransform? consolidate();
  setter void (unsigned long index, SVGTransform newItem);
};
Attributes:
length (readonly unsigned long)
The number of items in the list.
numberOfItems (readonly unsigned long)
The number of items in the list.
Operations:
void clear()
Clears all existing current items from the list, with the result being an empty list.
Exceptions
DOMException, code NO_MODIFICATION_ALLOWED_ERR
Raised when the list is read only.
SVGTransform initialize(SVGTransform newItem)
Clears all existing current items from the list and re-initializes the list to hold a single item specified by the parameter. If newItem is in a list, then a new SVGTransform object is created with the same values as newItem and this item is inserted into the list. Otherwise, newItem itself is inserted into the list.
Parameters
  1. SVGTransform newItem
    The item which should become the only member of the list.
Returns
The item being inserted into the list.
Exceptions
DOMException, code NO_MODIFICATION_ALLOWED_ERR
Raised when the list is read only.
SVGTransform getItem(unsigned long index)
Returns the specified item from the list. The returned item is the item itself and not a copy. Any changes made to the item are immediately reflected in the list.
Parameters
  1. unsigned long index
    The index of the item from the list which is to be returned. The first item is number 0.
Returns
The selected item.
Exceptions
DOMException, code INDEX_SIZE_ERR
Raised if the index number is greater than or equal to numberOfItems.
SVGTransform insertItemBefore(SVGTransform newItem, unsigned long index)
Inserts a new item into the list at the specified position. The first item is number 0. If newItem is already in a list, then a new SVGTransform object is created with the same values as newItem and this item is inserted into the list. Otherwise, newItem itself is inserted into the list.
Parameters
  1. SVGTransform newItem
    The item which is to be inserted into the list.
  2. unsigned long index
    The index of the item before which the new item is to be inserted. The first item is number 0. If the index is equal to 0, then the new item is inserted at the front of the list. If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.
Returns
The inserted item.
Exceptions
DOMException, code NO_MODIFICATION_ALLOWED_ERR
Raised when the list is read only.
SVGTransform replaceItem(SVGTransform newItem, unsigned long index)
Replaces an existing item in the list with a new item. If newItem is already in a list, then a new SVGTransform object is created with the same values as newItem and this item is inserted into the list. Otherwise, newItem itself is inserted into the list.
Parameters
  1. SVGTransform newItem
    The item which is to be inserted into the list.
  2. unsigned long index
    The index of the item which is to be replaced. The first item is number 0.
Returns
The inserted item.
Exceptions
DOMException, code NO_MODIFICATION_ALLOWED_ERR
Raised when the list is read only.
DOMException, code INDEX_SIZE_ERR
Raised if the index number is greater than or equal to numberOfItems.
SVGTransform removeItem(unsigned long index)
Removes an existing item from the list.
Parameters
  1. unsigned long index
    The index of the item which is to be removed. The first item is number 0.
Returns
The removed item.
Exceptions
DOMException, code NO_MODIFICATION_ALLOWED_ERR
Raised when the list is read only.
DOMException, code INDEX_SIZE_ERR
Raised if the index number is greater than or equal to numberOfItems.
SVGTransform appendItem(SVGTransform newItem)
Inserts a new item at the end of the list. If newItem is already in a list, then a new SVGTransform object is created with the same values as newItem and this item is inserted into the list. Otherwise, newItem itself is inserted into the list.
Parameters
  1. SVGTransform newItem
    The item which is to be inserted. The first item is number 0.
Returns
The inserted item.
Exceptions
DOMException, code NO_MODIFICATION_ALLOWED_ERR
Raised when the list is read only.
SVGTransform createSVGTransformFromMatrix(DOMMatrixReadOnly matrix)

Creates an SVGTransform object which is initialized to transform of type SVG_TRANSFORM_MATRIX and whose values are the given matrix. The values from the parameter matrix are copied, the matrix parameter is not adopted as SVGTransform::matrix.

Parameters
  1. The matrix which defines the transformation.
Returns
The returned SVGTransform object.
SVGTransform consolidate()
Consolidates the list of separate SVGTransform objects by multiplying the equivalent transformation matrices together to result in a list consisting of a single SVGTransform object of type SVG_TRANSFORM_MATRIX. The consolidation operation creates new SVGTransform object as the first and only item in the list. The returned item is the item itself and not a copy. Any changes made to the item are immediately reflected in the list.
Returns
The resulting SVGTransform object which becomes single item in the list. If the list was empty, then a value of null is returned.
Exceptions
DOMException, code NO_MODIFICATION_ALLOWED_ERR
Raised when the list is read only.
setter void (unsigned long index, SVGTransform newItem)
Replaces the item at index index with newItem. If the list is read only, then a NoModificationAllowedError is thrown.

7.14.4. Interface SVGAnimatedTransformList

Used for the various attributes which specify a set of transformations, such as the ‘transform’ property which is available for many of SVG's elements, and which can be animated.
interface SVGAnimatedTransformList {
  readonly attribute SVGTransformList baseVal;
  readonly attribute SVGTransformList animVal;
};
Attributes:
baseVal (readonly SVGTransformList)
The base value of the given attribute before applying any animations.
animVal (readonly SVGTransformList)
A read only SVGTransformList representing the current animated value of the given attribute. If the given attribute is not currently being animated, then the SVGTransformList will have the same contents as baseVal. The object referenced by animVal will always be distinct from the one referenced by baseVal, even when the attribute is not animated.

7.14.5. Interface SVGPreserveAspectRatio

The SVGPreserveAspectRatio interface corresponds to the preserveAspectRatio attribute, which is available for some of SVG's elements.

An SVGPreserveAspectRatio object can be designated as read only, which means that attempts to modify the object will result in an exception being thrown, as described below.

interface SVGPreserveAspectRatio {

  // Alignment Types
  const unsigned short SVG_PRESERVEASPECTRATIO_UNKNOWN = 0;
  const unsigned short SVG_PRESERVEASPECTRATIO_NONE = 1;
  const unsigned short SVG_PRESERVEASPECTRATIO_XMINYMIN = 2;
  const unsigned short SVG_PRESERVEASPECTRATIO_XMIDYMIN = 3;
  const unsigned short SVG_PRESERVEASPECTRATIO_XMAXYMIN = 4;
  const unsigned short SVG_PRESERVEASPECTRATIO_XMINYMID = 5;
  const unsigned short SVG_PRESERVEASPECTRATIO_XMIDYMID = 6;
  const unsigned short SVG_PRESERVEASPECTRATIO_XMAXYMID = 7;
  const unsigned short SVG_PRESERVEASPECTRATIO_XMINYMAX = 8;
  const unsigned short SVG_PRESERVEASPECTRATIO_XMIDYMAX = 9;
  const unsigned short SVG_PRESERVEASPECTRATIO_XMAXYMAX = 10;

  // Meet-or-slice Types
  const unsigned short SVG_MEETORSLICE_UNKNOWN = 0;
  const unsigned short SVG_MEETORSLICE_MEET = 1;
  const unsigned short SVG_MEETORSLICE_SLICE = 2;

  attribute unsigned short align;
  attribute unsigned short meetOrSlice;
};
Constants in group “Alignment Types”:
SVG_PRESERVEASPECTRATIO_UNKNOWN (unsigned short)
The enumeration was set to a value that is not one of predefined types. It is invalid to attempt to define a new value of this type or to attempt to switch an existing value to this type.
SVG_PRESERVEASPECTRATIO_NONE (unsigned short)
Corresponds to value 'none' for attribute preserveAspectRatio.
SVG_PRESERVEASPECTRATIO_XMINYMIN (unsigned short)
Corresponds to value 'xMinYMin' for attribute preserveAspectRatio.
SVG_PRESERVEASPECTRATIO_XMIDYMIN (unsigned short)
Corresponds to value 'xMidYMin' for attribute preserveAspectRatio.
SVG_PRESERVEASPECTRATIO_XMAXYMIN (unsigned short)
Corresponds to value 'xMaxYMin' for attribute preserveAspectRatio.
SVG_PRESERVEASPECTRATIO_XMINYMID (unsigned short)
Corresponds to value 'XMinYMid' for attribute preserveAspectRatio.
SVG_PRESERVEASPECTRATIO_XMIDYMID (unsigned short)
Corresponds to value 'xMidYMid' for attribute preserveAspectRatio.
SVG_PRESERVEASPECTRATIO_XMAXYMID (unsigned short)
Corresponds to value 'xMaxYMid' for attribute preserveAspectRatio.
SVG_PRESERVEASPECTRATIO_XMINYMAX (unsigned short)
Corresponds to value 'xMinYMax' for attribute preserveAspectRatio.
SVG_PRESERVEASPECTRATIO_XMIDYMAX (unsigned short)
Corresponds to value 'xMidYMax' for attribute preserveAspectRatio.
SVG_PRESERVEASPECTRATIO_XMAXYMAX (unsigned short)
Corresponds to value 'xMaxYMax' for attribute preserveAspectRatio.
Constants in group “Meet-or-slice Types”:
SVG_MEETORSLICE_UNKNOWN (unsigned short)
The enumeration was set to a value that is not one of predefined types. It is invalid to attempt to define a new value of this type or to attempt to switch an existing value to this type.
SVG_MEETORSLICE_MEET (unsigned short)
Corresponds to value 'meet' for attribute preserveAspectRatio.
SVG_MEETORSLICE_SLICE (unsigned short)
Corresponds to value 'slice' for attribute preserveAspectRatio.
Attributes:
align (unsigned short)
The type of the alignment value as specified by one of the SVG_PRESERVEASPECTRATIO_* constants defined on this interface.
Exceptions on setting
DOMException, code NO_MODIFICATION_ALLOWED_ERR
Raised when the object is read only.
meetOrSlice (unsigned short)
The type of the meet-or-slice value as specified by one of the SVG_MEETORSLICE_* constants defined on this interface.
Exceptions on setting
DOMException, code NO_MODIFICATION_ALLOWED_ERR
Raised when the object is read only.

7.14.6. Interface SVGAnimatedPreserveAspectRatio

Used for attributes of type SVGPreserveAspectRatio which can be animated.
interface SVGAnimatedPreserveAspectRatio {
  readonly attribute SVGPreserveAspectRatio baseVal;
  readonly attribute SVGPreserveAspectRatio animVal;
};
Attributes:
baseVal (readonly SVGPreserveAspectRatio)
The base value of the given attribute before applying any animations.
animVal (readonly SVGPreserveAspectRatio)
A read only SVGPreserveAspectRatio representing the current animated value of the given attribute. If the given attribute is not currently being animated, then the SVGPreserveAspectRatio will have the same contents as baseVal. The object referenced by animVal will always be distinct from the one referenced by baseVal, even when the attribute is not animated.
SVG 2 – 09 April 2015 TopContentsPreviousNextElementsAttributesProperties