SVG
FSharp.ViewEngine provides a maintained SVG 2 production subset for icons, charts, gradients, clipping, reusable symbols, text, and accessible inline graphics.
On this page
Overview
FSharp.ViewEngine provides a maintained SVG 2 production subset for icons, charts, gradients, clipping, reusable symbols, text, and accessible inline graphics.
Support Policy
The Svg type intentionally covers 21 common elements rather than every SVG 2 feature. Unsupported filters, animation, metadata, and specialized elements remain available through the generic trusted-name escape hatches.
SVG-specific helpers complement the global attributes on Html. Continue using _id, _class, _style, _href, _role, and the WAI-ARIA helpers from Html.
Setup
Open both static types when building inline SVG:
open FSharp.ViewEngine
open type Html
open type SvgThe SVG text and title builders are named textElement and titleElement so opening Svg does not shadow Html.text or Html.title. useElement avoids the F# use keyword.
Element Reference
Structure and descriptions: svg, g, defs, symbol, useElement, titleElement, and desc.
Shapes: path, circle, rect, line, polyline, polygon, and ellipse.
Resources and paint: clipPath, mask, linearGradient, radialGradient, and stop.
Text: textElement and tspan.
Numeric and Length Values
Geometry and numeric presentation helpers accept integers, invariant-culture floating-point values, and—where SVG permits lengths, percentages, or lists—strings. Root width and height retain numeric Svg._width and Svg._height helpers; use the existing HTML string helpers for CSS lengths.
svg {
Svg._width 24
Svg._height 24.5
Html._width "100%"
circle { _cx "50%"; _cy "50%"; _r 7.5 }
}Icon Example
let checkIcon =
svg {
_viewBox "0 0 24 24"
_preserveAspectRatio "xMidYMid meet"
Svg._width 24
Svg._height 24
_fill "none"
_stroke "currentColor"
_strokeWidth 1.5
_strokeLinecap "round"
_strokeLinejoin "round"
_vectorEffect "non-scaling-stroke"
path {
_d "M5 13l4 4L19 7"
_pathLength 1.0
}
}Chart and Text Example
svg {
_viewBox "0 0 400 200"
_role "img"
_ariaLabel "Revenue trend rising across five periods"
g {
_transform "translate(40 10)"
rect {
_x 0; _y 0; Svg._width 320; Svg._height 160; _rx 8
_fill "#ffffff"; _stroke "#cbd5e1"
}
polygon {
_points "0,140 80,100 160,120 240,40 320,20 320,160 0,160"
_fill "#10b981"; _fillOpacity 0.14
}
line { _x1 0; _y1 160; _x2 320; _y2 160; _stroke "#94a3b8" }
polyline {
_points "0,140 80,100 160,120 240,40 320,20"
_fill "none"; _stroke "#059669"; _strokeWidth 4
_strokeLinecap "round"; _strokeLinejoin "round"
}
ellipse { _cx 240; _cy 40; _rx 6; _ry 6; _fill "#047857" }
textElement {
_x 160; _y 184; _textAnchor "middle"
_fontFamily "sans-serif"; _fontSize "12px"; _fill "#475569"
tspan { "Revenue" }
}
}
}Gradients, Clipping, Masking, and Reuse
svg {
_viewBox "0 0 400 180"
defs {
linearGradient {
_id "svg-brand-gradient"
_x1 "0%"; _y1 "0%"; _x2 "100%"; _y2 "100%"
stop { _offset "0%"; _stopColor "#0ea5e9" }
stop { _offset "100%"; _stopColor "#6366f1" }
}
radialGradient {
_id "svg-spotlight"
stop { _offset "35%"; _stopColor "white" }
stop { _offset "100%"; _stopColor "black" }
}
clipPath {
_id "svg-card-clip"
rect { _x 20; _y 20; Svg._width 360; Svg._height 140; _rx 28 }
}
mask {
_id "svg-fade-mask"
rect {
_x 20; _y 20; Svg._width 360; Svg._height 140
_fill "url(#svg-spotlight)"
}
}
symbol {
_id "svg-dot"
_viewBox "0 0 10 10"
circle { _cx 5; _cy 5; _r 5 }
}
}
g {
_clipPath "url(#svg-card-clip)"
rect { _x 20; _y 20; Svg._width 360; Svg._height 140; _fill "url(#svg-brand-gradient)" }
g {
_fill "white"; _mask "url(#svg-fade-mask)"
useElement { _href "#svg-dot"; _x 80; _y 70; Svg._width 40; Svg._height 40 }
useElement { _href "#svg-dot"; _x 180; _y 45; Svg._width 70; Svg._height 70 }
useElement { _href "#svg-dot"; _x 300; _y 75; Svg._width 30; Svg._height 30 }
}
}
}Accessibility
For an informative graphic, give the root an image role and connect direct child titleElement and desc elements with _ariaLabelledby. SVG Accessibility API Mappings expose these children as the accessible name and description.
svg {
_role "img"
_ariaLabelledby "sales-title sales-description"
titleElement { _id "sales-title"; "Quarterly sales" }
desc {
_id "sales-description"
"Sales increased in each quarter."
}
// chart geometry
}Hide a purely decorative SVG from assistive technology:
svg {
_ariaHidden true
path { _d "M5 13l4 4L19 7" }
}Linking and Namespaces
SVG 2 uses the unnamespaced href attribute. Use Html._href with useElement and do not emit deprecated xlink:href. Add _xmlns when producing standalone SVG markup; it is optional for inline SVG parsed as HTML.
symbol { _id "check"; path { _d "M5 13l4 4L19 7" } }
useElement { _href "#check" }Attribute Reference
Viewport and global presentation: _viewBox, _preserveAspectRatio, _xmlns, _transform, _opacity, and _vectorEffect.
Fill and stroke: _fill, _fillOpacity, _fillRule, _stroke, _strokeWidth, _strokeOpacity, _strokeLinecap, _strokeLinejoin, _strokeMiterlimit, _strokeDasharray, and _strokeDashoffset.
Geometry: _x, _y, _x1, _y1, _x2, _y2, _cx, _cy, _r, _rx, _ry, _width, _height, _d, _points, and _pathLength.
Resources: _clipRule, _clipPath, _clipPathUnits, _mask, _maskUnits, _maskContentUnits, _gradientUnits, _gradientTransform, _spreadMethod, _fx, _fy, _fr, _offset, _stopColor, and _stopOpacity.
Text: _dx, _dy, _textAnchor, _dominantBaseline, _fontFamily, _fontSize, _fontWeight, _textLength, and _lengthAdjust.
Unsupported SVG
Use Html.el for an SVG element outside the maintained production subset and Html._attr for an unsupported attribute. Names passed to both helpers are trusted markup tokens and are not validated.
svg {
Html.el "filter" {
_id "blur"
Html.el "feGaussianBlur" {
_attr ("stdDeviation", "2")
}
}
}