Saturday, January 18, 2025
HomeProgrammingFancy Menu Navigation Utilizing Anchor Positioning

Fancy Menu Navigation Utilizing Anchor Positioning


You will have for certain heard concerning the new CSS Anchor Positioning, proper? It’s a characteristic that permits you to hyperlink any component from the web page to a different one, i.e., the anchor. It’s helpful for all of the tooltip stuff, however it could possibly additionally create lots of different good results.

On this article, we are going to research menu navigation the place I depend on anchor positioning to create a pleasant hover impact on hyperlinks.

Cool, proper? We now have a sliding impact the place the blue rectangle adjusts to suit completely with the textual content content material over a pleasant transition. In case you are new to anchor positioning, this instance is ideal for you as a result of it’s easy and permits you to uncover the fundamentals of this new characteristic. We will even research one other instance so keep till the top!

Notice that solely Chromium-based browsers totally help anchor positioning on the time I’m penning this. You’ll need to view the demos in a browser like Chrome or Edge till the characteristic is extra extensively supported in different browsers.

The preliminary configuration

Let’s begin with the HTML construction which is nothing however a nav component containing an unordered record of hyperlinks:

<nav>
  <ul>
    <li><a href="#">Residence</a></li>
    <li class="lively"><a href="#">About</a></li>
    <li><a href="#">Tasks</a></li>
    <li><a href="#">Weblog</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</nav>

We is not going to spend an excessive amount of time explaining this construction as a result of it may be totally different in case your use case is totally different. Merely make sure the semantic is related to what you are attempting to do. As for the CSS half, we are going to begin with some fundamental styling to create a horizontal menu navigation.

ul {
  padding: 0;
  margin: 0;
  list-style: none;
  show: flex;
  hole: .5rem;
  font-size: 2.2rem;
}

ul li a {
  colour: #000;
  text-decoration: none;
  font-weight: 900;
  line-height: 1.5;
  padding-inline: .2em;
  show: block;
}

Nothing fancy thus far. We take away some default styling and use Flexbox to align the weather horizontally.

Sliding impact

First off, let’s perceive how the impact works. At first look, it appears to be like like we now have one rectangle that shrinks to a small peak, strikes to the hovered component, after which grows to full peak. That’s the visible impact, however in actuality, a couple of component is concerned!

Right here is the primary demo the place I’m utilizing totally different colours to raised see what is occurring.

Every menu merchandise has its personal “component” that shrinks or grows. Then we now have a standard “component” (the one in pink) that slides between the totally different menu objects. The primary impact is finished utilizing a background animation and the second is the place anchor positioning comes into play!

The background animation

We are going to animate the peak of a CSS gradient for this primary half:

/* 1 */
ul li {
  background: 
    conic-gradient(lightblue 0 0)
    backside/100% 0% no-repeat;
  transition: .2s;
}

/* 2 */
ul li:is(:hover,.lively) {
  background-size: 100% 100%;
  transition: .2s .2s;
}

/* 3 */
ul:has(li:hover) li.lively:not(:hover) {
  background-size: 100% 0%;
  transition: .2s;
}

We’ve outlined a gradient with a 100% width and 0% peak, positioned on the backside. The gradient syntax might look unusual, but it surely’s the shortest one that enables me to have a single-color gradient.

Associated: “Methods to accurately outline a one-color gradient”

Then, if the menu merchandise is hovered or has the .lively class, we make the peak equal to 100%. Notice the usage of the delay right here to verify the rising occurs after the shrinking.

Lastly, we have to deal with a particular case with the .lively merchandise. If we hover any merchandise (that’s not the lively one), then the .lively merchandise will get the shirking impact (the gradient peak is the same as 0%). That’s the aim of the third selector within the code.

Our first animation is finished! Discover how the rising begins after the shrinking completes due to the delay we outlined within the second selector.

The anchor positioning animation

The primary animation was fairly simple as a result of every merchandise had its personal background animation, which means we didn’t should care concerning the textual content content material because the background robotically fills the entire area.

We are going to use one component for the second animation that slides between all of the menu objects whereas adapting its width to suit the textual content of every merchandise. That is the place anchor positioning will help us.

Let’s begin with the next code:

ul:earlier than {
  content material:"";
  place: absolute;
  position-anchor: --li;
  background: pink;
  transition: .2s;
}

ul li:is(:hover, .lively) {
  anchor-name: --li;
}

ul:has(li:hover) li.lively:not(:hover) {
  anchor-name: none;
}

To keep away from including an additional component, I’ll want utilizing a pseudo-element on the ul. It ought to be absolutely-positioned and we are going to depend on two properties to activate the anchor positioning.

