<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Popover on Commentary of Takao</title><link>https://takao.blog/zh-tw/tags/popover/</link><description>Recent content in Popover on Commentary of Takao</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Commentary of Takao</copyright><lastBuildDate>Tue, 20 Aug 2024 00:00:00 +0900</lastBuildDate><atom:link href="https://takao.blog/zh-tw/tags/popover/index.xml" rel="self" type="application/rss+xml"/><item><title>CSS Popover API: Native Overlays 不需要 JavaScript</title><link>https://takao.blog/zh-tw/web/css-popover-api/</link><pubDate>Tue, 20 Aug 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/zh-tw/web/css-popover-api/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/css-popover-api-zh-tw.png" alt="Featured image of post CSS Popover API: Native Overlays 不需要 JavaScript" /&gt;&lt;h2 id="introduction"&gt;Introduction
&lt;/h2&gt;&lt;p&gt;Building overlays like tooltips, dropdown menus, and modals has traditionally required a significant amount of JavaScript. Developers have relied on CSS &lt;code&gt;position: absolute&lt;/code&gt; with manual coordinate calculations, ARIA attributes for accessibility, and framework-specific solutions such as React portals or Floating UI. The CSS Popover API changes this by providing a native, declarative way to create overlays that handle positioning, show/hide toggling, focus management, and light dismiss without any JavaScript.&lt;/p&gt;
&lt;p&gt;This article explores the Popover API in depth, covering its core attributes, JavaScript integration, styling capabilities, accessibility features, and how it compares to existing solutions like &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; and custom modals.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-the-basics-popover-and-popovertarget"&gt;1. The Basics: popover and popovertarget
&lt;/h2&gt;&lt;p&gt;The Popover API introduces two HTML attributes that form its foundation. The &lt;code&gt;popover&lt;/code&gt; attribute marks an element as a popover, while &lt;code&gt;popovertarget&lt;/code&gt; ties a trigger button to that popover element.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;button&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;popovertarget&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;my-popover&amp;#34;&lt;/span&gt;&amp;gt;Open Menu&amp;lt;/&lt;span style="color:#f92672"&gt;button&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;my-popover&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;popover&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt;&amp;gt;This content appears in a native popover.&amp;lt;/&lt;span style="color:#f92672"&gt;p&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Clicking the button toggles the popover&amp;rsquo;s visibility, no JavaScript required. The &lt;code&gt;popover&lt;/code&gt; attribute 接受 two modes:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Mode&lt;/th&gt;
					&lt;th&gt;Behavior&lt;/th&gt;
					&lt;th&gt;Use Case&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;popover=&amp;quot;auto&amp;quot;&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Light dismiss on outside click or Escape, only one auto popover visible at a time&lt;/td&gt;
					&lt;td&gt;Tooltips, dropdown menus&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;popover=&amp;quot;manual&amp;quot;&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Must be closed programmatically, multiple can coexist&lt;/td&gt;
					&lt;td&gt;Notification toasts, slide-out panels&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="2-the-popover-toggle-api"&gt;2. The Popover Toggle API
