I am struggling to understand exactly how min-x
and min-y
on viewBox
works, from a technical standpoint (without metaphors).
Two helpful resources I have spent quite a lot of time on:
- SVG 1.1 (official specification) - 7.7 The ‘viewBox’ attribute
- Understanding SVG Coordinate Systems and Transformations (Part 1) - by Sara Soueidan
According to the SVG 1.1 specification:
The value of the ‘viewBox’ attribute is a list of four numbers , , and , 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’.
And:
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).
And:
(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 or .)
So, my expectation was that defining a viewBox is the same as:
- First scaling the viewbox, so it fills the viewport (assuming same aspect ratio on viewport and viewBox)
- Then translating the viewBox, so it is placed in the viewport according to
min-x
andmin-y
viewBox attributes.
If we look at Sara's two examples, starting here, that is not what seems to be happening.
In her first example (<svg width="800" height="600" viewbox="100 100 200 150">...</svg>
), it looks like:
- viewBox is placed according to
min-x
/min-y
in viewport - viewBox is scaled to same size as viewport
- viewBox origin is translated (moved) to coincide with viewport origin
In her second example however (<svg width="800" height="600" viewbox="-100 -100 400 300">...</svg>
), it looks like a completely different order:
- viewBox is scaled to same size as viewport
- viewBox origin is translated (moved) somehow in the opposite direction of what viewBox
min-x
min-y
indicates. It does not coincide with viewport origin - This is different from the first example
Thus, I recognize that I do not fully understand it, because technically it should work the same way in both cases.
Finally, in Sara's examples, I do not understand why the blue coordinate system (user coordinate system) does not itself move, to (100, 100) or (-100, -100) in viewport coordinate system. I thought viewBox was supposed to translate and scale the user coordinate system?
EDIT:
According to this SO answer, min-x
and min-y
does indeed follow my first set of steps. The viewBox origin is placed in the viewport according to min-x
and min-y
, and then translated so its origin is on top of viewport origin. It is then (before or after) scaled to fill viewport.
If that is correct, I have a hard time understanding why the blue user coordinate system in Sara's examples do not always end up with its origin on top of viewport origin. After all, viewBox should modify the user coordinate system.
vb-
values), and one in a renderer/browser (e-
values) and then draws every grafical content in the canvas in the rendering rectangle such that the rectangles "fit", without any regard to content. The grafical content can be everywhere in the canvas, and can thus end up everywhere in the renderer. Only afterwards everything outside the rendering rectangle is chopped off, everything inside is visible. – ccprog