Creating a dynamic animation for a navigation bar's underline

I'm attempting to add a smooth underline effect to the links in my navbar when they are hovered over. Unfortunately, the entire ul element is being underlined instead of just the selected link.

Is there a way to resolve this issue?

a {
  text-decoration: none;
  color: black;
}

.nav a::before {
  content: "";
  position: absolute;
  width: 100%;
  height: 2px;
  bottom: 0;
  left: 0;
  background-color: rgb(92, 149, 112);
  visibility: hidden;
  transform: scaleX(0);
  transition: all 0.3s ease-in-out 0s;
}

.nav a:hover::before {
  visibility: visible;
  transform: scaleX(1);
}

ul.nav {
  font-size: 11px;
  list-style: none;
  position: fixed;
  display: block;
  padding: 0;
  margin: 0;
  z-index: 100;
  top: 0.5em;
  right: 1.5em;
}

.nav li {
  display: inline-block;
  margin: 7px 15px;
}

.nav a:active::before {
  visibility: visible;
  transform: scaleX(1)
}
<ul class="nav">
  <li id="nav-home"><a id="a-home" href="#">Home</a></li>
  <li id="nav-services"><a href="#">Services</a></li>
  <li id="nav-about"><a href="#">About</a></li>
  <li id="nav-contact"><a href="#">Contact</a></li>
</ul>

Answer №1

Make sure to wrap the absolutely positioned element a inside a relative parent li. Check out this article on Absolute Positioning inside Relative Positioning for more details on why this is necessary. The absolutely positioned a was previously treating the entire ul as the relative parent.

Additional Code:

.nav li {
  position: relative;
}

.nav a::before  { 
   bottom: -2px; /* Adjust to match the border height */
}

a {
  text-decoration: none;
  color: black;
}

.nav li {
  position: relative;
}

.nav a::before {
  content: "";
  position: absolute;
  width: 100%;
  height: 2px;
  bottom: -2px;
  left: 0;
  background-color: rgb(92, 149, 112);
  visibility: hidden;
  transform: scaleX(0);
  transition: all 0.3s ease-in-out 0s;
}

.nav a:hover::before {
  visibility: visible;
  transform: scaleX(1);
}

ul.nav {
  font-size: 11px;
  list-style: none;
  position: fixed;
  display: block;
  padding: 0;
  margin: 0;
  z-index: 100;
  top: 0.5em;
  right: 1.5em;
}

.nav li {
  display: inline-block;
  margin: 7px 15px;
}

.nav a:active::before {
  visibility: visible;
  transform: scaleX(1);
}
<ul class="nav">
  <li id="nav-home"><a id="a-home" href="#">Home</a></li>
  <li id="nav-services"><a href="#">Services</a></li>
  <li id="nav-about"><a href="#">About</a></li>
  <li id="nav-contact"><a href="#">Contact</a></li>
</ul>

Answer №2

The issue at hand arises from the pseudo element a::before being absolutely positioned with respect to the ul.nav. This occurs because it is the nearest positioned element above it. Consequently, the element is removed from the normal flow of the document, causing width: 100%" to expand it to 100% of the ul width. To correct this, add position: relative to the a style, as demonstrated below:

a {
  text-decoration: none;
  color: black;
  position: relative;
}

.nav a::before {
  content: "";
  position: absolute;
  width: 100%;
  height: 2px;
  bottom: 0;
  left: 0;
  background-color: rgb(92, 149, 112);
  visibility: hidden;
  transform: scaleX(0);
  transition: all 0.3s ease-in-out 0s;
}

.nav a:hover::before {
  visibility: visible;
  transform: scaleX(1);
}

ul.nav {
  font-size: 11px;
  list-style: none;
  position: fixed;
  display: block;
  padding: 0;
  margin: 0;
  z-index: 100;
  top: 0.5em;
  right: 1.5em;
}

.nav li {
  display: inline-block;
  margin: 7px 15px;
}

.nav a:active::before {
  visibility: visible;
  transform: scaleX(1)
}
<ul class="nav">
  <li id="nav-home"><a id="a-home" href="#">Home</a></li>
  <li id="nav-services"><a href="#">Services</a></li>
  <li id="nav-about"><a href="#">About</a></li>
  <li id="nav-contact"><a href="#">Contact</a></li>
</ul>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What could be causing my insertRow function to inject empty cells into my table?

I am facing an issue with adding the results of a fetch request into a table as a new row. Strangely, when I click the button to trigger this function for the first time, it adds an empty row instead of the desired data. However, on subsequent clicks, the ...

Creating an animated link with a dynamic underline featuring a trio of vibrant colors

