A supplemental description that preserves focus and native trigger behavior. Use cem-dialog for interactive task content and cem-field for permanent field help.
Full examples and variation matrix ยท Automated stories
Blank inputs omit optional attributes. The preview uses #tooltip-playground-trigger. Change trigger-for to #tooltip-playground-alternate to rebind it. The gallery demonstrates projected triggers. Clear trigger-for to remove the relationship. Typed CEM references are authored in source. Keyboard focus presents immediately; pointer interest uses the delay controls. Escape dismisses while native editing and touch remain available.
{slice @name=trigger-for | #tooltip-playground-trigger}
{slice @name=show-delay | 500}
{slice @name=hide-delay | 100}
{slice @name=placement | block-start center}
{slice @name=anchor | }
{slice @name=boundary | }
{slice @name=fallback | }
{slice @name=overflow | flip shift resize}
{slice @name=anchor-lost | close}
{slice @name=surface-id | }
{slice @name=hidden | }
{slice @name=class | }
{slice @name=dir | ltr}
{slice @name=message | Supplemental description}
{slice @name=disabled | }
{slice @name=default-open | }
{cem-field @label="trigger-for" @value="{$datadom.slices.trigger-for}" @slice=trigger-for @slice-event=input @slice-value="$target.value"}
{cem-field @label="show-delay" @value="{$datadom.slices.show-delay}" @slice=show-delay @slice-event=input @slice-value="$target.value"}
{cem-field @label="hide-delay" @value="{$datadom.slices.hide-delay}" @slice=hide-delay @slice-event=input @slice-value="$target.value"}
{cem-field @label="placement" @value="{$datadom.slices.placement}" @slice=placement @slice-event=input @slice-value="$target.value"}
{cem-field @label="anchor" @value="{$datadom.slices.anchor}" @slice=anchor @slice-event=input @slice-value="$target.value"}
{cem-field @label="boundary" @value="{$datadom.slices.boundary}" @slice=boundary @slice-event=input @slice-value="$target.value"}
{cem-field @label="fallback" @value="{$datadom.slices.fallback}" @slice=fallback @slice-event=input @slice-value="$target.value"}
{cem-field @label="overflow" @value="{$datadom.slices.overflow}" @slice=overflow @slice-event=input @slice-value="$target.value"}
{fieldset @slice=anchor-lost @slice-event=change @slice-value="$target.value" | {legend | anchor-lost}{cem-radio @name="surface-anchor-lost" @value="freeze" @checked=true | freeze}{cem-radio @name="surface-anchor-lost" @value="close" | close}}
{cem-field @label="surface-id" @value="{$datadom.slices.surface-id}" @slice=surface-id @slice-event=input @slice-value="$target.value"}
{fieldset @slice=hidden @slice-event=change @slice-value="$target.value" | {legend | hidden}{cem-radio @name="surface-hidden" @value="" @checked=true | absent}{cem-radio @name="surface-hidden" @value="present" | present}}
{cem-field @label="class" @value="{$datadom.slices.class}" @slice=class @slice-event=input @slice-value="$target.value"}
{fieldset @slice=dir @slice-event=change @slice-value="$target.value" | {legend | dir}{cem-radio @name="surface-dir" @value="ltr" @checked=true | ltr}{cem-radio @name="surface-dir" @value="rtl" | rtl}}
{cem-field @label="message" @value="{$datadom.slices.message}" @slice=message @slice-event=input @slice-value="$target.value"}
{fieldset @slice=disabled @slice-event=change @slice-value="$target.value" | {legend | disabled}{cem-radio @name="surface-disabled" @value="" @checked=true | absent}{cem-radio @name="surface-disabled" @value="present" | present}}
{fieldset @slice=default-open @slice-event=change @slice-value="$target.value" | {legend | default-open}{cem-radio @name="surface-default-open" @value="" @checked=true | absent}{cem-radio @name="surface-default-open" @value="present" | present}}
{button @id=tooltip-playground-trigger @type=button | External tooltip launcher}
{button @id=tooltip-playground-alternate @type=button | Alternate tooltip launcher}
{cem-tooltip @trigger-for={if datadom.slices.trigger-for != "" { datadom.slices.trigger-for } else { null }} @show-delay={if datadom.slices.show-delay != "" { datadom.slices.show-delay } else { null }} @hide-delay={if datadom.slices.hide-delay != "" { datadom.slices.hide-delay } else { null }} @placement={if datadom.slices.placement != "" { datadom.slices.placement } else { null }} @anchor={if datadom.slices.anchor != "" { datadom.slices.anchor } else { null }} @boundary={if datadom.slices.boundary != "" { datadom.slices.boundary } else { null }} @fallback={if datadom.slices.fallback != "" { datadom.slices.fallback } else { null }} @overflow={if datadom.slices.overflow != "" { datadom.slices.overflow } else { null }} @anchor-lost={if datadom.slices.anchor-lost != "" { datadom.slices.anchor-lost } else { null }} @surface-id={if datadom.slices.surface-id != "" { datadom.slices.surface-id } else { null }} @hidden={if datadom.slices.hidden == "present" { true } else { null }} @class={if datadom.slices.class != "" { datadom.slices.class } else { null }} @dir={if datadom.slices.dir != "" { datadom.slices.dir } else { null }} @message={if datadom.slices.message != "" { datadom.slices.message } else { null }} @disabled={if datadom.slices.disabled == "present" { true } else { null }} @default-open={if datadom.slices.default-open == "present" { true } else { null }}}{cem-module-url @slice=sourceUrl @src="@epa-wg/cem-components/components/cem-tooltip/cem-tooltip.xhtml"}{cem:if @test="datadom.slices.sourceUrl" | {p | {a @href="{$datadom.slices.sourceUrl}" | Open canonical XHTML}}{cem-demo-element @legend="Canonical source" @src="{$datadom.slices.sourceUrl}" @type=xml @demo=false}}