Themes & Styling¶
Control the visual appearance of your dashboard globally or per-chart.
Themes¶
Dataface includes 18+ built-in themes that apply consistent styling across your entire dashboard. Built-ins live in dataface/core/compile/chart_themes/, one file per theme, while your project-specific additions still go in dataface.yml under themes:.
Internally, Dataface separates:
- Theme = CSS-like painting of the chart scaffold
- Structure = HTML-like chart scaffold
That means fonts, colors, surfaces, palette choices, stroke/fill, widths, and sizes belong in themes, while defaults like axis side, grid/domain presence, legend side, title anchoring, and other scaffold decisions belong in structures.
The runtime merge order is: base vega.config -> selected structure ->
theme-paired structure overlay (when configured) -> selected theme.
Using a Theme¶
Add theme: at the top level of your dashboard:
title: "Sales Dashboard" theme: dark queries: sales: SELECT * FROM sales layout: - chart: revenue_chart
Available Themes¶
| Theme | Description | Background |
|---|---|---|
light |
Clean default theme | White |
dark |
Dark mode with blue-gray tones | Dark blue-gray |
minimal |
Clean with no gridlines or borders | White |
excel |
Microsoft Excel style | White |
ggplot2 |
R's ggplot2 style | Light gray |
quartz |
Quartz design style | Off-white |
vox |
Vox Media design | White |
fivethirtyeight |
FiveThirtyEight style | White |
latimes |
LA Times newspaper style | White |
urbaninstitute |
Urban Institute style | White |
googlecharts |
Google Charts style | White |
powerbi |
Microsoft Power BI style | White |
carbonwhite |
IBM Carbon Design (light) | White |
carbong10 |
IBM Carbon (slightly darker) | #f4f4f4 |
carbong90 |
IBM Carbon (dark) | #262626 |
carbong100 |
IBM Carbon (darkest) | #161616 |
vega-lite-explorer |
Exploratory preset for surveying Vega-Lite theming surface | Warm ivory |
vega-lite-explorer-rich |
Reference-oriented preset with broader Vega-Lite default coverage | Warm ivory |
Theme Examples¶
Dark Theme:
title: "Analytics Dashboard" theme: dark layout: - chart: daily_metrics - chart: revenue_breakdown
FiveThirtyEight Theme:
title: "Election Results" theme: fivethirtyeight layout: - chart: poll_results
What Themes Control¶
Themes automatically style:
- ✅ Dashboard background - Overall page background color
- ✅ Chart colors - Bars, lines, areas, points
- ✅ Axis styling - Grid lines, labels, titles
- ✅ Tables - Header backgrounds, borders, stripes
- ✅ Variables - Input backgrounds, borders, labels
- ✅ Titles - Text color and contrast
Themes should not be the primary home for chart scaffolding defaults. If you find yourself deciding where an axis sits or whether grids/domains are shown by default, that belongs in a structure preset instead.
More precisely:
- theme answers how the scaffold is painted
- structure answers what scaffold exists and where it sits
Structures¶
Structures are reusable chart scaffolding presets. Built-ins live in
dataface/core/compile/chart_structures/ and are assembled into the runtime
config under structures:.
Dataface ships with a small set of canonical structures that can inherit from one another so we do not duplicate the same scaffolding rules across many themes.
Text-to-Mark Spectrum¶
When choosing or naming a structure, it can help to place the display on a
discrete text-to-mark spectrum:
table -> colored table -> spark table -> graphic table -> chart -> mini-chart
Each step shifts the balance away from textual and numeric cells and toward graphical marks as the primary carrier of statistical meaning.
table: a statistical display in which values are carried primarily by numbers, words, labels, and tabular structure. It may use meaningful graphical devices such as spacing, rules, line weight, or line style to organize and express relationships, but statistical marks do not yet dominate the display.colored table: a statistical table in which color carries some statistical meaning. Examples include negative values shown in red or cells shaded by magnitude.spark table: a table that includes tiny embedded statistical marks within cells or columns. Examples include sparklines, small bars, or other compact in-cell indicators.graphic table: a hybrid form in which tabular text and graphical marks share the work more evenly, while the row-and-column structure remains clearly visible.chart: a more conventionally chart-like statistical display in which most of the canvas is devoted to marks, while text mainly serves axes, labels, legends, or annotation.mini-chart: a highly compact statistical chart with very little or no text, where meaning is carried mostly by marks such as shape, position, length, angle, area, or color.
The spectrum does not depend on a strict boundary between tables and charts. Instead, it describes gradual changes in how statistical meaning is carried: first mainly by text and structure, then increasingly by marks.
For Dataface, this spectrum is most useful as a framing device for choosing and defining families of structures. It helps explain why some presets should preserve more tabular scaffolding while others should devote more of the canvas to marks.
What Structures Control¶
Structures should hold chart-skeleton defaults such as:
- axis side and axis posture defaults
- whether grids/domains exist at all
- legend placement
- title anchor / title positioning defaults
- other pre-Vega-Lite chart scaffolding choices
Concrete examples moved into structures include:
- y-axis on the left or right
- x-axis orientation
- whether grid lines exist
- whether the axis domain exists
- legend placement
- title anchoring
- default axis label angle / baseline / alignment posture
- axis title alignment / angle / x-y offsets
- whether band grids exist
Using a Structure¶
You can pick a structure in dataface.yml:
structure: editorial theme: light
This keeps the concerns separate:
structurecontrols the chart skeletonthemecontrols the visual skin
Custom Structures¶
You can add your own structures in dataface.yml and inherit from existing
ones:
structure: my-editorial structures: my-editorial: extends: editorial vega: config: axisY: orient: left legend: orient: bottom
You can also add Dataface-specific structure defaults used earlier in the chart pipeline:
structures: my-editorial: extends: editorial chart: axis_defaults: y: categorical_orient: left x: nominal: medium: angle: -20 align: right baseline: middle
When To Use Theme vs Structure¶
Use a theme when you are changing:
- palette
- font family
- font size
- fill/stroke colors
- stroke width
- symbol size
- background/surface colors
- table and variable styling
Use a structure when you are changing:
- whether the y-axis sits on the left or right
- whether an element exists at all, like a grid or domain
- whether grids/domains are shown
- legend placement
- title anchoring
- default axis label posture rules
Custom Themes¶
You can create custom themes in your dataface.yml config file:
# dataface.yml themes: my-brand: background: "#f8f9fa" title: color: "#2c3e50" axis: gridColor: "#ecf0f1" labelColor: "#7f8c8d" bar: fill: "#3498db" range: category: - "#3498db" - "#e74c3c" - "#2ecc71" - "#f39c12"
Then use it:
theme: my-brand
If you want the custom theme to have a preferred paired structure for internal
or legacy compatibility, set that separately in dataface.yml:
theme_structures: my-brand: my-editorial
This is most useful when you want a theme selection to carry a shared chart scaffolding preset without duplicating those structure keys in the theme file.
Use structure: when you want to control how charts are put together without
coupling those decisions to a visual brand preset:
title: "Vega-Lite Explorer" theme: vega-lite-explorer structure: vega-lite-explorer
Use the -rich pair when you want a more complete reference scaffold with many
more commented Vega-Lite sections:
theme: vega-lite-explorer-rich structure: vega-lite-explorer-rich
Example project structure:
structures: dense-editorial: extends: vega-lite-explorer concat: spacing: 20 axisBand: tickExtra: true bandPosition: 0.5 bar: discreteBandSize: 18
Full Vega-Lite Config Pass-Through¶
Theme objects are open-ended Vega-Lite config objects. Dataface reads a small subset for its own table/variable color derivation, but it passes through any valid Vega-Lite config keys you add.
You can use this in either place:
vega.configindataface.ymlfor project-wide defaultsthemes.<name>indataface.ymlfor reusable theme presets
Example:
# dataface.yml vega: config: axisBand: tickExtra: true bandPosition: 0.5 header: labelFontSize: 12 titleFontSize: 13 themes: newsroom: extends: light range: category: - "#1d4ed8" - "#ea580c" - "#059669" point: filled: true size: 64 boxplot: median: color: "#111827"
chart_defaults.yml ships with Dataface's default chart/Vega-Lite house style,
while default_config.yml holds broader app defaults. Use the official
Vega-Lite config docs as the full reference and layer your overrides in
dataface.yml.
Built-ins are assembled first, then your dataface.yml themes: block
deep-merges on top. That means you can either add a brand-new theme or
override part of a built-in one without copying the whole thing.
Theme Inheritance¶
Themes can extend other themes using extends:
# dataface.yml themes: my-dark-brand: extends: dark bar: fill: "#e74c3c" # Override just the bar color range: category: - "#e74c3c" - "#3498db"
Global Styling¶
Set styling options for the entire dashboard:
style: palette: "category10" # Color scheme name font: "Inter" # Font family grid_lines: true # Show grid lines by default background: "#f5f5f5" # General background color backgrounds: # Format-specific backgrounds svg: transparent png: "#ffffff" pdf: "#ffffff" css: "assets/custom.css" # Import custom CSS file
Style Options¶
palette: Color scheme (e.g., "category10", "viridis", "blues")font: Font family namegrid_lines:trueorfalseto show/hide grid lines by defaultbackground: General background color (hex, rgb, name, or "transparent")backgrounds: Format-specific backgrounds (svg, png, pdf)css: Path to a custom CSS file (relative to dashboard file or public root)
CSS Scope & Limitations¶
The style.css file styles the Dashboard Shell (HTML), but has limitations regarding internal Chart elements (SVG).
What CSS Can Style (HTML)¶
- Layout: Rows, columns, grids, margins.
- Typography: Section titles, markdown text, KPI cards, headers.
- Interactive Elements: Filter inputs, buttons, tabs.
- Backgrounds: Page background, section borders, shadows.
What CSS Cannot Style (Charts)¶
- Chart Internals: Bars, lines, axes, legends inside the Vega-Lite charts.
- PDF Exports: Static exports use a different rendering path where external CSS may not apply fully.
Recommendation:
- Use Style Options (style.palette, chart.style) for chart colors and axes.
- Use Custom CSS for layout, typography, and branding of the surrounding page.
Chart-Level Styling¶
Override theme for specific charts:
charts: custom_chart: title: "Custom Styled Chart" query: queries.sales type: bar x: month y: total_revenue style: palette: "viridis" # Different color scheme legend: show # Show legend grid_lines: false # Hide grid lines labels: show # Always show labels
Style Options¶
Color Palettes¶
Choose from built-in color palettes:
category10- Default categorical palette (10 colors)viridis- Perceptually uniform sequential paletteblues- Blue sequential palettereds- Red sequential palettegreens- Green sequential palettegrays- Grayscale palette
Choosing a palette:
- Categorical data: Use category10 or other categorical palettes
- Sequential data: Use viridis, blues, reds, greens
- Accessibility: Consider colorblind-friendly palettes
Legend¶
Control legend display:
style: legend: show # Always show legend legend: hide # Hide legend
Grid Lines¶
Show or hide grid lines:
style: grid_lines: true # Show grid lines grid_lines: false # Hide grid lines
Labels¶
Control axis label display:
style: labels: auto # Auto-label placement (default) labels: show # Always show labels labels: hide # Hide labels
Typography¶
Set the font family via the top-level style configuration:
style: font: "Inter" # Font family name
Common font choices:
- Inter - Modern, readable sans-serif
- Roboto - Google's Material Design font
- Open Sans - Friendly, readable sans-serif
- Lato - Humanist sans-serif
Board-Level Styling¶
Apply CSS-like styles to any board or nested layout section:
rows: - title: "Styled Section" style: background: "#f0f4f8" border: "2px solid #667eea" border-radius: "8px" padding: "16px" color: "#333" cols: - chart: my_chart
Supported Style Properties¶
| Property | Example | SVG | HTML | Description |
|---|---|---|---|---|
background |
"#f5f5f5" |
✅ | ✅ | Background color (hex, rgb, named) |
border |
"2px solid #ddd" |
✅ | ✅ | Border shorthand (width style color) |
border-radius |
"8px" |
✅ | ✅ | Corner rounding |
color |
"#333" |
✅ | ✅ | Text color |
padding |
"16px" |
✅ | ✅ | Inner spacing (affects content layout) |
margin |
"8px 16px" |
❌ | ✅ | Outer spacing |
gap |
"12px" |
✅ | ✅ | Override gap between child items |
Padding & Sizing¶
Padding is accounted for in layout calculations. When you add padding to a board:
- The board's children have less available space
- Content is properly inset from the border
- Height calculations include the padding
# Padding formats (CSS-style) style: padding: "16px" # All sides equal padding: "8px 16px" # Vertical, horizontal padding: "8px 16px 12px" # Top, horizontal, bottom padding: "8px 16px 12px 4px" # Top, right, bottom, left
Border Styling¶
Borders support the CSS shorthand format:
style: border: "2px solid #667eea" # width style color border-radius: "8px" # Rounded corners
Example: Styled Cards¶
Create card-style sections with backgrounds and borders:
cols: - content: "### Success Card" style: background: "#c8e6c9" border: "2px solid #4caf50" border-radius: "12px" color: "#1b5e20" - content: "### Warning Card" style: background: "#fff3e0" border: "2px solid #ff9800" border-radius: "12px"
Layout Sizing¶
Automatic Sizing¶
Dataface automatically calculates sizes based on content:
- Charts: 300px default height (KPIs: 100px, Tables: 250px)
- Titles: Height based on font size and text length
- Markdown content: Height based on rendered text with word-wrapping
User-Specified Widths¶
In cols layouts, specify widths for individual items:
cols: - width: "30%" # 30% of available width chart: sidebar_chart - width: "70%" # 70% of available width chart: main_chart
Supported formats:
- Percentages: "30%", "70%"
- Pixels: "200px", "400px"
- Auto (default): Remaining space divided equally
Gap Control¶
Control spacing between items:
# Per-section gap override rows: - title: "Compact Section" style: gap: "8px" # Smaller gap between children cols: - chart: a - chart: b
Content-Aware Heights¶
Heights are calculated based on content type:
| Content Type | Default Height |
|---|---|
| Standard chart | 300px |
| KPI card | 100px |
| Table | 250px |
| Title | Based on text |
| Markdown | Based on rendered content |
In cols layouts, all items get the same height (maximum of their content heights) for proper alignment.
Best Practices¶
Consistent Styling¶
- Use the same color palette throughout a dashboard
- Keep font choices consistent
- Use grid lines consistently (all on or all off)
Accessibility Considerations¶
- Choose colorblind-friendly palettes
- Ensure sufficient contrast
- Use labels and legends for clarity
Color Choices¶
- Categorical data: Use distinct colors (category10)
- Sequential data: Use gradient palettes (viridis, blues)
- Avoid: Too many colors (5-7 max for clarity)
Performance¶
- Styling has minimal performance impact
- Use global style when possible (more efficient)
- Override only when necessary
Related¶
- Charts - Chart styling options
- Boards - Layout and organization
- Configuration - Custom themes in
dataface.yml