VML — VoxMark Language

VML (VoxMark Language) is a declarative programming language for building interactive web applications and documents. It combines component-based UI, data binding, conditional rendering, scoped styling, reusable object definitions, routing, and compilation to HTML, CSS, and WebAssembly through the VoxMark compiler.

Table of Contents

Topics Description
Installation / Quick Start Installation and quick start VoxMark Language (VML)
Syntax Basics Basic syntax for writing VML
Variables Define a reusable text value once and reference it anywhere with @name.
Classes Define an object-style namespace of named properties and reference them with dot notation throughout the document.
Content Widgets
Topics Description
Card A rounded content card with an optional title bar.
Alert A status alert box. Four built-in styles.
Callout A highlighted callout / tip box with a leading emoji icon.
Tabs A tabbed panel. Tab labels go in [args], tab content segments in {body}.
Timeline A vertical event timeline. Each item is Title::Description.
Progress Bar An animated progress bar with an optional label.
Badge An inline pill badge.
Collapsible A <details> / <summary> collapsible section. Uses triple-colon (:::).
Tooltip An inline element with a hover tooltip.
--
Layout Widgets
Topics Description
Columns A responsive multi-column layout.
Grid A CSS grid container. Uses triple-colon.
Flex A CSS flex container. Uses triple-colon.
Hero A full-width hero section with configurable background and alignment. Uses triple-colon.
Section A full-width content section with optional title and subtitle. Uses triple-colon.
Box A styled container box with configurable variant. Uses triple-colon.
Div A generic <div> wrapper with custom class, id, or style. Uses triple-colon.
Center / Right Align block content.
Spacer / Divider Add whitespace or a horizontal rule.
--
Typography Widgets
Topics Description
Highlight Highlighted / marked text with colour variants.
Styled Bold Bold text with special rendering styles.
Color Inline text with a custom colour.
Glow --
Keyboard Key --
Math --
--
Navigation Widgets
Topics Description
Sidebar --
Router --
Footer --
--
Media & Embed Widgets
Topics Description
Icon --
Icon Card --
Inline SVG --
Embed --
--
Form Widgets
Topics Description
Input --
Checkbox --
Select --
Button --
Button Group --
--
Control Flow Widgets
Topics Description
If --
Else --
If / Else (inline) --
--
CSS Widgets
Topics Description
Scoped CSS Block --
CSS Playground --
CSS Variable --
Inline Style --
CSS Class --
--
Data Visualisation
Topics Description
Chart --
Graph --
Graph Playground --
--
Charting
Topics Description
Demo Sandbox --
--
Build-time Widgets
Topics Description
Include Read another .vml file from disk and inline its fully-rendered output here.
--
CLI Reference --
Quick-reference Table --

Installation

Install VoxMark Language using Python Package Manager (pip).

pip install voxmark

Quick Build

voxmark init my-project
cd my-project
voxmark compiler --build index.vml -o build/

Or, set a title.

voxmark compiler --build index.vml -o build/ --title My-Project
voxmark server build/

Or, choose a port:

voxmark server --port 7080 build/

Or, bind a host and port:

voxmark server --host 0.0.0.0 --port 7080 build/

Syntax Basics

::cmd[args]{body}       ← double colon  — most widgets
:::cmd[args]{body}      ← triple colon  — block/layout/structural widgets
Part Required Description
:: or ::: yes Widget opener. Triple-colon widgets are typically block-level layout containers.
cmd yes The widget name (case-insensitive).
[args] depends Pipe-separated arguments: [arg1\|arg2\|arg3]. Some widgets require them, some don't.
{body} depends Body content. Supports Markdown, nested ::widgets, and @var references. Omit for bodyless widgets.

Argument separator: |

Multiple arguments inside [...] are separated by |:

