Canvas rendering improvements
Image embeds, note embeds with rendered markdown, custom hex colors, and style fixes for Obsidian Canvas rendering.

Canvas rendering just got an upgrade!
Create in Obsidian
Draw on Canvas
Bloom on Flowershow
Share with the world
Customize

Custom styles
Creating the file
- Create a new file named
custom.cssin the root of your repository (or the root directory of your site if you're publishing from a subfolder) - Add your CSS rules to customize colors, fonts, layouts, and more
- Publish it along with your content.
custom.css loads after the default theme, so a rule in custom.css wins over the theme when its selector is equally or more specific, without needing !important. Overriding the variables in :root is the most reliable way to restyle the site.
Start with the theme variables below for broad visual changes. When you need to target a particular component or state, use the semantic theme class reference, which groups Flowershow's stable CSS hooks by the UI area that emits them.
Theme variables
Flowershow exposes CSS custom properties (variables) in :root.
You can override them in custom.css without touching app code.
The variables below are drawn from two source files in the Flowershow repository — browse them directly for the full picture:
- default-theme.css — layout, typography, colors, border radius
- callouts.css — callout color tokens
Colors
Set the base colors for light and dark themes:
:root {
/* Light theme */
--color-l-background: #ffffff;
--color-l-foreground: #525252;
--color-l-accent: #fb923c;
/* Dark theme */
--color-d-background: #0c0a09;
--color-d-foreground: #d6d3d1;
--color-d-accent: #fb923c;
}
--color-foreground, --color-background, and --color-accent are resolved from these automatically depending on the active theme.
Foreground shade scale
Flowershow derives a 10-step shade scale from --color-foreground. These are used across navigation, content, borders, and interactive states:
--color-foreground-50— subtlest (borders, hover backgrounds)--color-foreground-100…--color-foreground-800--color-foreground-900— strongest (headings, high-contrast text)
You generally should not override these directly. Change the base --color-l-* / --color-d-* values instead and let Flowershow derive the scale.
Accent shades
--color-accent-lighter--color-accent-darker
Same advice applies: prefer changing --color-l-accent / --color-d-accent.
Semantic state colors
:root {
--color-danger: #dc2626;
--color-warning: #d97706;
}
Used in error cards and warning indicators.
Code block backgrounds
:root {
--color-code-bg: #fafafa; /* light mode */
--color-code-bg-dark: #2f2f2f; /* dark mode */
}
CTA button colors
The navbar call-to-action button is unstyled by default (inherits foreground tones). Override these to brand it:
:root {
--color-cta-bg: /* defaults to --color-foreground-700 */ --color-cta-bg-hover:
/* defaults to --color-foreground-500 */
--color-cta-text: /* defaults to #ffffff */;
}
Tag pill colors
Tag pills (the frontmatter tag row in page headers, inline #tags in your content, and the /tags pages) take their colors from four variables. The defaults are pink:
| Variable | Light default | Dark default |
|---|---|---|
--color-tag-pill-text | #db2777 | #f472b6 |
--color-tag-pill-bg | rgb(219 39 119 / 0.1) | rgb(244 114 182 / 0.12) |
--color-tag-pill-text-hover | #be185d | #f9a8d4 |
--color-tag-pill-bg-hover | rgb(219 39 119 / 0.16) | rgb(244 114 182 / 0.2) |
Unlike the --color-l-* / --color-d-* pairs, there is one set of tag variables. Values you set on :root apply in both light and dark mode. To use different colors in dark mode, also set them on :root[data-theme="dark"]:
:root {
--color-tag-pill-text: #0369a1;
--color-tag-pill-bg: #e0f2fe;
--color-tag-pill-text-hover: #075985;
--color-tag-pill-bg-hover: #bae6fd;
}
:root[data-theme="dark"] {
--color-tag-pill-text: #7dd3fc;
--color-tag-pill-bg: rgb(125 211 252 / 0.12);
--color-tag-pill-text-hover: #bae6fd;
--color-tag-pill-bg-hover: rgb(125 211 252 / 0.2);
}
To match tag pills to your accent color in both modes:
:root {
--color-tag-pill-text: var(--color-accent-darker);
--color-tag-pill-bg: color-mix(in oklab, var(--color-accent) 12%, transparent);
--color-tag-pill-text-hover: var(--color-accent);
--color-tag-pill-bg-hover: color-mix(in oklab, var(--color-accent) 20%, transparent);
}
Shape, padding and font are not variables. Style them with the .tag-pill class, for example .tag-pill { border-radius: var(--radius); }.
Typography
Font families
:root {
--font-heading: "Inter", sans-serif;
--font-body: "Inter", sans-serif;
}
Fonts and other files referenced from custom.css
- Paths resolve from your site root. Every page loads
custom.cssas a stylesheet from/custom.css, sourl()paths resolve against your site root, not the page's URL.url('/fonts/Brand.woff2')andurl('fonts/Brand.woff2')both point to thefontsfolder at your site root, on every page. We recommend starting paths with/because it's clearer. - Put
@importat the very top. Only comments may come before it. An@importafter any other rule is silently ignored. Don't addlayer(...): rules inside a cascade layer lose to the default theme. - Publish the files. Fonts (
.woff2,.woff,.ttf,.otf) are served like any other site file. If you usecontentInclude, include the folder that holds them. - Don't embed fonts as base64
data:URLs. They bloatcustom.css, so first visits to your site load slower. Separate font files load only when needed and are cached on their own.
See the Custom fonts guide for a full example.
Font sizes
All sizes are derived from --font-size-base. Override the base to scale everything proportionally, or override individual steps.
:root {
--font-size-base: 1rem;
--font-size-xxs: calc(var(--font-size-base) * 0.5); /* 0.5rem */
--font-size-xs: calc(var(--font-size-base) * 0.75); /* 0.75rem */
--font-size-sm: calc(var(--font-size-base) * 0.85); /* 0.85rem */
--font-size-lg: calc(var(--font-size-base) * 1.125); /* 1.125rem */
--font-size-xl: calc(var(--font-size-base) * 1.25); /* 1.25rem */
--font-size-2xl: calc(var(--font-size-base) * 1.5); /* 1.5rem */
--font-size-3xl: calc(var(--font-size-base) * 1.75); /* 1.75rem */
--font-size-4xl: calc(var(--font-size-base) * 2.25); /* 2.25rem */
--font-size-5xl: calc(var(--font-size-base) * 2.6); /* 2.6rem */
--font-size-6xl: calc(var(--font-size-base) * 3.1); /* 3.1rem */
}
Font weights
:root {
--font-weight-thin: 100;
--font-weight-extralight: 200;
--font-weight-light: 300;
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
--font-weight-extrabold: 800;
--font-weight-black: 900;
}
Line heights
:root {
--line-height-none: 1;
--line-height-tight: 1.25;
--line-height-snug: 1.375;
--line-height-normal: 1.5;
--line-height-relaxed: 1.625;
--line-height-loose: 2;
}
Border radius
Set --radius to 0 for sharp corners everywhere, or to a larger value for rounder components. The derived steps scale with it.
:root {
--radius: 0.375rem;
--radius-xs: calc(var(--radius) * 0.67);
--radius-md: calc(var(--radius) * 1.33);
--radius-lg: calc(var(--radius) * 2);
--radius-xl: calc(var(--radius) * 2.67);
}
Layout heights
--navbar-height sets the height of the navbar itself, and everything that has to clear it follows: the sticky sidebar, table of contents and mobile breadcrumb bar, the anchor scroll offset for headings (--navbar-height + 0.5rem) and the changelog's sticky date (--navbar-height + 1rem). Change it in one place to resize the navbar, e.g. --navbar-height: 3rem for a 48px header. When a page or site hides the navbar (showNavbar: false) it is set to 0px automatically.
:root {
--navbar-height: 4rem;
--subnav-height: 3rem; /* mobile breadcrumb/sidebar toggle bar */
}
Callout colors
Each callout type maps to one of these tokens. Override them to retheme all callouts of that category at once.
:root {
--callout-note-color: oklch(0.623 0.214 259); /* blue */
--callout-tip-color: oklch(0.714 0.143 215); /* cyan */
--callout-success-color: oklch(0.723 0.219 142); /* green */
--callout-warning-color: oklch(0.705 0.191 55); /* orange */
--callout-danger-color: oklch(0.627 0.258 29); /* red */
--callout-example-color: oklch(0.627 0.265 303); /* purple */
--callout-quote-color: oklch(0.554 0.014 286); /* zinc */
}
Callout type → color token mapping:
| Token | Types |
|---|---|
--callout-note-color | note, info, todo |
--callout-tip-color | tip, hint, important, abstract, summary, tldr |
--callout-success-color | success, check, done |
--callout-warning-color | warning, caution, attention, question, help, faq |
--callout-danger-color | danger, error, bug, failure, fail, missing |
--callout-example-color | example |
--callout-quote-color | quote, cite |
Full-width sections
On a page with layout: plain in its frontmatter, your content is not constrained: Flowershow adds no max-width, padding or margin around it, so every block already spans the full width between the navbar and the footer. You own the layout.
That means you don't need a width: 100vw breakout to make a band reach the edges. Don't add one: 100vw includes the width of the vertical scrollbar, so on browsers that draw a classic scrollbar (Windows, and macOS or Linux with "always show scrollbars") it makes the page a few pixels wider than the window and adds a horizontal scrollbar.
Instead, build the page from full-width bands, each with a centred inner container for its text:
<section class="band">
<div class="band-inner">
<h2>Our mission</h2>
<p>Full-width background, readable text column.</p>
</div>
</section>
.band {
padding: 4rem 1.5rem;
background-color: var(--color-accent);
}
.band-inner {
max-width: 48rem;
margin-inline: auto;
}
If you want most of the page in a narrow column with a few bands between, close the column, add the band, and open a new column, rather than wrapping the whole page in one narrow container.
Plain pages also drop the default Markdown typography: headings, lists, links and paragraph spacing get no prose styling, so style them yourself in custom.css.
On the default layout, content sits in a readable column next to the sidebar and table of contents, and full-width sections are not supported. Use layout: plain for landing-page-style pages.
Practical examples
Change the accent color
:root {
--color-l-accent: #0ea5e9;
--color-d-accent: #38bdf8;
}
Bigger, more readable body text
:root {
--font-size-base: 1.0625rem;
--line-height-normal: 1.65;
}
Custom heading font
:root {
--font-heading: "Space Grotesk", sans-serif;
}
Sharp corners throughout
:root {
--radius: 0;
}
Custom CTA button
:root {
--color-cta-bg: #0ea5e9;
--color-cta-bg-hover: #0284c7;
--color-cta-text: #ffffff;
}
Retheme warning callouts
:root {
--callout-warning-color: oklch(0.65 0.18 80); /* amber instead of orange */
}
Keep overrides in :root where possible. This gives you broad, consistent changes with less CSS.
For a detailed guide including examples and step-by-step instructions, check out this blog post.
What's new
- Image embeds – file nodes referencing images (
.png,.jpg,.gif,.svg,.webp) now render the actual image inside the canvas node, with proper sizing and lazy loading - Note embeds with rendered markdown – file nodes pointing to
.mdfiles now display the note's rendered content (headings, lists, links, callouts, math, code highlighting) instead of just the filename - Rich text in text nodes – text nodes now render full markdown (GFM, wiki-links, callouts, math, syntax highlighting) instead of plain text
- Custom hex colors – nodes and edges with custom hex color values (e.g.
#ff6600) now render correctly, in addition to the 6 Obsidian color presets - Improved labels display – edge labels are now positioned correctly on edge lines and have background for better readability.
For full details, see the Canvas documentation.