&lt;/h2&gt;&lt;p&gt;When you need programmatic control, the Popover Toggle API provides three methods on &lt;code&gt;HTMLElement&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;showPopover()&lt;/code&gt; — displays the popover&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hidePopover()&lt;/code&gt; — hides the popover&lt;/li&gt;
&lt;li&gt;&lt;code&gt;togglePopover()&lt;/code&gt; — toggles visibility&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;popover&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; document.&lt;span style="color:#a6e22e"&gt;getElementById&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;my-popover&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;popover&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;showPopover&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The API also fires two events: &lt;code&gt;beforetoggle&lt;/code&gt; and &lt;code&gt;toggle&lt;/code&gt;. The &lt;code&gt;beforetoggle&lt;/code&gt; event includes &lt;code&gt;oldState&lt;/code&gt; and &lt;code&gt;newState&lt;/code&gt; properties, making it ideal for performing actions before the visibility change, such as fetching dynamic content or animating.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;popover&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;addEventListener&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;beforetoggle&amp;#39;&lt;/span&gt;, (&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;newState&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;open&amp;#39;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Popover is about to open&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="3-light-dismiss-behavior"&gt;3. Light Dismiss Behavior
&lt;/h2&gt;&lt;p&gt;Auto popovers handle closing intelligently. They automatically dismiss when the user clicks outside the popover, presses the Escape key, or opens another auto popover. This behavior is powered by the same close-watcher infrastructure used by &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Manual popovers, on the other hand, require explicit dismissal via &lt;code&gt;hidePopover()&lt;/code&gt; or &lt;code&gt;popovertarget&lt;/code&gt;. This makes them suitable for modal-like interactions where the user must complete an action before the overlay closes.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;button&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;popovertarget&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;toast&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;popovertargetaction&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;show&amp;#34;&lt;/span&gt;&amp;gt;Show Toast&amp;lt;/&lt;span style="color:#f92672"&gt;button&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;toast&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;popover&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;manual&amp;#34;&lt;/span&gt;&amp;gt;Action completed!&amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;popovertargetaction&lt;/code&gt; attribute lets you specify &lt;code&gt;&amp;quot;show&amp;quot;&lt;/code&gt;, &lt;code&gt;&amp;quot;hide&amp;quot;&lt;/code&gt;, or the default &lt;code&gt;&amp;quot;toggle&amp;quot;&lt;/code&gt; behavior.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="4-anchor-positioning"&gt;4. Anchor Positioning
&lt;/h2&gt;&lt;p&gt;The Popover API integrates naturally with the CSS Anchor Positioning API, eliminating the need for libraries like Popper.js or Floating UI for most use cases.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;popover&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;position-anchor&lt;/span&gt;: &lt;span style="color:#f92672"&gt;--&lt;/span&gt;trigger;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; inset-area: &lt;span style="color:#66d9ef"&gt;block&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;button&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;trigger&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;popovertarget&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;tooltip&amp;#34;&lt;/span&gt;&amp;gt;Hover me&amp;lt;/&lt;span style="color:#f92672"&gt;button&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;tooltip&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;popover&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;popover&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;anchor&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;trigger&amp;#34;&lt;/span&gt;&amp;gt;Tooltip content&amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;anchor&lt;/code&gt; attribute binds the popover to its trigger, and CSS properties like &lt;code&gt;inset-area&lt;/code&gt; and &lt;code&gt;position-fallback&lt;/code&gt; control where the popover appears. If the popover would overflow the viewport, it automatically flips to the opposite side — a behavior that previously required JavaScript to detect and adjust.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="5-styling-and-animations"&gt;5. Styling and Animations
&lt;/h2&gt;&lt;p&gt;Popovers render in the top layer, meaning they appear above everything else regardless of z-index. This eliminates the need for stacking context management.&lt;/p&gt;
&lt;p&gt;Use the &lt;code&gt;::backdrop&lt;/code&gt; pseudo-element to style the area behind the popover:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#f92672"&gt;popover&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt;::&lt;span style="color:#a6e22e"&gt;backdrop&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;background&lt;/span&gt;: rgba(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.3&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;[popover]:popover-open&lt;/code&gt; pseudo-class targets the popover when it is visible, enabling transition-based animations. However, because popovers toggle between &lt;code&gt;display: none&lt;/code&gt; and &lt;code&gt;display: block&lt;/code&gt;, CSS transitions from display changes do not work by default. Work around this with &lt;code&gt;@starting-style&lt;/code&gt; and the &lt;code&gt;overlay&lt;/code&gt; property:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@&lt;span style="color:#66d9ef"&gt;starting-style&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#f92672"&gt;popover&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt;:&lt;span style="color:#a6e22e"&gt;popover-open&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;opacity&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;translate&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;-10&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#f92672"&gt;popover&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt;:&lt;span style="color:#a6e22e"&gt;popover-open&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;opacity&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;translate&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;transition&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;opacity&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.3&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;s&lt;/span&gt;, translate &lt;span style="color:#ae81ff"&gt;0.3&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;s&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;overlay&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.3&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;s&lt;/span&gt; allow-discrete;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="6-accessibility"&gt;6. Accessibility
&lt;/h2&gt;&lt;p&gt;The Popover API handles many accessibility concerns automatically. It assigns appropriate implicit roles (&lt;code&gt;group&lt;/code&gt; or &lt;code&gt;dialog&lt;/code&gt; depending on context), moves focus to the popover when it opens, traps focus within auto popovers, and handles Escape key dismissal.&lt;/p&gt;
&lt;p&gt;For additional context, use &lt;code&gt;aria-describedby&lt;/code&gt; to link the popover to its trigger description, or &lt;code&gt;aria-label&lt;/code&gt; when the popover content lacks visible heading text.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;button&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;popopertarget&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;help&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;aria-describedby&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;help&amp;#34;&lt;/span&gt;&amp;gt;Help&amp;lt;/&lt;span style="color:#f92672"&gt;button&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;help&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;popover&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;role&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;tooltip&amp;#34;&lt;/span&gt;&amp;gt;Press Escape to close this tip.&amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If the popover functions as a menu, explicitly set &lt;code&gt;role=&amp;quot;menu&amp;quot;&lt;/code&gt; and use &lt;code&gt;aria-activedescendant&lt;/code&gt; for keyboard navigation.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="7-popover-vs-dialog-vs-custom-modals"&gt;7. Popover vs. &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; vs. Custom Modals
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Feature&lt;/th&gt;
					&lt;th&gt;Popover API&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt;&lt;/th&gt;
					&lt;th&gt;Custom Modal&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Light dismiss&lt;/td&gt;
					&lt;td&gt;Built-in (auto)&lt;/td&gt;
					&lt;td&gt;Manual implementation&lt;/td&gt;
					&lt;td&gt;Manual implementation&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Top layer&lt;/td&gt;
					&lt;td&gt;Yes&lt;/td&gt;
					&lt;td&gt;Yes via &lt;code&gt;showModal()&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Via portal or z-index&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;JS required to open&lt;/td&gt;
					&lt;td&gt;No&lt;/td&gt;
					&lt;td&gt;Yes (&lt;code&gt;show()&lt;/code&gt;/&lt;code&gt;showModal()&lt;/code&gt;)&lt;/td&gt;
					&lt;td&gt;Yes&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;專注 trapping&lt;/td&gt;
					&lt;td&gt;Auto popovers&lt;/td&gt;
					&lt;td&gt;Modal dialogs&lt;/td&gt;
					&lt;td&gt;Custom implementation&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Best for&lt;/td&gt;
					&lt;td&gt;Tooltips, menus, toasts&lt;/td&gt;
					&lt;td&gt;Confirmations, forms&lt;/td&gt;
					&lt;td&gt;Complex framework-managed overlay&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Choose &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; for modal forms and confirmations where focus trapping is essential. Use Popover for lightweight, non-modal overlays. Custom modals remain useful when you need framework-managed state or complex orchestration.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="8-browser-支援-and-polyfills"&gt;8. Browser 支援 and Polyfills
&lt;/h2&gt;&lt;p&gt;The Popover API is 支援 in Chrome 114+, Edge 114+, Firefox 125+, and Safari 17+. Feature detection is straightforward:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;typeof&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;HTMLElement&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;prototype&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;showPopover&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;function&amp;#39;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Popover API is supported
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For non-supporting browsers, the &lt;code&gt;@oddbird/popover-polyfill&lt;/code&gt; provides a fallback. Note that the polyfill cannot fully replicate &lt;code&gt;::backdrop&lt;/code&gt; or top-layer behavior and uses &lt;code&gt;position: fixed&lt;/code&gt; instead.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="結論"&gt;結論
&lt;/h2&gt;&lt;p&gt;The CSS Popover API marks a significant step forward for declarative UI development. By handling show/hide toggling, light dismiss, focus management, and positioning natively, it eliminates the need for JavaScript in a wide range of overlay use cases. Combined with CSS Anchor Positioning, it provides a solid foundation for tooltips, dropdown menus, toast notifications, and context menus.&lt;/p&gt;
&lt;p&gt;For complex scenarios that exceed the API&amp;rsquo;s scope — such as multi-step modals or framework-managed portals — existing JavaScript solutions remain valuable. But for the majority of overlay patterns, the Popover API is the simpler, more accessible, and more performant choice.&lt;/p&gt;</description></item></channel></rss>