Skip to Content
🚨 New Example: Handling Node Collisions!

Theming

Svelte Flow comes with minimal default styles and was designed to be fully customizable. Many of our users fully transform the look and feel of Svelte Flow to match their own brand or design system. This guide will introduce you to the different ways you can customize Svelte Flow’s appearance.

Default styles

Svelte Flow’s default styles are enough to get going with the built-in nodes. They provide some sensible defaults for styles like padding, border radius, and animated edges. You can see what they look like below:

import '@xyflow/svelte/dist/style.css';

You’ll typically load these default styles by importing them in your +layout.svelte, App.svelte, or another entry point.

Without dipping into custom nodes and edges, there are several ways you can style Svelte Flow’s basic look:

  • Passing inline styles through style props
  • Overriding the built-in classes with custom CSS
  • Overriding the CSS variables Svelte Flow uses
  • Using scoped styles in your Svelte components for custom nodes and edges

Base styles

If you just want to load the very basic styles that are necessary for Svelte Flow to work, you can import the base styles instead:

import '@xyflow/svelte/dist/base.css';

These base styles are required for Svelte Flow to function correctly. If you don’t import them or you override them with your own styles, some things might not work as expected!

Customization

Built in dark and light mode

You can choose one of the built-in color modes by using the colorMode prop ('dark', 'light', or 'system') as seen in the dark mode example.

<script> import { SvelteFlow } from '@xyflow/svelte'; import '@xyflow/svelte/dist/style.css'; </script> <SvelteFlow colorMode="dark" nodes={[]} edges={[]} />

When you use the colorMode prop, Svelte Flow adds a class to the root element (.svelte-flow) that you can use to style your flow based on the color mode:

