Monday, July 22, 2024
HomeCSSAnchor Positioning and the Popover API for a JS-Free Web site Menu

Anchor Positioning and the Popover API for a JS-Free Web site Menu


Anchor positioning in CSS allows us to place a component relative to an anchor ingredient anyplace on the web page. Previous to this we might solely place a component relative to its closest positioned ancestor, which generally meant doing a little HTML and CSS gymnastics or, as a rule, resorting to Javascript for positioning components like tooltips or nested submenus.

Popovers

Anchor positioning turns into much more highly effective when mixed with the Popover API. When constructing parts the place content material must grow to be seen upon consumer interplay, it may be a problem to make sure they’re absolutely accessible to customers of assistive applied sciences, and sometimes require further JS to get this proper. Utilizing net platform options just like the Popover API can assist us construct extra accessible web sites, as a lot of the required performance comes already baked in.

The best approach to create a popover is to use the popover attribute to the specified popover content material, then use the popovertarget attribute to focus on the popover’s ID.

<button popovertarget="popover_1">Open popover</button>
<p popover id="popover_1">I'm the popover!</p>

See the Pen
popover
by Michelle Barker (@michellebarker)
on CodePen.

We will additionally set off popovers with JS, however that’s for one more day.

Anchoring

If we need to place the popover relative to a component, we have to designate that ingredient as an anchor with the anchor-name property. On this instance, the anchor is the button that triggers the popover. The worth have to be a dashed ident.

#anchor_1 {
  anchor-name: --anchor_1;
}

On the popover we’ll specify the anchor we’re utilizing (with the position-anchor property). Then we’ll use the anchor() perform to manage the precise positioning. Right here we’re specifying that we would like the highest left of the popover to be positioned on the backside proper of the anchor ingredient.

#popover_1 {
  position-anchor: --anchor_1;
  high: anchor(--anchor_1 backside);
  left: anchor(--anchor_1 proper);
}

Alternatively we might use the logical property equivalents:

#popover_1 {
  position-anchor: --anchor_1;
  inset-block-start: anchor(--anchor_1 backside);
  inset-inline-start: anchor(--anchor_1 proper);
}

We’ll additionally must reset a number of the default types on the popover ingredient.

p,
[popover] {
  margin: 0;
  padding: 0;
  border: 0;
}

See the Pen
Popover with anchor positioning (inset space)
by Michelle Barker (@michellebarker)
on CodePen.

We will additionally place our anchored ingredient with the inset-area, property as a substitute of the anchor() perform. That is extra restricted, because it solely permits positioning on one axis, with solely a single key phrase of high, proper, backside or left (or logical property equivalents: block-start, inline-end, block-end, inline-start). We will nevertheless use transforms to maneuver our ingredient round if we so select.

#popover_1 {
  position-anchor: --anchor_1;
  inset-area: backside;
  rework: translateX(50%);
}

See the Pen
Popover with anchor positioning
by Michelle Barker (@michellebarker)
on CodePen.

Popover menu demo

The next demo takes benefit of the Popover API and anchor positioning to construct a navigation menu with interactive, nested submenus that doesn’t require any JS. Fairly cool!

See the Pen
Anchor place menu
by Michelle Barker (@michellebarker)
on CodePen.

Slightly than the button that triggers the popover, we’re utilizing the paren <menu> ingredient.

Animating popovers

Moreover, we’re animating the transition between open and closed states. That’s because of one more new characteristic, which permits us to transition discrete properties, such because the show property.

Beforehand, if we needed to transition a component that wasn’t there earlier than to a visual state, we must first change the show property from show: none to show: block or another worth, give it an opacity of 0 (making it invisible), then carry out the transition. We’s usually want some JS for that. However now we will transition the show worth too, with the transition-behavior property.

[popover] {
  transition: show 300ms;
  transition-behavior: allow-discrete;
}

Alternatively it may be included with the shorthand transition property.

[popover] {
  transition: show 300ms allow-discrete;
}

We’ll must explicitly set show: none on the popover, then transition it when open:

[popover] {
  show: none;
  transition: show 300ms allow-discrete;

  &:popover-open {
    show: block;
  }
}

This gained’t do a lot in the intervening time. We truly need to transition the opacity, so we have to embrace this too.

We must also transition the overlay property. This can be a property set by the browser, which specifies whether or not a popover or <dialog> ingredient is rendered within the high layer. Including it to the transition listing causes the elimination of the ingredient from the highest layer to be deferred, in order that it may be animated.

[popover] {
  show: none;
  opacity: 0;
  transition:
    opacity 300ms,
    show 300ms allow-discrete,
    overlay 500ms allow-discrete;

  &:popover-open {
    show: block;
    opacity: 1;
  }
}

If we check this we will see that the ingredient transitions out easily after we disguise it, nevertheless it nonetheless seem immediately after we click on the button.

See the Pen
Popover with anchor positioning
by Michelle Barker (@michellebarker)
on CodePen.

To transition easily in, we’d like @starting-style. We’ll apply this at-rule to the :popover-open pseudo-class on our popover, to inform the browser what model to start the transition from. (I’m nesting the types right here, as a result of why use only one newly supported CSS characteristic when you need to use all of them?).

[popover] {
  show: none;
  opacity: 0;
  transition:
    opacity 500ms,
    show 500ms allow-discrete,
    overlay 500ms allow-discrete;

  &:popover-open {
    show: block;
    opacity: 1;

    @starting-style {
      opacity: 0;
    }
  }
}

Una has an important rundown of those new transition options over on the Chrome weblog, so remember to test it out.

See the Pen
Transition and starting-style with popover
by Michelle Barker (@michellebarker)
on CodePen.

Really helpful sources

If you wish to know extra about popovers, I extremely suggest this speak from Hidde de Vries from CSS Day 2023.

There’s additionally hundreds extra to study anchor positioning than I’m lined right here! As soon as once more, Una has an in-depth information.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments