TECHTRICKS365

Working With Multiple CSS Anchors And Popovers Inside The WordPress Loop | CSS-Tricks TechTricks365

Working With Multiple CSS Anchors And Popovers Inside The WordPress Loop | CSS-Tricks TechTricks365


I know, super niche, but it could be any loop, really. The challenge is having multiple tooltips on the same page that make use of the Popover API for toggling goodness and CSS Anchor Positioning for attaching a tooltip to its respective anchor element.

There’s plenty of moving pieces when working with popovers:

  • A popover needs an ID (and an accessible role while we’re at it).
  • A popovertarget needs to reference that ID.
  • IDs have to be unique for semantics, yes, but also to hook a popover into a popovertarget.

That’s just the part dealing with the Popover API. Turning to anchors:

  • An anchor needs an anchor-name.
  • A target element needs to reference that anchor-name.
  • Each anchor-name must be unique to attach the target to its anchor properly.

The requirements themselves are challenging. But it’s more challenging working inside a loop because you need a way to generate unique IDs and anchor names so everything is hooked up properly without conflicting with other elements on the page. In WordPress, we query an array of page objects:

$property_query = new WP_Query(array(
  'post_type' => 'page',
  'post_status' => 'publish',
  'posts_per_page' => -1, // Query them all!
  'orderby' => 'title',
  'order' => "ASC"
));

Before we get into our while() statement I’d like to stub out the HTML. This is how I want a page object to look inside of its container:



OK, let’s stub out the tooltip markup while we’re here, focusing just inside the

element since that’s what represents a single page.

accent-color

Experimental feature

With me so far? We’ll start with the Popover side of things. Right now we have a that is connected to a

. Clicking the former toggles the latter.

Styling isn’t really what we’re talking about, but it does help to reset a few popover things so it doesn’t get that border and sit directly in the center of the page. You’ll want to check out Michelle Barker’s article for some great tips that make this enhance progressively.

.info-tip {
  position: relative; /* Sets containment */

  /* Bail if Anchor Positioning is not supported */
  [popovertarget] {
    display: none;
  }

  /* Style things up if Anchor Positioning is supported */
  @supports (anchor-name: --infotip) {

    [popovertarget] {
      display: inline;
      position: relative;
    }

    [popover] {
      border: 0; /* Removes default border */
      margin: 0; /* Resets placement */
      position: absolute; /* Required */
  }
}

This is also the point at which you’ll want to start using Chrome because Safari and Firefox are still working on supporting the feature.

We’re doing good! The big deal at the moment is positioning the tooltip’s content so that it is beside the button. This is where we can start working with Anchor Positioning. Juan Diego’s guide is the bee’s knees if you’re looking for a deep dive. The gist is that we can connect an anchor to its target element in CSS. First, we register the as the anchor element by giving it an anchor-name. Then we anchor the

to the with position-anchor and use the anchor() function on its inset properties to position it exactly where we want, relative to the :
.tooltip {
  position: relative; /* Sets containment */

  /* Bail if Anchor Positioning is not supported */
  [popovertarget] {
    display: none;
  }

  /* Style things up if Anchor Positioning is supported */
  @supports (anchor-name: --tooltip) {

    [popovertarget] {
      anchor-name: --tooltip;
      display: inline;
      position: relative;
    }

    [popover] {
      border: 0; /* Removes default border */
      margin: 0; /* Resets placement */
      position: absolute; /* Required */
      position-anchor: --tooltip;
      top: anchor(--tooltip -15%);
      left: anchor(--tooltip 110%);
    }
  }
}

This is exactly what we want! But it’s also where things more complicated when we try to add more tooltips to the page. Notice that both buttons want to cull the same tooltip.

That’s no good. What we need is a unique ID for each tooltip. I’ll simplify the HTML so we’re looking at the right spot:

Experimental feature

The popover has an ID of #experimental-label. The anchor references it in the popovertarget attribute. This connects them but also connects other tooltips that are on the page. What would be ideal is to have a sequence of IDs, like:


...

...

...

We can make the page query into a function that we call:

function letterOutput($letter, $propertyID) {
  $property_query = new WP_Query(array(
    'post_type' => 'page',
    'post_status' => 'publish',
    'posts_per_page' => -1, // Query them all!
    'orderby' => 'title',
    'order' => "ASC"
  ));
}

And when calling the function, we’ll take two arguments that are specific only to what I was working on. If you’re curious, we have a structured set of pages that go Almanac → Type → Letter → Feature (e.g., Almanac → Properties → A → accent-color). This function outputs the child pages of a “Letter” (i.e., A → accent-color, anchor-name, etc.). A child page might be an “experimental” CSS feature and we’re marking that in the UI with tooltops next to each experimental feature.

We’ll put the HTML into an object that we can return when calling the function. I’ll cut it down for brevity…

$html .= '
'; $html .= ''; $html .= '

accent-color

'; $html .= ''; $html .= ''; $html .= '

'; // ... $html .= '

'; $html .= '
'; $html .= '
'; $html .= '
'; return $html;

WordPress has some functions we can leverage for looping through this markup. For example, we can insert the_title() in place of the hardcoded post title:

$html .= '

' . get_the_title(); . '

';

We can also use get_the_id() to insert the unique identifier associated with the post. For example, we can use it to give each

element a unique ID:
$html .= '
';

This is the secret sauce for getting the unique identifiers needed for the popovers:

// Outputs something like `id="experimental-label-12345"`
$html .= '


Exit mobile version