• Introduction
    • Why Liquid Oxygen
    • Getting started
      • React
      • Vue
  • Guides
    • CSS vs. Web Components
    • Component assets
    • Type checking and intellisense
    • Server-side rendering
    • Event handling
    • Form validation
    • Tailwind CSS integration
    • Design tokens
    • Testing
    • Sandbox applications
    • Troubleshooting
      • Popped-out element is rendered in wrong container
      • Failed to execute removeChild on Node
    • FAQ
    • Contributing
  • Globals
    • Animations
    • Border-radius
    • Colors
    • Focus
    • Fonts
    • Shadows
    • Spacings
    • Theming
    • Typography
  • Components
    • Accordion
      • Accordion Panel
      • Accordion Section
      • Accordion Toggle
    • Background Cells
    • Badge
    • Breadcrumbs
      • Crumb
    • Button
    • Card
      • Card Stack
    • Checkbox
    • Circular Progress
    • Context Menu
      • Menu
      • Menuitem
      • Menuitem Group
    • Cookie Consent
    • Header
    • Icon
    • Input
    • Input Message
    • Label
    • Link
    • Loading Indicator
    • Modal
    • Notice
    • Notification
    • Pagination
    • Progress
    • Radio Button
    • Screen Reader Live
    • Screen Reader Only
    • Select
      • Option
      • Option Group
    • Sidenav
      • Sidenav Accordion
      • Sidenav Back
      • Sidenav Header
      • Sidenav Heading
      • Sidenav Navitem
      • Sidenav Separator
      • Sidenav Slider
      • Sidenav Subnav
      • Sidenav Toggle Outside
    • Slider
    • Stepper
      • Step
    • Switch
      • Switch Item
    • Table
      • Table Body
      • Table Caption
      • Table Cell
      • Table Colgroup
      • Table Column
      • Table Footer
      • Table Head
      • Table Header
      • Table Row
      • Table Toolbar
    • Tabs
      • Tab
      • Tab List
      • Tab Panel
      • Tab Panel List
    • Toggle
    • Tooltip
    • Typography
  • Data Visualization
    • Getting Started
  1. Problem
  2. Solution
Guides Troubleshooting Popped-out element is rendered in wrong container
(external link)

Popped-out element is rendered in wrong container #

Problem #

Some components have a popper element that needs to stay above every other element when popped out. The ld-select component, the ld-context-menu component and the ld-tooltip component are examples of such components. By default, this is achieved by rendering the popped-out element as a direct child of the body element.

However, in some cases this default behavior can be problematic. For instance:

  • When using the component within the ld-modal component, the browser may render the dialog element above the popped-out element.
  • When using a UI library, such as React or Vue, your application may have been mounted on an element within the body element. This may result in event handlers not being called, because the event listeners may be attached to the root element of the application and not the body element.
  • When you want the popped-out element to be rendered within a container with specific dimensions and overflow settings.

Solution #

All components, which have a popper element, can be configured to pop out within a specific element using the tetherOptions property, which expects an object of options, including the bodyElement option. Use this option to specify the container, which shall become the parent element for the popped-out element. Please refer to the Tether documentation for more information on available options.

Here is an example on how you can specify the application root element as the bodyElement in a React application:

export default function App() {
  const tetherOptions = {
    bodyElement: document.getElementById('root')
  }
  return (
    <>
      <LdTooltip tetherOptions={tetherOptions} triggerType="click">
        <LdButton slot="trigger">File context menu</LdButton>
        <LdButton onClick={/* ... */}>Copy URL</LdButton>
        <LdButton onClick={/* ... */}>Download</LdButton>
      </LdTooltip>
    </>
  )
}

This example demonstrates how you can specify the bodyElement when using the ld-modal component:

export default function App() {
  const modalRef = useRef(null)
  const tetherOptions = {
    bodyElement: modalRef.current,
    constraints: [{ to: 'scrollParent' }],
  }
  const [open, setOpen] = useState(false)
  return (
    <>
      <LdModal
        onLdmodalclosed={() => setOpen(false)}
        open={open}
        ref={modalRef}
      >
        <LdTypo slot="header">We make a fruit salat!</LdTypo>
        <LdSelect
          name="fruit"
          placeholder="Pick a fruit"
          tetherOptions={tetherOptions}
        >
          <LdOption value="apple">Apple</LdOption>
          <LdOption value="banana">Banana</LdOption>
        </LdSelect>
      </LdModal>
      <LdButton
        onClick={() => {
          setOpen(true)
        }}
      >
        Open Modal
      </LdButton>
    </>
  )
}