Guide for creating beautiful Mermaid diagrams with high-contrast styling for GitHub markdown (light/dark mode compatible, no icons).
This skill provides guidance on creating beautiful, professional Mermaid diagrams that render correctly on GitHub and work well in both light and dark mode.
none — Allows subgraphs to adapt to any background([text]) for stadium shapes, ((text)) for circlesfa:fa-* icons, they render as textsubgraph Name["Label Text"] syntaxThe key insight for dark/light mode compatibility:
classDef myStyle fill:#DARK_COLOUR,stroke:#LIGHT_COLOUR,stroke-width:2px,color:#fff
#fff (white text on dark background)This approach ensures nodes are readable regardless of the page background.
This is the canonical template for GitHub-rendered Mermaid diagrams:
flowchart TD
%% --- COLOUR PALETTE & STYLING ---
%% Dark fills + light strokes = readable in both light and dark mode
classDef user fill:#374151,stroke:#d1d5db,stroke-width:2px,color:#fff
classDef primary fill:#5b21b6,stroke:#ddd6fe,stroke-width:2px,color:#fff
classDef secondary fill:#1e40af,stroke:#bfdbfe,stroke-width:2px,color:#fff
classDef accent fill:#c2410c,stroke:#fed7aa,stroke-width:2px,color:#fff
classDef success fill:#047857,stroke:#a7f3d0,stroke-width:2px,color:#fff
%% --- NODES ---
User((User)):::user
User --> Action(["Performs action"]):::user
Action --> Primary
subgraph Primary["Primary Component"]
direction TB
Step1(["Step 1"]):::primary
Step2(["Step 2"]):::primary
Step1 --> Step2
end
subgraph Secondary["Secondary Component"]
direction TB
Process(["Process"]):::secondary
end
Primary --> Secondary
Secondary --> Output(["Output"]):::success
%% --- SUBGRAPH STYLES ---
%% fill:none allows subgraphs to adapt to any background
style Primary fill:none,stroke:#8b5cf6,stroke-width:2px,stroke-dasharray:5 5,color:#8b5cf6
style Secondary fill:none,stroke:#3b82f6,stroke-width:2px,color:#3b82f6
Choose any colours you like — just follow the dark fill + light stroke pattern:
| Fill (Dark) | Stroke (Light) | Result |
|---|---|---|
#374151 |
#d1d5db |
Grey |
#5b21b6 |
#ddd6fe |
Purple |
#1e40af |
#bfdbfe |
Blue |
#c2410c |
#fed7aa |
Orange |
#047857 |
#a7f3d0 |
Green |
#b91c1c |
#fecaca |
Red |
#0f766e |
#99f6e4 |
Teal |
These are just examples. Use whatever colours suit your diagram — the principle is what matters.
subgraph MyGroup [Label With Spaces]
subgraph MyGroup["Label With Spaces"]
A[Square Node]
A(["Stadium shape"]) %% Rounded ends - use for most nodes
B((Circle)) %% Circle - use for users/actors
C{{"Decision"}} %% Hexagon for decisions
D[(Database)] %% Cylinder for databases/storage
style MySubgraph fill:#f0f9ff,stroke:#3182ce
style MySubgraph fill:none,stroke:#8b5cf6,stroke-width:2px,stroke-dasharray:5 5,color:#8b5cf6
Key points:
fill:none makes the background transparentstroke-dasharray:5 5 creates a dashed border (optional, looks clean)color:#... sets the subgraph label colour to match the borderA --> B %% Solid arrow
A -.-> B %% Dashed arrow
A -.->|Label| B %% Dashed arrow with label
A ==> B %% Thick arrow
flowchart TD
classDef user fill:#374151,stroke:#d1d5db,stroke-width:2px,color:#fff
classDef process fill:#5b21b6,stroke:#ddd6fe,stroke-width:2px,color:#fff
classDef decision fill:#c2410c,stroke:#fed7aa,stroke-width:2px,color:#fff
classDef success fill:#047857,stroke:#a7f3d0,stroke-width:2px,color:#fff
User((User)):::user
User --> Request(["Makes request"]):::user
Request --> Process
subgraph Process["Processing"]
direction TB
Validate(["Validate input"]):::process
Execute(["Execute logic"]):::process
Validate --> Execute
end
Execute --> Check{{"Success?"}}:::decision
Check -->|Yes| Done(["Complete"]):::success
Check -->|No| Request
style Process fill:none,stroke:#8b5cf6,stroke-width:2px,stroke-dasharray:5 5,color:#8b5cf6
A[fa:fa-user User] %% Renders as literal text
classDef bad fill:#ffffff,stroke:#000000,color:#000000 %% Invisible in dark mode
style Sub fill:#e0f2fe %% Looks different in light vs dark mode
subgraph Sub [My Label] %% Parse error!
flowchart TD
%% 1. Define styles: dark fill + light stroke + white text
classDef myStyle fill:#DARK,stroke:#LIGHT,stroke-width:2px,color:#fff
%% 2. Use rounded shapes
Node(["Text"]):::myStyle
%% 3. Quote subgraph labels
subgraph Sub["My Label"]
Inner(["Inner"])
end
%% 4. Style subgraphs with fill:none
style Sub fill:none,stroke:#COLOR,stroke-width:2px,color:#COLOR
Invoke this skill when creating:
<br> or other HTML in node labelssubgraph X["Label"] not subgraph X [Label]