::button[primary|https://example.com]{Visit}
::icon[github|1.2em|#7c6dff]{🐙}
::badge[stable|#22c55e]

Body segment separator: ||

Some widgets accept multiple body segments separated by || — for example, tabs (one segment per tab panel), columns (one segment per column), and the router (one segment per page):

::tab[Python|Rust]{
python
||
rust
}

Bodyless widgets

Some widgets take only [args] and no {body}. These never have curly braces:

::badge[v1.0|#7c6dff]
::progress[72/100|Completion]
::divider[]
::spacer[2em]

Nesting

VML widgets nest freely inside any {body}:

::card[Example]{
  Status: ::badge[OK|#22c55e]
  Press ::kbd{Ctrl+S} to save.
  ::alert[info]{Nested alert inside a card body.}
}

Markdown inside bodies

Widget bodies are fully Markdown-aware. Any Markdown that Mistune supports (CommonMark + GFM) works inside a body:

::callout[💡]{
**Bold**, *italic*, `inline code`, [links](https://example.com),
and even fenced code blocks all work here.
}

Exception: the body of ::var, :::css, :::cssplay, ::math, ::kbd, ::chart, ::embed, ::svg, :::demo, ::if, ::else, ::ifelse, ::router, ::footer, ::input, ::checkbox, ::select, and ::cssvar is treated as raw text (not Markdown) because those widgets need their body content unmodified.

Variables — ::var

Define a reusable text value once and reference it anywhere with @name.

::var[author]{Divyanshu Sinha}
::var[version]{2.0.0}
::var[repo]{https://github.com/DivyanshuSinha136}

Built by **@author** — VoxMark v@version.
[Source code](@repo)

Preview

Built by Divyanshu Sinha — VoxMark v2.0.0. Source code

Classes — ::class_def and @Name.prop

Define an object-style namespace of named properties and reference them with dot notation throughout the document.

::class_def[School]{
  name:Springfield Elementary
  ||address:742 Evergreen Terrace, Springfield
  ||founded:1953
  ||principal:Principal Skinner
  ||website:https://springfield-elem.edu
}

The school is **@School.name**, founded in @School.founded.
Address: @School.address
Principal: @School.principal — [Website](@School.website)

Syntax rules

Rule Detail
Body format Each \|\|-separated segment is key:value
Key Any word characters: [A-Za-z0-9_]+
Value Everything after the first : (may contain colons, spaces, URLs, etc.)
ClassName Convention: start with a capital letter. re.sub(r'[^\w]', '', name) for safety.
Unknown ref @School.unknown is left unchanged — safe to use conditionally
Re-definition Replaces all properties of that class
Visibility Emits an invisible <meta class="vml-class-def"> tag — no visible output

Dot-ref vs plain-var

Syntax Resolves
@School.name Class property (resolved first)
@author Simple var (no dot — resolved after class refs)

Class properties work inside any widget body, argument, or plain text.

Preview

The school is Springfield Elementary, founded in 1953. Address: 742 Evergreen Terrace, Springfield Principal: Principal Skinner — Website

Content Widgets

Card

A rounded content card with an optional title bar.

::card[🚀 Card Title]{
Body content here. Supports **Markdown**, ::badge[tags|#7c6dff], and nested widgets.
}
::card[]{No title — just body content.}
::card[Title]{Body text}

Preview

Source Code

::card[]{No title — just body content.}
::card[Title]{Body text}

View

No title — just body content.
Title
Body text


Alert

A status alert box. Four built-in styles.

::alert[success]{Your document saved successfully.}
::alert[info]{This is an informational note.}
::alert[warn]{Something needs your attention.}
::alert[error]{An error occurred. Check the logs.}

Preview

Source Code

::alert[success]{Your document saved successfully.}
::alert[info]{This is an informational note.}
::alert[warn]{Something needs your attention.}
::alert[error]{An error occurred. Check the logs.}

View

Your document saved successfully.
This is an informational note.
Something needs your attention.
An error occurred. Check the logs.


Callout

A highlighted callout / tip box with a leading emoji icon.

::callout[💡]{**Pro Tip:** You can use `::var[name]{value}` to define
reusable values and reference them with `@name`.}

::callout[⚠]{Be careful when nesting more than 3 levels of widgets.}
::callout[🔗]{Check the [full docs](https://github.com/DivyanshuSinha136).}

Preview

Source Code

::callout[💡]{**Pro Tip:** You can use `::var[name]{value}` to define
reusable values and reference them with `@name`.}

::callout[⚠]{Be careful when nesting more than 3 levels of widgets.}
::callout[🔗]{Check the [full docs](https://github.com/DivyanshuSinha136/VoxMark-Language).}

View

💡
Pro Tip: You can use ::var[name]{value} to define reusable values and reference them with @name.

Be careful when nesting more than 3 levels of widgets.
🔗
Check the full docs.


Tabs

A tabbed panel. Tab labels go in [args], tab content segments in {body} separated by ||.

::tab[Python|JavaScript|Rust]{
Python
||
JS
||
Rust
}

Preview

Python
JS
Rust

Timeline

A vertical event timeline. Each item is Title::Description, separated by ||.

::timeline{
  Project Kickoff::Started VoxMark as a production-grade document engine.
  ||v1.0 Released::Shipped Markdown + 26 VML widgets with live preview.
  ||v2.0::Added sidebar, router, footer, includes, class system, and forms.
  ||You Are Here::Explore, edit, and create!
}

Preview

Project Kickoff

Started VoxMark as a production-grade document engine.

v1.0 Released

Shipped Markdown + 26 VML widgets with live preview.

v2.0

Added sidebar, router, footer, includes, class system, and forms.

You Are Here

Explore, edit, and create!


Progress Bar

An animated progress bar with an optional label.

::progress[72/100|Project Completion]
::progress[3/5|Milestones]
::progress[1/1|Tests Passing]

Preview

Project Completion
72.0%
Milestones
60.0%
Tests Passing
100.0%

Badge

An inline pill badge.

Status: ::badge[stable|#22c55e]
Version: ::badge[v2.0|#7c6dff]
License: ::badge[MIT|#f59e0b]
Platform: ::badge[Python 3.12|#3b82f6]

Preview

Status: stable Version: v2.0 License: MIT Platform: Python 3.12


Collapsible Fold

A details / summary collapsible section. Uses triple-colon (:::).

:::fold[Click to expand — Advanced Options]{
### Variable System

Define once, use everywhere:
### Nested Widgets

Everything works inside a fold:

::alert[info]{Even alerts.}
::progress[80/100|Even progress bars.]
}

Preview

Click to expand — Advanced Options

Variable System

Define once, use everywhere:

::var[author]{Divyanshu Sinha}

Nested Widgets

Everything works inside a fold:

Even alerts.
Even progress bars.
80.0%


Tooltip

An inline element with a hover tooltip.

VoxMark uses ::tooltip[LEB128|Unsigned Little-Endian Base-128 variable-length encoding]{LEB128}
encoding in its WASM binary output.

Preview

VoxMark uses LEB128LEB128|Unsigned Little-Endian Base-128 variable-length encoding encoding in its WASM binary output.

Layout Widgets

Columns

A responsive multi-column layout. Columns use || to separate content.

::columns[1:1]{
**Left column**

Full Markdown here — lists, code, widgets, anything.
||
**Right column**

::alert[info]{Even nested widgets.}
}
::columns[2:1]{
Main content (takes 2/3 width)
||
Sidebar content (takes 1/3 width)
}

Preview

Left column

Full Markdown here — lists, code, widgets, anything.

Right column

Even nested widgets.

Main content (takes 2/3 width)
Sidebar content (takes 1/3 width)

Grid

A CSS grid container. Uses triple-colon.

:::grid[3|16px]{
::card[Card 1]{Content}
||
::card[Card 2]{Content}
||
::card[Card 3]{Content}
}

Preview

Card 1
Content
Card 2
Content
Card 3
Content

Flex

A CSS flex container. Uses triple-colon.

:::flex[12px|center|flex-start|wrap]{
::badge[Python|#3b82f6]
||
::badge[NASM|#f59e0b]
||
::badge[Flask|#22c55e]
}

Preview

Python
NASM
Flask

Hero

A full-width hero section with configurable background and alignment. Uses triple-colon.

:::hero[#13162a|center|400px]{
# Welcome to VoxMark

The document engine built from **first principles**.

:::btngroup{::button[outline|#]{Get Started}||::button[ghost|#]{Learn More}}
}

Preview

Welcome to VoxMark

The document engine built from first principles.


Section

A full-width content section with optional title and subtitle. Uses triple-colon.

:::section[Features|Everything you need|center]{
::columns[1:1:1]{
::card[Fast]{Sub-millisecond rendering.}
||
::card[Secure]{XSS scanning built in.}
||
::card[Extensible]{53+ widget types.}
}
}

Preview

Features
Everything you need
Fast
Sub-millisecond rendering.
Secure
XSS scanning built in.
Extensible
53+ widget types.

Box

A styled container box with configurable variant. Uses triple-colon.

:::box[info]{
This is an info box. Useful for highlighting important content.
}

Preview

This is an info box. Useful for highlighting important content.

Div

A generic div wrapper with custom class, id, or style. Uses triple-colon.

:::div[my-custom-class|my-id|color:red;font-size:1.2em]{
Content with custom styling applied.
}

Preview

Content with custom styling applied.

Center / Right

Align block content.

::center{This text and ::badge[content|#7c6dff] are centered.}

::right{Right-aligned text.}

Preview

This text and content are centered.
Right-aligned text.

Spacer / Divider

Add whitespace or a horizontal rule.

::spacer[2em]         ← vertical whitespace of 2em

::divider[]           ← default styled HR
::divider[dashed]     ← dashed style
::divider[dotted]     ← dotted style
::divider[gradient]   ← gradient fade

Both are bodyless — no {...}.

Preview

Dividers







Typography Widgets

Highlight

Highlighted / marked text with colour variants.

Normal text, then ::hl[yellow]{important}, ::hl[green]{success},
::hl[pink]{warning}, ::hl[blue]{info}, ::hl[orange]{note}, ::hl[purple]{vml}.

Preview

Normal text, then important, success, warning, info, note, vml.


Styled Bold

Bold text with special rendering styles.

::b[gradient]{Gradient}   — multicolour gradient fill
::b[outline]{Outline}     — transparent with a stroke
::b[shadow]{Shadow}       — layered drop shadow
::b[neon]{Neon}           — glowing neon effect
::b[stamp]{STAMP}         — uppercase bordered stamp
::b[underline]{Underline} — accent underline
::b[mono]{mono}           — monospace code-style bold

Preview

Gradient
Outline
Shadow
Neon
STAMP
Underline mono


Color

Inline text with a custom colour.

::color[#ef4444]{Red text}  ::color[#22c55e]{Green text}  ::color[#f59e0b]{Amber text}

Preview

Red text Green text Amber text

Glow

Glowing text with a custom glow colour.

::glow[#7c6dff]{VoxMark glows in the dark.}
::glow[#38d9a9]{Teal glow}

Preview

VoxMark glows in the dark. Teal glow

Keyboard Key

Render keyboard shortcuts as styled kbd elements.

Press ::kbd{Ctrl+S} to save.
Press ::kbd{Ctrl+Enter} to render.
Press ::kbd{⌘+K} to open command palette.

Preview

Press Ctrl + S to save. Press Ctrl + Enter to render. Press + K to open command palette.


Math

Render a LaTeX / KaTeX expression.

::math{E = mc^2}
::math{\int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2}}
::math{\sum_{n=1}^{\infty} \frac{1}{n^2} = \frac{\pi^2}{6}}

Preview

\(E = mc^2\) \(\int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2}\) \(\sum_{n=1}^{\infty} \frac{1}{n^2} = \frac{\pi^2}{6}\)

A slide-in navigation sidebar with a floating toggle button. Uses triple-colon.

:::sidebar[My Portfolio|left|260px]{
  Site Name
  ||Home::#home
  ||About::#about
  ||Projects::#projects
  ||---
  ||Contact::#contact
  ||::badge[v2.0|#7c6dff]
}

Arguments ([Title|side|width]):

Arg Default Description
Title Menu Shown in the sidebar header
side left left or right
width 260px CSS width of the sidebar panel

Body segment formats (separated by ||):

Pattern Renders as
Label::href Nav link —
--- Horizontal divider
Plain text Section heading
::widget{...} Raw widget block inside the sidebar

Router

A hash-based single-page router with auto-generated tab navigation.

::router[home]{
  home:Home::# Welcome
  Body of the home page — full Markdown + VML.

  ||about:About::# About
  About page content here.

  ||projects:Projects::# Projects
  ::card[VoxMark]{A compiler built from scratch.}
}

[default_page_id] — the page shown on first load (defaults to first page).

Body segment format: each || segment is page_id:Display Title::page body.

Field Description
page_id URL-safe identifier, used as #hash
Display Title Shown in the nav bar and document.title
page body Full VML + Markdown content for this page

Combined with ::include for multi-file sites:

::router[home]{
  home:Home::     
  ||about:About:: 
  ||work:Work::   
}

A site footer with an optional multi-column layout and copyright bar.

::footer[© 2025 Divyanshu Sinha|#7c6dff]{
  **VoxMark**
  A custom Markdown + VML engine.
  ::badge[Open Source|#22c55e]
  ||
  **Navigation**
  [Home](#home) · [About](#about) · [Projects](#projects)
  ||
  **Connect**
  ::icon[github|1em|#7c6dff]{} [GitHub](https://github.com/DivyanshuSinha136)
  ::icon[mail|1em|#38d9a9]{} [Email](mailto:you@example.com)
}

Arguments ([copyright|accent]):

Arg Default Description
copyright (empty) Text for the bottom copyright bar
accent #7c6dff Gradient colour for the top border

Body:

Each column renders its own mini VML + inline-Markdown pass, so badges, icons, links, and bold/italic text all work inside footer columns.

Learned
47.1%

Media & Embed Widgets

Icon

An inline SVG icon from the built-in icon set.

::icon[github|1.2em|#7c6dff]{🐙}
::icon[rocket|1em|#f59e0b]{}
::icon[check-circle|1em|#22c55e]{} Done

Available icons (209 total):

Categories Icon Name Preview
BRAND vml, voxmark ,
ARROWS arrow-right, arrow-left, arrow-up, arrow-down, arrow-up-right, arrow-up-left, chevron-right, chevron-left, chevron-up, chevron-down, chevrons-right, chevrons-left, move, corner-up-right, corner-down-right , , , , , , , , , , , , , ,
STATUS check, check-circle, check-square, x, x-circle, x-square, info, warn, alert-circle, alert-triangle, help-circle, shield, shield-check, shield-off , , , , , , , , , , , , ,
MEDIA play, pause, stop, skip-back, skip-forward, volume, volume-x, mic, mic-off, camera, camera-off, video, video-off, music, headphones, radio, cast, airplay , , , , , , , , , , , , , , , , ,
FILES file, file-text, file-code, file-image, file-archive, folder, folder-open, folder-plus, save, paperclip, clipboard , , , , , , , , , ,
EDITING edit, edit-2, edit-3, scissors, crop, rotate-cw, rotate-ccw, maximize, minimize, maximize-2, minimize-2 , , , , , , , , , ,
SOCIAL github, twitter, linkedin, youtube, instagram, facebook, twitch, discord, slack, codepen, gitlab, npm, python, figma , , , , , , , , , , , , ,
CODING code, code-2, terminal, cpu, server, database, cloud, git-branch, git-commit, git-merge, git-pull-request, package, puzzle, command, hash, function , , , , , , , , , , , , , , ,
UI layout, sidebar, menu, grid, list, table, columns, bar-chart, bar-chart-2, pie-chart, trending-up, trending-down, activity, filter, sort, toggle-left, toggle-right, sliders, loader, refresh-cw, refresh-ccw , , , , , , , , , , , , , , , , , , , ,
COMMUNICATION mail, mail-open, send, message, message-circle, message-square, phone, phone-call, phone-off , , , , , , , ,
PEOPLE user, users, user-plus, user-minus, user-check, user-x , , , , ,
NATURE sun, moon, cloud-rain, wind, umbrella, anchor, feather , , , , , ,
MISC star, heart, bookmark, tag, flag, trophy, gift, coffee, zap, battery, wifi, bluetooth, rss, share, eye, eye-off, globe, map, map-pin, navigation, compass, clock, calendar, shopping-cart, shopping-bag, credit-card, dollar-sign, key, unlock, lock, home, building, tool, wrench, bell, bell-off, thumbs-up, thumbs-down, smile, frown, image, image-off, box, layers, rocket, spacer-icon, minus, plus, plus-circle, copy, trash, search, settings, download, upload, external, link, more-horizontal, more-vertical, dots, print, share-2, log-in, log-out, power , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

Icon Card

A card with a large icon, title, and description text.

::iconcard[rocket|Fast Render]{Sub-millisecond VML transforms.}
::iconcard[lock|Secure]{XSS scanning and rate limiting built in.}
::iconcard[layers|Extensible]{53+ widget types and growing.}

Best used inside :::grid or ::columns for a feature-cards layout.

Preview

Fast Render
Sub-millisecond VML transforms.
Secure
XSS scanning and rate limiting built in.
Extensible
53+ widget types and growing.

Inline SVG

Render raw SVG directly in the document. Uses triple-colon.

:::svg{

  
    
      
      
    
  
  
  VoxMark

}

Preview

VoxMark

Embed

Embed external content of many types.

::embed[youtube]{https://www.youtube.com/watch?v=dQw4w9WgXcQ}
::embed[github]{https://github.com/DivyanshuSinha136/VoxMark}
::embed[spotify]{https://open.spotify.com/track/...}
::embed[codepen]{https://codepen.io/pen/...}
::embed[map]{https://maps.google.com/...}
::embed[pdf]{/docs/spec.pdf}
::embed[audio]{/assets/music.mp3}
::embed[image]{https://example.com/photo.jpg}
::embed[site]{https://example.com}
Learned
52.9%

Form Widgets

Input

A styled form input field.

::input[text|Enter your name|inp-name]{Full Name}
::input[email|you@example.com|inp-email]{Email Address}
::input[password|••••••••|inp-pw]{Password}
::input[number|0|score|50|0|100|1]{Score (0–100)}
::input[date||dob]{Date of Birth}
::input[range||brightness|75|0|100]{Brightness}
::input[color||accent|#7c6dff]{Accent Colour}
::input[file||upload]{Upload File}

Arguments ([type|placeholder|id|default|min|max|step]):

Arg Default Description
type text Input type (see list below)
placeholder Placeholder text
id auto Element id and name
default Initial value
min Minimum (for number, range)
max Maximum (for number, range)
step Step increment (for number, range)

{body} — visible label text (above the input)

Supported types: text · email · password · number · url · tel · search · date · datetime-local · time · range · color · file

Range inputs get a live numeric readout. Color inputs get a swatch preview.

Preview

75
#7c6dff

Checkbox

A styled checkbox with a label.

::checkbox[agree|yes]{I agree to the terms and conditions.}
::checkbox[newsletter|yes|checked]{Subscribe to newsletter (pre-ticked)}

Arguments ([id|value|checked]):

Arg Default Description
id auto Element id and name
value on Form submission value
checked Write checked to pre-tick

{body} — checkbox label text


Select

A styled dropdown select.

::select[country|IN|Country]{
  US:United States|UK:United Kingdom|IN:India|JP:Japan|DE:Germany
}

::select[size||T-Shirt Size]{S|M|L|XL|XXL}

Arguments ([id|default|label]):

Arg Default Description
id auto Element id and name
default Pre-selected value
label Visible label above the select

{body} — pipe-separated options:

Preview


Button

A styled button / link.

::button[primary|https://github.com]{Visit GitHub}
::button[secondary|#about]{Learn More}
::button[ghost|mailto:you@example.com]{Send Email}
::button[outline|#]{Read Docs}
::button[danger|#delete]{Delete}
::button[success|#]{Confirm}

Arguments ([style|action]):

Arg Default Description
style primary primary · secondary · ghost · outline · danger · success
action # href value — URL, #hash, mailto:, tel:, or javascript:

{body} — button label, supports inline VML like ::icon and ::badge

Preview

Visit GitHub Learn More Send Email Read Docs Delete Confirm

Button Group

A group of buttons rendered inline. Uses triple-colon.

:::btngroup{
  ::button[primary|#]{Get Started}
  ||::button[ghost|#]{Learn More}
  ||::button[outline|https://github.com]{GitHub}
}

Preview

Get StartedLearn MoreGitHub
Learned
58.8%

Control Flow Widgets

All control-flow widgets are client-side — the condition is evaluated in the browser using Function("return (expr)")() with a character-class safety filter. They are evaluated once at page-load.

If

Show content when a JavaScript expression is truthy.

::if[window.innerWidth > 768]{Wide-screen layout — only visible on desktop.}

::if[navigator.language.startsWith('en')]{English content.}

::if[document.documentElement.dataset.theme === 'dark']{Dark mode content.}

Else

Show content when the same expression is falsy. Pair with a preceding ::if.

::if[window.innerWidth > 768]{Wide layout.}
::else[window.innerWidth > 768]{Narrow / mobile layout.}

If / Else (inline)

Compact inline branch — shows one of two segments based on a condition.

::ifelse[navigator.onLine]{
  You are **online** — live features active.
  ||
  You are **offline** — some features unavailable.
}
Learned
64.7%

CSS Widgets

Scoped CSS Block

Define CSS that applies to the current document scope. Uses triple-colon.

:::css{
.my-box {
  background: linear-gradient(135deg, #7c6dff22, #38d9a911);
  border: 1px solid #7c6dff44;
  border-radius: 12px;
  padding: 20px 24px;
}
.my-box h3 {
  color: #7c6dff;
  margin: 0 0 8px;
}
}

::class[my-box]{### Scoped styles applied here

This block uses the styles defined above.}

Preview

CSSScoped stylesheet active

Scoped styles applied here

This block uses the styles defined above.


CSS Playground

A live split-editor showing CSS and HTML side-by-side with instant preview. Uses triple-colon.

:::cssplay{
.card {
  background: linear-gradient(135deg, #7c6dff, #38d9a9);
  padding: 24px; border-radius: 16px; color: white;
}
||

Live Preview

Edit the CSS pane to see changes instantly.

}

Preview

CSS Playground
CSS
Live Preview

CSS Variable

Define a CSS custom property (--variable) for the document scope.

::cssvar[--brand]{#7c6dff}
::cssvar[--accent2]{#38d9a9}
::cssvar[--gap]{16px}

Then use it in any :::css{} block:

:::css{
.branded {
  border-left: 4px solid var(--brand);
  background: color-mix(in srgb, var(--brand) 10%, transparent);
}
}

Inline Style

Apply arbitrary inline CSS to a block of content.

::style[display:flex;gap:12px;flex-wrap:wrap;margin:.5em 0]{
  ::style[background:#7c6dff;color:#fff;padding:10px 18px;border-radius:10px;font-weight:700]{Primary}
  ::style[background:#22c55e22;color:#22c55e;padding:10px 18px;border-radius:10px;border:1px solid #22c55e44]{Success}
}

Preview

Primary Success

CSS Class

Apply one or more CSS class names to a block of content.

::class[my-box hero-card]{
### Scoped Class Applied

Content inside this div has `class="my-box hero-card"` applied.
}
Learned
70.6%

Data Visualisation

Chart

A Chart.js chart powered by a JSON data payload.

::chart[bar]{
{
  "labels": ["Jan", "Feb", "Mar", "Apr", "May"],
  "datasets": [{
    "label": "Revenue ($k)",
    "data": [42, 58, 37, 71, 63],
    "backgroundColor": ["#7c6dff","#38d9a9","#f59e0b","#ef4444","#3b82f6"]
  }]
}
}

Preview


Graph

A rich server-side data graph with built-in themes.

::graph[bar|Monthly Revenue|purple|280px]{
{
  "labels": ["Jan","Feb","Mar","Apr"],
  "data":   [42, 58, 37, 71]
}
}
::graph[area|Monthly Revenue|purple|280px]{
{
  "labels": ["Jan","Feb","Mar","Apr"],
  "data":   [42, 58, 37, 71]
}
}

Preview


Graph Playground

An interactive graph editor. Uses triple-colon.

:::graphplay{{"type":"bar","data":{"labels":["Mon","Tue","Wed","Thu","Fri","Sat","Sun"],"datasets":[{"label":"Visitors","data":[320,450,280,690,510,820,430]},{"label":"Conversions","data":[32,45,28,69,51,82,43]}]}}}

Preview

Graph Playground
Chart.js JSON

Demo Sandbox

A live HTML/CSS sandbox. Uses triple-colon.

:::demo{

✦ Live Demo

This HTML is editable and renders live.

}

Preview

Live Demo
Learned
76.5%

Build-time Widgets

Include

Read another .vml file from disk and inline its fully-rendered output here.




Multi-file project example:

my-site/
  index.vml
  sections/
    home.vml
    about.vml
    contact.vml

index.vml:

:::sidebar[My Site]{Home::#home||About::#about||Contact::#contact}

::router[home]{
  home:Home::  
  ||about:About:: 
  ||contact:Contact:: 
}

::footer[© 2025]{Built with **VoxMark**}

Build with:

voxmark compiler --build index.vml -o build/
Learned
94.1%

CLI Reference

voxmark compiler --build input -o build-dir
Flag Description
--build Required. Compile to HTML + CSS + WASM + JS loader.
input Source .vml / .md file or directory.
-o / --output Output directory (default: build/).
--title Override HTML title.
--no-wasm Skip .wasm / loader.js output.
--no-wat Skip debug.wat output.
voxmark server  [--port PORT] [--host HOST] [--open]
voxmark lint [input]
voxmark format [input] [-o output] [-i]
voxmark ast [input] [--json]
voxmark init [directory]
voxmark watch [input] -o build-dir [--port PORT]
voxmark version

Global flags: --verbose / -v · --quiet / -q · --no-color


Learned
100.0%

Quick-reference Table

Widget Syntax Triple? Bodyless?
Alert ::alert[type]{msg}
Badge ::badge[label\|colour]
Bold styled ::b[style]{text}
Box :::box[variant]{content}
Button ::button[style\|href]{label}
Button group :::btngroup{::button\|\|…}
Callout ::callout[emoji]{text}
Card ::card[title]{body}
Center ::center{content}
Chart ::chart[type]{json}
Checkbox ::checkbox[id\|val\|checked]{label}
Class (apply) ::class[names]{body}
Class (define) ::class_def[Name]{k:v\|\|k:v}
Color ::color[#hex]{text}
Columns ::columns[1:1]{col\|\|col}
CSS block :::css{…}
CSS class ::class[names]{content}
CSS playground :::cssplay{css\|\|html}
CSS variable ::cssvar[--name]{value}
Demo sandbox :::demo{html}
Div :::div[class\|id\|style]{content}
Divider ::divider[style]
Else ::else[cond]{content}
Embed ::embed[type]{url}
Flex :::flex[gap\|…]{item\|\|item}
Fold :::fold[title]{body}
Footer ::footer[copy\|accent]{col\|\|col}
Glow ::glow[colour]{text}
Graph ::graph[type\|title\|palette\|h]{json}
Graph playground :::graphplay{json}
Grid :::grid[cols\|gap]{cell\|\|cell}
Hero :::hero[bg\|align\|h]{content}
Highlight ::hl[colour]{text}
Icon ::icon[name\|size\|colour]{fallback}
Icon card ::iconcard[icon\|title]{desc}
If ::if[cond]{content}
If/else ::ifelse[cond]{then\|\|else}
Include
Input ::input[type\|…]{label}
Keyboard key ::kbd{key combo}
Math ::math{LaTeX}
Progress ::progress[val/max\|label]
Right-align ::right{content}
Router ::router[default]{id:Title::body\|\|…}
Section :::section[title\|sub\|align]{body}
Select ::select[id\|default\|label]{opts}
Sidebar :::sidebar[title\|side\|w]{nav}
Spacer ::spacer[size]
Style (inline) ::style[css]{content}
SVG :::svg{}
Tab ::tab[A\|B]{body\|\|body}
Timeline ::timeline{Title::Desc\|\|…}
Tooltip ::tooltip[tip text]{anchor}
Variable ::var[name]{value}