We outline the anchor with the anchor-name property. When a menu merchandise is hovered or has the .lively class, it turns into the anchor component. We additionally should take away the anchor from the .lively merchandise if one other merchandise is in a hovered state (therefore, the final selector within the code). In different phrases, just one anchor is outlined at a time.

Then we use the position-anchor property to hyperlink the pseudo-element to the anchor. Discover how each use the identical notation --li. It’s just like how, for instance, we outline @keyframes with a particular title and later use it inside an animation property. Remember the fact that you need to use the <dashed-indent> syntax, which means the title should at all times begin with two dashes (--).

The pseudo-element is accurately positioned however nothing is seen as a result of we didn’t outline any dimension! Let’s add the next code:

ul:earlier than {
  backside: anchor(backside);
  left: anchor(left);
  proper: anchor(proper);
  peak: .2em;  
}

The peak property is trivial however the anchor() is a newcomer. Right here’s how Juan Diego describes it within the Almanac:

The CSS anchor() perform takes an anchor component’s aspect and resolves to the <size> the place it’s positioned. It may well solely be utilized in inset properties (e.g. high, backside, backside, left, proper, and many others.), usually to position an absolute-positioned component relative to an anchor.

Let’s examine the MDN web page as nicely:

The anchor() CSS perform can be utilized inside an anchor-positioned component’s inset property values, returning a size worth relative to the place of the perimeters of its related anchor component.

Normally, we use left: 0 to position an absolute component on the left fringe of its containing block (i.e., the closest ancestor having place: relative). The left: anchor(left) will do the identical however as a substitute of the containing block, it’ll think about the related anchor component.

That’s all — we’re accomplished! Hover the menu objects within the under demo and see how the pseudo-element slides between them.

Every time you hover over a menu merchandise it turns into the brand new anchor for the pseudo-element (the ul:earlier than). This additionally implies that the anchor(...) values will change creating the sliding impact! Let’s not overlook the usage of the transition which is necessary in any other case, we could have an abrupt change.

We are able to additionally write the code otherwise like this:

ul:earlier than {
  content material:"";
  place: absolute;
  inset: auto anchor(proper, --li) anchor(backside, --li) anchor(left, --li);
  peak: .2em;  
  background: pink;
  transition: .2s;
}

In different phrases, we are able to depend on the inset shorthand as a substitute of utilizing bodily properties like left, proper, and backside, and as a substitute of defining position-anchor, we are able to embrace the anchor’s title contained in the anchor() perform. We’re repeating the identical title thrice which might be not optimum right here however in some conditions, you might have considered trying your component to think about a number of anchors, and in such instances, this syntax will make sense.

Combining each results

Now, we mix each results and, tada, the phantasm is ideal!

Take note of the transition values the place the delay is necessary:

ul:earlier than {
  transition: .2s .2s;
}

ul li {
  transition: .2s;
}

ul li:is(:hover,.lively) {
  transition: .2s .4s;
}

ul:has(li:hover) li.lively:not(:hover) {
  transition: .2s;
}

We now have a sequence of three animations — shrink the peak of the gradient, slide the pseudo-element, and develop the peak of the gradient — so we have to have delays between them to drag the whole lot collectively. That’s why for the sliding of the pseudo-element we now have a delay equal to the period of 1 animation (transition: .2 .2s) and for the rising half the delay is the same as twice the period (transition: .2s .4s).

Bouncy impact? Why not?!

Let’s attempt one other fancy animation through which the spotlight rectangle morphs right into a small circle, jumps to the following merchandise, and transforms again right into a rectangle once more!

I received’t clarify an excessive amount of for this instance because it’s your homework to dissect the code! I’ll supply a couple of hints so you’ll be able to unpack what’s occurring.

Just like the earlier impact, we now have a mix of two animations. For the primary one, I’ll use the pseudo-element of every menu merchandise the place I’ll alter the dimension and the border-radius to simulate the morphing. For the second animation, I’ll use the ul pseudo-element to create a small circle that I transfer between the menu objects.

Right here is one other model of the demo with totally different coloration and a slower transition to raised visualize every animation:

The difficult half is the leaping impact the place I’m utilizing an odd cubic-bezier() however I’ve an in depth article the place I clarify the approach in my CSS-Methods article “Superior CSS Animation Utilizing cubic-bezier().

Conclusion

I hope you loved this little experimentation utilizing the anchor positioning characteristic. We solely checked out three properties/values but it surely’s sufficient to organize you for this new characteristic. The anchor-name and position-anchor properties are the obligatory items for linking one component (usually known as a “goal” component on this context) to a different component (what we name an “anchor” component on this context). From there, you’ve gotten the anchor() perform to manage the place.

Associated: CSS Anchor Positioning Information

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments