Skip to main content
HTVG supports a comprehensive set of style properties inspired by CSS. All style properties are optional and use sensible defaults.

Property Categories

Control the size of elements with width, height, and constraints
Margin and padding using flexible syntax
Colors, borders, and opacity
Flex container and child properties
Font properties for text elements

Dimension Properties

Dimension properties control the size of elements. They accept either pixel values (numbers) or percentage strings.

Width & Height

width
number | string
Element width. Examples:
  • 400 - 400 pixels
  • "50%" - 50% of parent width
height
number | string
Element height. Examples:
  • 200 - 200 pixels
  • "100%" - 100% of parent height
{
  "type": "box",
  "style": {
    "width": 400,
    "height": "50%"
  }
}

Size Constraints

minWidth
number | string
Minimum width constraint
maxWidth
number | string
Maximum width constraint
minHeight
number | string
Minimum height constraint
maxHeight
number | string
Maximum height constraint
{
  "type": "flex",
  "style": {
    "width": "100%",
    "maxWidth": 600,
    "minWidth": 300
  }
}

Dimension Type Implementation

From crates/htvg-core/src/element.rs:45-64:
pub enum Dimension {
    Px(f32),
    Percent(String), // e.g., "50%"
}

impl Dimension {
    pub fn to_px(&self, container_size: f32) -> f32 {
        match self {
            Dimension::Px(px) => *px,
            Dimension::Percent(s) => {
                let percent = s.trim_end_matches('%').parse::<f32>().unwrap_or(0.0);
                container_size * percent / 100.0
            }
        }
    }
}

Spacing Properties

Spacing properties (margin and padding) use a flexible syntax supporting 1-4 values.

Margin

margin
number | string
default:"0"
Outer spacing around the element. Syntax:
  • Single value: 20 - All sides
  • Two values: "10 20" - Vertical, Horizontal
  • Three values: "10 20 30" - Top, Horizontal, Bottom
  • Four values: "10 20 30 40" - Top, Right, Bottom, Left
{
  "type": "box",
  "style": {
    "margin": 20
  }
}
All sides get 20px margin.

Padding

padding
number | string
default:"0"
Inner spacing inside the element. Uses the same syntax as margin.
{
  "type": "flex",
  "style": {
    "padding": "20 32",
    "backgroundColor": "#ffffff"
  }
}

Spacing Implementation

From crates/htvg-core/src/element.rs:66-100:
pub enum Spacing {
    Uniform(f32),
    Multi(String), // e.g., "10 20" or "10 20 30 40"
}

impl Spacing {
    pub fn to_edges(&self) -> [f32; 4] {
        match self {
            Spacing::Uniform(v) => [*v, *v, *v, *v],
            Spacing::Multi(s) => {
                let parts: Vec<f32> = s
                    .split_whitespace()
                    .filter_map(|p| p.parse().ok())
                    .collect();
                match parts.len() {
                    1 => [parts[0], parts[0], parts[0], parts[0]],
                    2 => [parts[0], parts[1], parts[0], parts[1]], // vertical, horizontal
                    3 => [parts[0], parts[1], parts[2], parts[1]], // top, horizontal, bottom
                    4 => [parts[0], parts[1], parts[2], parts[3]], // top, right, bottom, left
                    _ => [0.0, 0.0, 0.0, 0.0],
                }
            }
        }
    }
}

Visual Properties

Colors

backgroundColor
string
Background color. Supports:
  • Hex: "#fff", "#ffffff", "#ffffffaa" (with alpha)
  • RGB: "rgb(255, 255, 255)"
  • RGBA: "rgba(255, 255, 255, 0.5)"
  • Named: "red", "blue", "green", "black", "white", "transparent"
borderColor
string
Border color (same format as backgroundColor)
color
string
default:"#000000"
Text color for Text elements
{
  "type": "box",
  "style": {
    "backgroundColor": "#2563eb",
    "borderColor": "#1e40af"
  }
}

Color Implementation

