htmlcssanchorpopoveralpine.js

Creating css anchors with dynamic identifiers


For the following HTML code (with AlpineJS syntax), I intent to create dynamic anchors for each entry. This works for the popover, but how can I set it for the button as well?

   <!-- looping through contacts with indivial values for "email" -->  
     <button class="icon" :popovertarget="email">
       <img alt="..." class="icon" src="/images/icons/extend.svg">
     </button>
     <dialog :anchor="email" :id="email" popover>
       <button @click="user.shareWith(email, false); $el.disabled = true">
         <img alt="❌" class="icon" src="/images/icons/cancel.svg"> 
         Teilen beenden
       </button>
     </dialog>  
   <!-- end of loop -->

CSS

[popover]{
  position: absolute;
  position-anchor: auto; // Using value from the anchor attribute
  position-area: center right;
  position-try-fallbacks: flip-block, flip-inline;
}
[popovertarget]{
  anchor-name: // what to put here to match the anchor var?
}

Or is there any other approach which does allow me to have any number of anchors with a dynamic identifier?


Solution

  • To dynamically anchor buttons and popovers using Alpine.js and the native Popover API, you need to make sure both the anchor and anchor-name values match — and are dynamically set for each contact.

    <template x-for="contact in contacts" :key="contact.email">
      <div>
        <!-- Set the anchor name dynamically using a unique email-based value -->
        <button
          class="icon"
          :anchorname="`anchor-${contact.email}`"
          :popovertarget="`popover-${contact.email}`"
        >
          <img alt="..." class="icon" src="/images/icons/extend.svg">
        </button>
    
        <!-- Anchor element (can be the same button or a sibling) -->
        <div :anchorname="`anchor-${contact.email}`"></div>
    
        <!-- Popover dialog linked to the anchor -->
        <dialog
          :anchor="`anchor-${contact.email}`"
          :id="`popover-${contact.email}`"
          popover
        >
          <button
            @click="user.shareWith(contact.email, false); $el.disabled = true"
          >
            <img alt="❌" class="icon" src="/images/icons/cancel.svg">
            Teilen beenden
          </button>
        </dialog>
      </div>
    </template>