Description
Related to #3027 (double circles + classDef), which was closed in Feb 2026 as fixed. The underlying CSS issue is the same and still affects stadium, flag, and the v11 @{shape} shapes.
classDef fill/stroke colors work on rectangles, rounded boxes, hexagons, diamonds, cylinders, and circles. They silently do nothing on stadiums ([]), flags >], double circles ((())), and all @{shape} syntax nodes.
flowchart LR
A["Rectangle"]:::blue
B(["Stadium"]):::blue
classDef blue fill:#1e40af,stroke:#60a5fa,color:#fff
Rectangle renders blue. Stadium stays gray.
This renders correctly in the live editor and in standalone HTML. It only breaks in environments where inline style attributes get stripped (Confluence Forge iframes being the one we hit).
Steps to reproduce
- Render this flowchart with mermaid 11.13.0 in any environment that strips inline
style attributes from SVG elements (e.g. Confluence Cloud with the Forge Mermaid Diagrams Viewer app):
flowchart LR
A["Rectangle"]:::blue
B(["Stadium"]):::blue
classDef blue fill:#1e40af,stroke:#60a5fa,color:#fff
-
Rectangle is blue, stadium is gray/default theme color.
-
Same diagram in the live editor or standalone HTML renders both shapes blue — inline style attributes compensate there.
Screenshots
Code Sample
flowchart LR
J(["Stadium"]) --> A["Square"] --> B("Rounded") --> C[["Subroutine"]] --> D(("Circle")) --> E>"Flag"]
E --> F{{"Hexagon"}} --> G[/"Para Right"/] --> H[\"Para Left"\] --> I((("Double Circle")))
classDef blue fill:#1e40af,stroke:#60a5fa,color:#fff
classDef red fill:#be123c,stroke:#fb7185,color:#fff
classDef green fill:#15803d,stroke:#4ade80,color:#fff
classDef purple fill:#6d28d9,stroke:#a78bfa,color:#fff
classDef orange fill:#b45309,stroke:#fbbf24,color:#fff
class A,F blue
class B,G red
class C,H green
class D,I purple
class E,J orange
Setup
- mermaid 11.13.0
- Discovered in Confluence Cloud via the Forge Mermaid Diagrams Viewer app (v2.79.0)
- Reproduces with any SVG consumer that strips inline
style attributes
Suggested Solutions
Change the generated classDef CSS from:
.blue > * { fill:#1e40af !important; }
to also include grandchildren:
.blue > *, .blue > g > path, .blue > g > circle { fill:#1e40af !important; }
This way the colors work regardless of whether inline styles are present. The inline styles already handle non-sandboxed environments, but the CSS should be self-sufficient too.
Additional Context
Why it breaks
Mermaid applies classDef colors two ways:
- CSS rules in the SVG
<style> block: .blue > * { fill:#1e40af !important }
- Inline
style attributes directly on shape elements as a fallback
For rectangles, the shape element (<rect>) is a direct child of the node <g class="node default blue">, so the .blue > * CSS selector reaches it. Works fine.
For stadiums and flags, mermaid wraps the actual <path> elements in an extra <g class="outer-path">:
<g class="node default blue">
<g class="outer-path"> ← .blue > * hits this
<path d="..."> ← .blue > * does NOT reach this
The <path> is a grandchild, not a child. The CSS misses it. Normally the inline style attribute on the <path> compensates, but in environments that strip inline styles (like Forge iframes), the color is lost entirely.
@stevecopley identified the same selector issue in #3027 back in Aug 2022:
The CSS needs to be altered to include the children of the group, i.e.
#graph-div .default>*, #graph-div .default>*>*
Affected shapes
From reading the source — these shapes always use roughjs and wrap paths in a <g>:
- Stadium (
shapes/stadium.ts) — always uses rc.path()
- Half-rounded rectangle / flag (
shapes/halfRoundedRectangle.ts) — same
- Double circle (
shapes/doubleCircle.ts) — wraps two <circle> elements in <g>
Shapes that put native SVG elements as direct children work fine (rect, polygon, cylinder path, etc).
Description
Related to #3027 (double circles + classDef), which was closed in Feb 2026 as fixed. The underlying CSS issue is the same and still affects stadium, flag, and the v11
@{shape}shapes.classDef fill/stroke colors work on rectangles, rounded boxes, hexagons, diamonds, cylinders, and circles. They silently do nothing on stadiums
([]), flags>], double circles((())), and all@{shape}syntax nodes.Rectangle renders blue. Stadium stays gray.
This renders correctly in the live editor and in standalone HTML. It only breaks in environments where inline
styleattributes get stripped (Confluence Forge iframes being the one we hit).Steps to reproduce
styleattributes from SVG elements (e.g. Confluence Cloud with the Forge Mermaid Diagrams Viewer app):Rectangle is blue, stadium is gray/default theme color.
Same diagram in the live editor or standalone HTML renders both shapes blue — inline
styleattributes compensate there.Screenshots
Code Sample
Setup
styleattributesSuggested Solutions
Change the generated classDef CSS from:
to also include grandchildren:
This way the colors work regardless of whether inline styles are present. The inline styles already handle non-sandboxed environments, but the CSS should be self-sufficient too.
Additional Context
Why it breaks
Mermaid applies classDef colors two ways:
<style>block:.blue > * { fill:#1e40af !important }styleattributes directly on shape elements as a fallbackFor rectangles, the shape element (
<rect>) is a direct child of the node<g class="node default blue">, so the.blue > *CSS selector reaches it. Works fine.For stadiums and flags, mermaid wraps the actual
<path>elements in an extra<g class="outer-path">:The
<path>is a grandchild, not a child. The CSS misses it. Normally the inlinestyleattribute on the<path>compensates, but in environments that strip inline styles (like Forge iframes), the color is lost entirely.@stevecopley identified the same selector issue in #3027 back in Aug 2022:
Affected shapes
From reading the source — these shapes always use roughjs and wrap paths in a
<g>:shapes/stadium.ts) — always usesrc.path()shapes/halfRoundedRectangle.ts) — sameshapes/doubleCircle.ts) — wraps two<circle>elements in<g>Shapes that put native SVG elements as direct children work fine (rect, polygon, cylinder path, etc).