CSS 与布局 / 🔷 SVG × CSS:一块能被 CSS 管的画布 / viewBox:SVG 自带的相机 待审核 2 / 9
viewBox · 坐标系

viewBox:SVG 自带的相机

SVG 有两套尺寸。widthheight 是元素在页面上占的窗口(viewport,CSS 像素);viewBox="min-x min-y w h" 在窗口里架了一台相机,决定拍下用户坐标系的哪一块、放多大。改后两个值相当于推拉镜头(缩放),改前两个值相当于平移取景框。绘图坐标和显示像素就此解耦。

1 · 相机的四个值

图 1-1 · 外面靛蓝紫实线框是固定的 viewport(240 × 180 像素),里面的房子画在 user 坐标 0..120 × 0..90。可拖四个滑块看相机怎么动。

注 · 缩放倍数等于 viewport 除以 viewBox。把 width 从 120 拖到 60,相机只拍 60 个 user 单位却仍铺满 240 像素,内容因此放大 2 倍。描边也会跟着变粗——勾上 non-scaling-stroke,描边宽度就按屏幕像素算、不再随相机缩放,地图线与图标常用这一招。

2 · preserveAspectRatio

viewBox 的宽高比不等于 viewport 的宽高比,浏览器得决定怎么塞。这与 CSS object-fit 是同一套思想:meet 相当于 contain(整图可见、留白),slice 相当于 cover(填满、裁掉溢出);前缀的九种 align 决定往哪靠。

图 2-1 · viewport 是 220 × 150(扁),viewBox 是 0 0 100 100(正方)。可切换 align 与 meet / slice,看四个橙角的去留。

建议 · 盯住四个橙角就能读懂这套规则:meet 时方形图缩到 150 高、左右留白,四角都在;切 slice 它被放大到铺满 220 宽,上下溢出的部分被裁掉,此时 alignYMin 就保住顶边两角、裁底边。xMidYMid meet 是默认值,也是 <img> 那种「居中完整显示」的来源。

3 · 嵌套的坐标系

<symbol> 和嵌套的 <svg> 都能带自己的 viewBox,相当于在父坐标系里开一扇新窗、重新定义内部的 user 单位。这正是嵌入矩阵一页 sprite 中每个 <use> 都能独立缩放贴合的原因。