From crates/htvg-core/src/element.rs:141-240:
pub struct Color {
    pub r: u8,
    pub g: u8,
    pub b: u8,
    pub a: u8,
}

impl Color {
    pub const TRANSPARENT: Self = Self { r: 0, g: 0, b: 0, a: 0 };
    pub const BLACK: Self = Self { r: 0, g: 0, b: 0, a: 255 };
    pub const WHITE: Self = Self { r: 255, g: 255, b: 255, a: 255 };

    pub fn parse(s: &str) -> Option<Self> {
        // Supports:
        // - Hex: #RGB, #RRGGBB, #RRGGBBAA
        // - rgb(r, g, b) / rgba(r, g, b, a)
        // - Named colors
    }

    pub fn to_css(&self) -> String {
        if self.a == 255 {
            format!("#{:02x}{:02x}{:02x}", self.r, self.g, self.b)
        } else if self.a == 0 {
            "none".to_string()
        } else {
            format!("rgba({},{},{},{:.3})", self.r, self.g, self.b, self.a as f32 / 255.0)
        }
    }
}

Borders

borderWidth
number
default:"0"
Border thickness in pixels
borderRadius
number | string
default:"0"
Corner radius. Syntax:
  • Single value: 8 - All corners
  • Two values: "8 4" - Top-left/bottom-right, top-right/bottom-left
  • Four values: "8 8 0 0" - Top-left, top-right, bottom-right, bottom-left
{
  "type": "box",
  "style": {
    "backgroundColor": "#ffffff",
    "borderWidth": 1,
    "borderColor": "#e0e0e0",
    "borderRadius": 12
  }
}

Opacity

opacity
number
default:"1"
Element opacity from 0 (fully transparent) to 1 (fully opaque)
{
  "type": "box",
  "style": {
    "backgroundColor": "#000000",
    "opacity": 0.5
  }
}

Flexbox Properties

Flex properties control layout behavior for Flex containers and their children.

Container Properties

These properties are available on flex elements:
flexDirection
string
default:"row"
Primary axis direction:
  • "row" - Left to right
  • "column" - Top to bottom
  • "row-reverse" - Right to left
  • "column-reverse" - Bottom to top
justifyContent
string
default:"flex-start"
Main axis alignment:
  • "flex-start" - Pack to start
  • "flex-end" - Pack to end
  • "center" - Center items
  • "space-between" - Space between items
  • "space-around" - Space around items
  • "space-evenly" - Evenly distributed space
alignItems
string
default:"stretch"
Cross axis alignment:
  • "flex-start" - Align to start
  • "flex-end" - Align to end
  • "center" - Center items
  • "stretch" - Stretch to fill
  • "baseline" - Align text baselines
gap
number
default:"0"
Space between flex items in pixels
flexWrap
string
default:"nowrap"
Wrapping behavior:
  • "nowrap" - Single line
  • "wrap" - Multi-line, wrapping as needed
{
  "type": "flex",
  "style": {
    "flexDirection": "column",
    "gap": 16,
    "padding": 24
  }
}

Child Properties

These properties are available on Text and Image elements when inside a Flex container:
flexGrow
number
default:"0"
Ability to grow. Value of 1 means the element will grow to fill available space.
flexShrink
number
default:"1"
Ability to shrink. Value of 0 prevents shrinking.
{
  "type": "flex",
  "style": { "flexDirection": "row", "width": 400 },
  "children": [
    {
      "type": "text",
      "content": "Flexible",
      "style": { "flexGrow": 1 }
    },
    {
      "type": "text",
      "content": "Fixed",
      "style": { "flexGrow": 0, "flexShrink": 0 }
    }
  ]
}

Flex Enums

From crates/htvg-core/src/element.rs:256-304:
#[derive(Debug, Clone, Copy, Default)]
pub enum FlexDirection {
    #[default]
    Row,
    Column,
    RowReverse,
    ColumnReverse,
}

