Teleport

<teleport> renders its children somewhere else in the document.

The children stay part of your component - their state, bindings and handlers all work - but they escape the parent's overflow: hidden and its stacking context.

<Teleport> is the same component.

<script>
let open = false
</script>

<div class="box">
  <button onclick="open = !open">{open ? 'Hide' : 'Show'} the panel</button>

  <teleport to="#panel-layer">
    {open && <p class="panel">I was written inside the box, but I render below it.</p>}
  </teleport>
</div>

<div id="panel-layer"></div>
output

Props

Prop Type Default Description
to string required Any CSS selector: "body", "#modal-layer", ".popup-layer". If nothing matches, the children render in place and a warning is logged.
disabled boolean false Render in place instead. Reactive, so content can move back and forth.

to is reactive too, and the children are removed from the target when the component unmounts.

source
<script>
// On a narrow screen the dropdown stays put; on a wide one it escapes to <body>.
let isMobile = window.innerWidth < 768
</script>

<teleport to="body" disabled={isMobile}>
  <Dropdown items={items} />
</teleport>

Layers

Declare the targets once in a layout and give them a stacking order, so every teleport in the app lands in a known place:

<!-- layout.html -->
<slot />

<div id="tooltip-layer"></div>
<div id="modal-layer"></div>
<div id="toast-layer"></div>

For modals, drawers, popovers and toasts, reach for the built-in overlays first. They use the platform's own top layer, which needs no teleporting and no z-index at all. <teleport> is for the cases those do not cover.