Skip to main content
HTVG elements define the structure of your graphic. All elements are defined in the Element enum.

Element Enum

Root element type that can be Box, Flex, Text, or Image.
#[derive(Debug, Clone, Deserialize)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum Element {
    Box {
        #[serde(default)]
        style: BoxStyle,
        #[serde(default)]
        children: Vec<Element>,
    },
    Flex {
        #[serde(default)]
        style: FlexStyle,
        #[serde(default)]
        children: Vec<Element>,
    },
    Text {
        content: String,
        #[serde(default)]
        style: TextStyle,
    },
    Image {
        src: String,
        width: f32,
        height: f32,
        #[serde(default)]
        style: ImageStyle,
    },
}

Box Element

Block container element for grouping children.
style
BoxStyle
default:"{}"
Styling properties for the box
children
Vec<Element>
default:"[]"
Child elements

BoxStyle

#[derive(Debug, Clone, Default, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct BoxStyle {
    // Display
    pub display: Option<Display>,

    // Dimensions
    pub width: Option<Dimension>,
    pub height: Option<Dimension>,
    pub min_width: Option<Dimension>,
    pub max_width: Option<Dimension>,
    pub min_height: Option<Dimension>,
    pub max_height: Option<Dimension>,

    // Spacing
    pub margin: Option<Spacing>,
    pub padding: Option<Spacing>,

    // Visual
    pub background_color: Option<Color>,
    pub border_width: Option<f32>,
    pub border_color: Option<Color>,
    pub border_radius: Option<BorderRadius>,
    pub opacity: Option<f32>,
}

Example

{
  "type": "box",
  "style": {
    "width": 200,
    "height": 100,
    "backgroundColor": "#ff0000",
    "borderRadius": 8,
    "padding": "10 20"
  },
  "children": []
}

Flex Element

Flexbox container element with flex layout properties.
style
FlexStyle
default:"{}"
Styling and flex properties
children
Vec<Element>
default:"[]"
Child elements laid out using flexbox

FlexStyle

#[derive(Debug, Clone, Default, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct FlexStyle {
    // Display
    pub display: Option<Display>,

    // Dimensions
    pub width: Option<Dimension>,
    pub height: Option<Dimension>,
    pub min_width: Option<Dimension>,
    pub max_width: Option<Dimension>,
    pub min_height: Option<Dimension>,
    pub max_height: Option<Dimension>,

    // Spacing
    pub margin: Option<Spacing>,
    pub padding: Option<Spacing>,

    // Flex container
    pub flex_direction: Option<FlexDirection>,
    pub justify_content: Option<JustifyContent>,
    pub align_items: Option<AlignItems>,
    pub gap: Option<f32>,
    pub flex_wrap: Option<FlexWrap>,

    // Visual
    pub background_color: Option<Color>,
    pub border_width: Option<f32>,
    pub border_color: Option<Color>,
    pub border_radius: Option<BorderRadius>,
    pub opacity: Option<f32>,
}

Flex Properties

flex_direction
FlexDirection
Layout direction: row, column, row-reverse, column-reverse (default: row)
justify_content
JustifyContent
Main axis alignment: flex-start, flex-end, center, space-between, space-around, space-evenly (default: flex-start)
align_items
AlignItems
Cross axis alignment: flex-start, flex-end, center, stretch, baseline (default: stretch)
gap
f32
Spacing between flex items in pixels
flex_wrap
FlexWrap
Wrapping behavior: nowrap, wrap (default: nowrap)

Example

{
  "type": "flex",
  "style": {
    "flexDirection": "column",
    "width": 400,
    "padding": 20,
    "backgroundColor": "#fff",
    "gap": 10,
    "alignItems": "center"
  },
  "children": [
    {
      "type": "text",
      "content": "Hello World",
      "style": { "fontSize": 24, "color": "#333" }
    }
  ]
}

Text Element

Text leaf element with typography controls.
content
String
required
The text content to render
style
TextStyle
default:"{}"
Typography and styling properties

TextStyle

