Portal

Portal is the low-level escape hatch for rendering a subtree in the global overlay stack instead of inline.
In ordinary layout, a child lives inside its parent's bounds and stacking context. A portal breaks that rule on purpose. It tells the runtime, "render this subtree in the overlay phase against the whole viewport." That is what makes modals, drawers, popovers, and toasts possible.
Most app authors should not start with Portal directly. Higher-level widgets such as Modal, Drawer, Popover, and Tooltip already handle the common overlay behavior and are easier to keep accessible and predictable.

Example

use fission::prelude::*;

let global_debug_overlay = if view.state().show_debug_banner {
    Portal {
        child: Container::new(Text::new("Diagnostics connected").into())
            .padding_all(12.0)
            .into(),
    }
    .into()
} else {
    Spacer::default().into()
};
Your app state still decides whether the portal exists. The widget only changes where the child is composed.

Field table

Field
Type
Meaning
Notes / default behavior
child
Widget
The subtree to place in the overlay stack.
Required. The portal itself returns an invisible spacer in normal layout.

Runtime boundary

Portal uses BuildCtxHandle::register_portal(...) during component conversion. That means the overlay registration is explicit and visible to the runtime, not a hidden side effect after the frame has already been built.
The helper registers into the default portal layer. If you need modal, flyout, or toast ordering, use a higher-level widget or call BuildCtxHandle::register_portal_with_layer(...) yourself inside a custom widget.

Specific advice

Use Portal when you are authoring your own overlay widget or application-wide overlay system. For normal product work, start with the more specific overlay widget that already matches the interaction. The more behavior you build directly on top of Portal, the more responsibility you take on for layering, dismissal, semantics, and testing.
Also remember that a portal changes rendering location, not state ownership. Keep open or closed flags, selected items, and form values in your app state as usual.

Production checklist

For Portal, review the fields that change behavior before treating the widget as finished: child. The goal is to make the product rule visible in state and actions, not hidden inside ad-hoc construction code.
If this widget appears inside an interactive flow, keep the surrounding action binding in the parent component and test that the flow still has one clear reducer path.
When child widgets are generated from data, give reordered or filtered rows an explicit WidgetId so retained local state and scroll behavior do not drift between items.
Check the semantics tree for the user-facing label or role that makes this widget understandable without relying only on pixels.
Add at least one component or harness test that confirms the visible text, semantic role, action dispatch, and layout constraint that matter for this widget in context.
If a screen starts repeating the same Portal setup, extract a named component around this widget. That keeps the reference API small while making product code easier to read and safer for generated code to copy.
Modal, Drawer, Popover, Tooltip, and flyout.
Fission
A cross-platform, GPU-accelerated user interface framework for Rust. MIT licensed.
Copyright (c) 2026 Fission
Ready to use today. Widget APIs are expected to remain stable; some runtime and shell APIs may change before 1.0.0.
Fission 0.7.0