#[derive(Debug, Clone, Copy, Default)]
pub enum JustifyContent {
    #[default]
    FlexStart,
    FlexEnd,
    Center,
    SpaceBetween,
    SpaceAround,
    SpaceEvenly,
}

#[derive(Debug, Clone, Copy, Default)]
pub enum AlignItems {
    FlexStart,
    FlexEnd,
    Center,
    #[default]
    Stretch,
    Baseline,
}

#[derive(Debug, Clone, Copy, Default)]
pub enum FlexWrap {
    #[default]
    Nowrap,
    Wrap,
}

Typography Properties

These properties are specific to Text elements.
fontFamily
string
default:"sans-serif"
Font family name
fontSize
number
default:"16"
Font size in pixels
fontWeight
number | string
default:"400"
Font weight:
  • Number: 100-900 (100, 200, 300, 400, 500, 600, 700, 800, 900)
  • Keyword: "normal" (400), "bold" (700)
lineHeight
number
default:"1.2"
Line height as a multiplier of font size
textAlign
string
default:"left"
Text alignment:
  • "left" - Left-aligned
  • "center" - Centered
  • "right" - Right-aligned
  • "justify" - Justified (stretched to fill)
letterSpacing
number
default:"0"
Additional space between characters in pixels
textRendering
string
default:"text"
Rendering mode:
  • "text" - Render as SVG <text> elements
  • "vector" - Render as vector paths (planned feature)
{
  "type": "text",
  "content": "Card Title",
  "style": {
    "fontSize": 20,
    "fontWeight": 700,
    "color": "#1a1a1a"
  }
}

Font Weight Implementation

From crates/htvg-core/src/element.rs:333-367:
pub struct FontWeight(pub u16);

impl Default for FontWeight {
    fn default() -> Self {
        Self(400)
    }
}

// Deserializes from number or string:
// - Number: 100-900
// - "normal" -> 400
// - "bold" -> 700

Image Properties

objectFit
string
default:"contain"
How the image fits within its bounds:
  • "contain" - Scale to fit, preserving aspect ratio
  • "cover" - Scale to cover, preserving aspect ratio (may crop)
  • "fill" - Stretch to fill exactly
{
  "type": "image",
  "src": "data:image/png;base64,...",
  "width": 800,
  "height": 600,
  "style": {
    "maxWidth": 400,
    "objectFit": "contain"
  }
}
Image scales down to fit 400px width while maintaining aspect ratio.

Display Property

display
string
Display mode for Box/Flex elements:
  • "block" - Block display (default for Box)
  • "flex" - Flex display (default for Flex)
  • "none" - Hide element
{
  "type": "box",
  "style": {
    "display": "none"
  }
}
Setting display: "none" will completely remove the element from layout computation.

Complete Style Type Definitions

From crates/htvg-core/src/element.rs:373-478:
// Box elements
pub struct BoxStyle {
    pub display: Option<Display>,
    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>,
    pub margin: Option<Spacing>,
    pub padding: Option<Spacing>,
    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 elements (extends BoxStyle properties)
pub struct FlexStyle {
    // All BoxStyle properties plus:
    pub flex_direction: Option<FlexDirection>,
    pub justify_content: Option<JustifyContent>,
    pub align_items: Option<AlignItems>,
    pub gap: Option<f32>,
    pub flex_wrap: Option<FlexWrap>,
}

// Text elements
pub struct TextStyle {
    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>,
    pub flex_grow: Option<f32>,
    pub flex_shrink: Option<f32>,
}

// Image elements
pub struct ImageStyle {
    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>,
    pub margin: Option<Spacing>,
    pub object_fit: Option<ObjectFit>,
    pub border_radius: Option<BorderRadius>,
    pub opacity: Option<f32>,
    pub flex_grow: Option<f32>,
    pub flex_shrink: Option<f32>,
}

Element Types

Learn about Box, Flex, Text, and Image elements

Layout Engine

How Taffy computes layout with these properties

Build docs developers (and LLMs) love