I'm having trouble figuring out how to animate my links on hover with 3 different colors. I attempted using the linear-gradient property but it doesn't seem to be working. Any suggestions on how to proceed? Below is an example of what I'm a ...

The process of displaying a single large image from a local file system using the elements input, img, and canvas

I am attempting to create a mobile-friendly picture upload webpage, but I keep experiencing memory issues causing the browser to crash when the picture is too large. Here's my code: <input type="file" id="testFile" /> <img src="" style="posi ...

Issue with Ionic app on iPhone X not correctly detecting safe areas

Struggling to place a loading element between the top toolbar and bottom tabs on various iPhone models and iOS versions. The challenge arises with iOS 10. Using "margin-top" causes errors, while "padding-top" doesn't work on iPhone X. Is there a CSS s ...

Troubleshooting Issue with jQuery replaceWith in Loop

Trying to make it so that when the update button is clicked, the text on the left side becomes an input box: Click the update button and the text on the left will be an input box However, instead of just one input box appearing, all the text on the left s ...

Tips for positioning a div at the bottom using Bootstrap

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3d5f5252494e494f5c4d7d08130c130e">[email protected]</a>/dist/css/bootstrap.min.css"> <div class="co ...

Fluid and static dimensions in CSS

I am looking to have two divs in the same row in HTML, where one remains a constant width while the other adjusts its size as the end user increases the web page. My initial attempt was to define a parent div with two child divs like this: <div> ...

Utilize Bootstrap button dropdown to automatically assign a selected value to a list item

I have a form with a select box that transforms into a bootstrap button after the page loads. However, I am unable to set the selected value for the converted bootstrap button drop-down li. <button type="button" class="btn dropdown-toggle btn-default" ...

Utilizing JavaScript to assign a CSS class to an <li> list item

I am working on a page that includes a menu feature: https://jsfiddle.net/dva4zo8t/ When a menu button is clicked, the color changes and I need to retain this color even after the page is reloaded: $('[id*="button"]').click(function() { $( ...

What is the best way to implement an anchor link in my JavaScript code?

I'm struggling to wrap my head around this, as my thoughts seem to have vanished. On my webpage, there's a button element with an id: for example <button id="someId"></button> Within the document.ready function, I've set up an ...

Pages with embedded HTML code

Within the confines of locale/lang.json, there resides { "title": "Title", "image": "service-corporate_thumb-v2.jpg", "alt": "alt", "imageFooter": "Some caption %", "imageFooterCTA": "author", "imageFooterURL": "https://example.com/author", } ...

Instructions for adjusting the size of my modal window when the keyboard appears?

While developing a next.js app, I encountered an issue with the chat modal. When the input field is in focus, I want to resize the modal height so that the keyboard popup does not hide the input field. I attempted to modify the DOM but could not get it to ...

Steps for adding a delete icon to a text input field and enabling the functionality to delete text

In the code snippet below, I am creating a text input field: <input type="text" class="signup-input text-value" name="" placeholder="e.g. <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2d48554c405d41486d">[email pro ...

Aligning a Material UI button to the far right of a row

I am struggling to align a React material-ui button to the right-most of the page and despite trying to use the justify="flex-end" attribute within the following code, it doesn't seem to be working: <Grid item justify="flex-end" ...

Selecting the incorrect label while hovering over a checkbox

I am using Bootstrap and encountering an issue with displaying checkboxes after clicking on an accordion element. While the first checkbox is displayed correctly, the checkboxes inside the accordion do not appear as expected. It is confusing to me why thi ...

Is there a way to make jQuery Validate display errors within the form elements rather than outside of them?

Given the jQuery Validate basic example provided in the link below, what method can be used to display error messages within form elements whenever feasible (excluding checkboxes)? http://docs.jquery.com/Plugins/validation#source ...

Maintain original image file name when downloading

I have successfully created a download link containing a base 64 encoded image. The only issue is that I need to retain the original file name, which is dynamic and cannot be hardcoded. downloadImage: function(){ var image_url = document.getEleme ...

In Vue, it is not accurate to measure overflow

I am working on creating an overflow effect with tagging that fades out at the beginning to provide a subtle hint to users that there is more content. Here is what it currently looks like: https://i.stack.imgur.com/fXGBR.png To achieve this, I added a fa ...

Is there a way to incorporate an MTN Momo or Orange Money payment system into your application if you are not a registered business entity?

Implementing an MTN Momo and Orange Money payment system through their respective APIs is crucial. In addition, I am seeking a dependable and effective method to seamlessly integrate these diverse APIs. During my attempt to incorporate the API via their ...

Node-modules CSS

In my React application, I am utilizing CSS modules. By configuring modules:true in my webpack.config.js, I can successfully apply styles from files within my src folder. However, when importing components from node-modules, the corresponding CSS is not be ...