.dark .svelte-flow__node { background: #777; color: white; } .light .svelte-flow__node { background: white; color: #111; }

Customizing with style props

The easiest way to start customizing the look and feel of your flows is to use the style prop on SvelteFlow and other components to inline your own CSS.

<script> import { SvelteFlow } from '@xyflow/svelte'; import '@xyflow/svelte/dist/style.css'; const styles = { background: 'red', width: '100%', height: 300, }; </script> <SvelteFlow style={styles} nodes={[]} edges={[]} />

CSS variables

If you don’t want to replace the default styles entirely but just want to tweak the overall look and feel, you can override some of the CSS variables we use throughout the library. For an example of how to use these CSS variables, check out our Feature Overview example.

These variables are mostly self-explanatory. Below is a table of all the variables you might want to tweak and their default values for reference:

Variable nameDefault
--xy-edge-stroke-default#b1b1b7
--xy-edge-stroke-width-default1
--xy-edge-stroke-selected-default#555
--xy-connectionline-stroke-default#b1b1b7
--xy-connectionline-stroke-width-default1
--xy-attribution-background-color-defaultrgba(255, 255, 255, 0.5)
--xy-minimap-background-color-default#fff
--xy-background-pattern-dots-color-default#91919a
--xy-background-pattern-lines-color-default#eee
--xy-background-pattern-cross-color-default#e2e2e2
--xy-node-color-defaultinherit
--xy-node-border-default1px solid #1a192b
--xy-node-background-color-default#fff
--xy-node-group-background-color-defaultrgba(240, 240, 240, 0.25)
--xy-node-boxshadow-hover-default0 1px 4px 1px rgba(0, 0, 0, 0.08)
--xy-node-boxshadow-selected-default0 0 0 0.5px #1a192b
--xy-handle-background-color-default#1a192b
--xy-handle-border-color-default#fff
--xy-selection-background-color-defaultrgba(0, 89, 220, 0.08)
--xy-selection-border-default1px dotted rgba(0, 89, 220, 0.8)
--xy-controls-button-background-color-default#fefefe
--xy-controls-button-background-color-hover-default#f4f4f4
--xy-controls-button-color-defaultinherit
--xy-controls-button-color-hover-defaultinherit
--xy-controls-button-border-color-default#eee
--xy-controls-box-shadow-default0 0 2px 1px rgba(0, 0, 0, 0.08)
--xy-resize-background-color-default#3367d9

These variables are used to define the defaults for the various elements of Svelte Flow. This means they can still be overridden by inline styles or custom classes on a per-element basis. If you want to override a variable, you can do so by adding:

.svelte-flow { --xy-node-background-color-default: #ff5050; }

Be aware that these variables are defined under .svelte-flow and under :root.

Overriding built-in classes

Some consider heavy use of inline styles to be an anti-pattern. In that case, you can override the built-in classes that Svelte Flow uses with your own CSS. There are many classes attached to all sorts of elements in Svelte Flow, but the ones you’ll likely want to override are listed below:

Class nameDescription
.svelte-flow

The outermost container

.svelte-flow__renderer

The inner container for zooming and panning (renderer pane)

.svelte-flow__selection

User selection

.svelte-flow__edges

The element containing all edges in the flow

.svelte-flow__edge

Applied to each Edge in the flow

.svelte-flow__edge.selected

Added to an Edge when selected

.svelte-flow__edge.animated

Added to an Edge when its animated prop is true

.svelte-flow__edge-path

The SVG <path /> element of an Edge

.svelte-flow__edge-label

The edge label

.svelte-flow__connection

Applied to the current connection line

.svelte-flow__connection-path

The SVG <path /> of a connection line

.svelte-flow__nodes

The element containing all nodes in the flow

.svelte-flow__node

Applied to each Node in the flow

.svelte-flow__node.selected

Added to a Node when selected.

.svelte-flow__node-default

Added when Node type is "default"

.svelte-flow__node-input

Added when Node type is "input"

.svelte-flow__node-output

Added when Node type is "output"

.svelte-flow__node-group

Added when Node type is "group"

.svelte-flow__nodesselection

Nodes selection

.svelte-flow__nodesselection-rect

Nodes selection rect

.svelte-flow__handle

Applied to each <Handle /> component

.svelte-flow__handle-top

Applied when a handle's Position is set to "top"

.svelte-flow__handle-right

Applied when a handle's Position is set to "right"

.svelte-flow__handle-bottom

Applied when a handle's Position is set to "bottom"

.svelte-flow__handle-left

Applied when a handle's Position is set to "left"

.svelte-flow__handle.connectingfrom

Added to a Handle when a connection is being drawn from this handle.

.svelte-flow__handle.connectingto

Added to a Handle when a connection line is above this handle.

.svelte-flow__handle.valid

Added to a Handle when a connection line is above a handle and the connection is valid.

.svelte-flow__handle.connectionindicator

Applied when the handle can start or end a connection (connectable state).

.svelte-flow__background

Applied to the <Background /> component

.svelte-flow__minimap

Applied to the <MiniMap /> component

.svelte-flow__controls

Applied to the <Controls /> component

Be careful if you go poking around the source code looking for other classes to override. Some classes are used internally and are required in order for the library to be functional. If you replace them you may end up with unexpected bugs or errors!

Scoped styles for custom nodes and edges

Custom nodes and edges are Svelte components. You can use scoped styles (or global CSS with @apply) in those components to keep styling isolated from the rest of your app.

Third-party solutions

You can choose to opt out of Svelte Flow’s default styling altogether and use a third-party styling solution instead. If you want to do this, you must make sure you still import the base styles (@xyflow/svelte/dist/base.css).

TailwindCSS

Custom nodes and edges are just Svelte components, and you can use any styling solution you’d like to style them. For example, you might want to use Tailwind  to style your nodes:

<script lang="ts"> import { Handle, Position, type NodeProps } from '@xyflow/svelte'; let { data }: NodeProps = $props(); </script> <div class="px-4 py-2 shadow-md rounded-md bg-background border-2 border-stone-400"> <div class="flex"> <div class="rounded-full w-12 h-12 flex justify-center items-center bg-card"> {data.emoji} </div> <div class="ml-2"> <div class="text-lg font-bold">{data.name}</div> <div class="text-gray-500">{data.job}</div> </div> </div> <Handle type="target" position={Position.Top} class="w-16 !bg-teal-500 rounded-none border-none" /> <Handle type="source" position={Position.Bottom} class="w-16 !bg-teal-500 rounded-none border-none" /> </div>

If you want to overwrite default styles, make sure to import Tailwind’s entry point after Svelte Flow’s base styles.

import '@xyflow/svelte/dist/style.css'; import 'tailwind.css';

For a complete example of using Tailwind with Svelte Flow, check out the tailwind example!

Last updated on