Basic SVG: structure, coordinates and primitives
1. The <svg> tag as the root of the document
Every SVG document begins with a root <svg> element that defines the drawing canvas and its parameters.
Basic attributes
width and height
Set the physical dimensions of the SVG area on the page (in pixels, percentages, or other CSS units).
<svg width="300" height="200">
<!-- content -->
</svg>
If you do not specify these attributes, the SVG will take up 100% of the container's width (but the height may be 0 if viewBox is not set).
viewBox
The most important attribute for responsiveness. Defines the internal coordinate system and content proportions.
Syntax: viewBox="min-x min-y width height"
<svg width="300" height="200" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="coral"/>
</svg>
What happens: The circle is drawn in the coordinates of the 100×100 internal space, but stretched to the physical 300×200 pixels. The content is scaled automatically.
Practical meaning: You can change width/height for different screens, and viewBox will remain unchanged - the proportions will be preserved.
Example of working with viewBox: ⭐
- WITHOUT the viewBox attribute (Problem) The browser maps coordinates 1 to 1. Since the container (100px) is smaller than the shape (200px), we will only see the upper left corner of the circle. The center of the circle (coordinate 100, 100) will be in the very corner of the container.
<!-- The drawing is cropped -->
<svg width="100" height="100">
<!-- A circle with a center at point 100,100 and a radius of 100 -->
<circle cx="100" cy="100" r="100" fill="crimson" />
</svg>
Result: Only a quarter of the circle is visible. The rest is hidden behind the borders.
- With the viewBox attribute (Solution) We add viewBox="0 0 200 200". These numbers tell the browser: “All our graphics are in the space from 0 to 200 on the X and Y axes. Please compress this space so that it fits completely into a 100×100 pixel block.”
<!-- The drawing is scaled -->
<svg width="100" height="100" viewBox="0 0 200 200">
<!-- The same circle -->
<circle cx="100" cy="100" r="100" fill="crimson" />
</svg>
Result: The circle is fully visible. The browser automatically reduced the image (scale 1:2) so that the entire area specified in the viewBox fits into the width and height of the svg.
The preserveAspectRatio attribute
This attribute controls the display of graphics in cases where the proportions of the drawing itself (set in the viewBox) do not match with the dimensions of the container (width and height). Its main task is to determine how exactly the image should be scaled and aligned, to avoid unwanted distortion (stretching or squashing).
Syntax: preserveAspectRatio="alignment mode"
- Alignment (Align) The first part of the command indicates to which side of the container the image should be "pinned". It is formed from the coordinates on the X (horizontal) and Y (vertical) axes:
Min- left edge or top;Mid- center;Max- right edge or bottom.; Example: xMidYMid means alignment strictly in the center (on both axes).
- Scaling mode (Meet or Slice)
The second part determines how the image fills the space:
- meet - Fit completely. The image is scaled so that it is fully visible. The proportions are preserved, but there may be empty areas at the edges (analogous to the background-size: contain property in CSS).
- slice - Fill the space. The image is enlarged to cover the entire available area. The proportions are preserved, but the parts of the drawing that go beyond the borders will be cropped (analogous to the background-size: cover property in CSS).
Example: Consider a situation where a square image is placed in a rectangular container
<svg width="200" height="100" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet">
<rect width="100" height="100" fill="teal"/>
</svg>
Result:
In this case, the square from the viewBox (100×100) is placed in a wide container (200×100). Thanks to the xMidYMid meet value, the figure is not stretched in width, but is neatly scaled and placed exactly in the center of the canvas. There will be free space to the left and right of the square.
2. SVG coordinate system
Origin of coordinates
By default, the point (0, 0) is in the upper left corner of the canvas.
- X-axis: From left to right (positive values to the right)
- Y-axis: From top to bottom (positive values down) ⚠️
Important: Unlike in school mathematics, the Y-axis is directed downwards!
<svg width="200" height="200" viewBox="0 0 200 200">
<!-- Point (0,0) - upper left corner -->
<circle cx="0" cy="0" r="10" fill="red"/>
<!-- Point (100,100) - center of the canvas -->
<circle cx="100" cy="100" r="10" fill="blue"/>
<!-- Point (200,200) - lower right corner -->
<circle cx="200" cy="200" r="10" fill="green"/>
</svg>
Units of measurement
If the unit is not specified explicitly, user units from the viewBox are used. You can use:
px(pixels)em,rem(relative units)%(percentage of parent size)cm,mm,in,pt(physical units)
<svg width="10cm" height="5cm" viewBox="0 0 100 50">
<rect x="10" y="10" width="30" height="20" fill="purple"/>
</svg>
3. Grouping elements: the <g> tag
The <g> (group) element combines several shapes into a logical group. This allows you to:
- Apply common styles to the entire group
- Transform elements together (rotation, offset)
- Structure the code
Attribute inheritance
Child elements inherit the group's attributes (unless they override them).
<svg width="200" height="200" viewBox="0 0 200 200">
<g fill="orange" stroke="black" stroke-width="2">
<!-- Both circles will get an orange fill and a black stroke -->
<circle cx="50" cy="50" r="30"/>
<circle cx="120" cy="50" r="30"/>
</g>
<g fill="none" stroke="blue" stroke-width="3">
<!-- These shapes have no fill, but have a blue stroke -->
<rect x="20" y="100" width="60" height="40"/>
<rect x="100" y="100" width="60" height="40"/>
</g>
</svg>
Group transformations
<svg width="200" height="200" viewBox="0 0 200 200">
<g transform="rotate(45 100 100)">
<!-- The entire group is rotated 45° around the point (100,100) -->
<rect x="80" y="80" width="40" height="40" fill="crimson"/>
<circle cx="100" cy="100" r="5" fill="white"/>
</g>
</svg>
4. Comments, metadata and rendering order
Comments
Standard XML syntax is used:
<svg width="100" height="100">
<!-- This is a comment: it is not displayed in the browser -->
<circle cx="50" cy="50" r="40" fill="gold"/>
</svg>
Metadata
The <title> and <desc> tags improve accessibility (for screen readers) and SEO:
<svg width="100" height="100" role="img" aria-labelledby="icon-title">
<title id="icon-title">House icon</title>
<desc>A simple house icon with a triangular roof</desc>
<rect x="20" y="50" width="60" height="40" fill="brown"/>
<polygon points="50,20 10,50 90,50" fill="darkred"/>
</svg>
Rendering order (z-index)
SVG has no z-index attribute. Elements are drawn in the order they appear in the code:
- The first element is in the background
- The last element is in the foreground
<svg width="200" height="100">
<!-- 1. Red rectangle (back layer) -->
<rect x="20" y="20" width="80" height="60" fill="red"/>
<!-- 2. Blue circle (middle layer) -->
<circle cx="80" cy="50" r="30" fill="blue"/>
<!-- 3. Green square (front layer) -->
<rect x="100" y="30" width="40" height="40" fill="green"/>
</svg>
Result: The green square overlaps the blue circle, which overlaps the red rectangle.