#[derive(Debug, Clone, Default, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct TextStyle {
    // Typography
    pub font_family: Option<String>,
    pub font_size: Option<f32>,
    pub font_weight: Option<FontWeight>,
    pub line_height: Option<f32>,
    pub text_align: Option<TextAlign>,
    pub color: Option<Color>,
    pub letter_spacing: Option<f32>,
    pub text_rendering: Option<TextRendering>,

    // Flex child properties
    pub flex_grow: Option<f32>,
    pub flex_shrink: Option<f32>,
}

Typography Properties

font_family
String
Font family name (must match a registered font)
font_size
f32
Font size in pixels
font_weight
FontWeight
Font weight: 100-900 or "normal" (400), "bold" (700)
line_height
f32
Line height multiplier
text_align
TextAlign
Text alignment: left, center, right, justify (default: left)
text_rendering
TextRendering
Rendering mode: text (default, uses SVG <text>), vector (converts to paths)

Example

{
  "type": "text",
  "content": "Hello World",
  "style": {
    "fontSize": 24,
    "fontWeight": "bold",
    "color": "#333333",
    "textAlign": "center",
    "letterSpacing": 0.5
  }
}

Image Element

Image element with intrinsic dimensions and object-fit support.
src
String
required
Image URL or data URI
width
f32
required
Intrinsic width of the image in pixels
height
f32
required
Intrinsic height of the image in pixels
style
ImageStyle
default:"{}"
Image styling properties

ImageStyle

#[derive(Debug, Clone, Default, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct ImageStyle {
    // Dimensions (overrides intrinsic if set)
    pub width: Option<Dimension>,
    pub height: Option<Dimension>,
    pub min_width: Option<Dimension>,
    pub max_width: Option<Dimension>,
    pub min_height: Option<Dimension>,
    pub max_height: Option<Dimension>,

    // Spacing
    pub margin: Option<Spacing>,

    // Image-specific
    pub object_fit: Option<ObjectFit>,

    // Visual
    pub border_radius: Option<BorderRadius>,
    pub opacity: Option<f32>,

    // Flex child properties
    pub flex_grow: Option<f32>,
    pub flex_shrink: Option<f32>,
}
object_fit
ObjectFit
Image scaling mode: contain, cover, fill (default: contain)

Example

{
  "type": "image",
  "src": "https://example.com/image.jpg",
  "width": 800,
  "height": 600,
  "style": {
    "width": 400,
    "objectFit": "cover",
    "borderRadius": 8
  }
}

Dimension Types

Dimension

A dimension value that can be a number (pixels) or percentage string.
#[derive(Debug, Clone, Deserialize)]
#[serde(untagged)]
pub enum Dimension {
    Px(f32),
    Percent(String), // e.g., "50%"
}
Examples: 400, "50%"

Spacing

Spacing value for margin/padding - can be a single number or space-separated string.
#[derive(Debug, Clone, Deserialize)]
#[serde(untagged)]
pub enum Spacing {
    Uniform(f32),
    Multi(String), // e.g., "10 20" or "10 20 30 40"
}
Examples:
  • 10 - 10px on all sides
  • "10 20" - 10px vertical, 20px horizontal
  • "10 20 30 40" - top, right, bottom, left

BorderRadius

Border radius - single value or per-corner.
#[derive(Debug, Clone, Deserialize)]
#[serde(untagged)]
pub enum BorderRadius {
    Uniform(f32),
    Multi(String), // e.g., "8 8 0 0"
}
Examples:
  • 8 - 8px on all corners
  • "8 8 0 0" - top-left, top-right, bottom-right, bottom-left

Color

Color value - supports hex and rgb/rgba functions.
pub struct Color {
    pub r: u8,
    pub g: u8,
    pub b: u8,
    pub a: u8,
}
Supported formats:
  • Hex: "#RGB", "#RRGGBB", "#RRGGBBAA"
  • Functions: "rgb(255, 0, 0)", "rgba(0, 0, 255, 0.5)"
  • Named: "transparent", "black", "white", "red", "green", "blue"

Build docs developers (and LLMs) love