Highlight the navigation transition in the menu

Is there a more updated tutorial available for creating an underline effect that slides from one link to another when hovered over and remains at the clicked link?

I have come across a tutorial on Underline transition in menu which seems to be based on the tutorial from Css-only Lavalamp-like Fancy Menu Effect.

However, I am facing some issues with the code provided in codepen

  1. I am having difficulty centering the underline under the link due to its absolute position. It requires trial and error to find the correct number to center it using the left element. I would prefer to center the underline using margin: 0 auto or text-align: center if possible.

  2. Since this is for a Wordpress navigation menu, I am wondering if you have any tips or suggestions.

HTML

<div class="width">
<nav class="ph-line-nav">
    <a href="#">News</a>
    <a href="#">Activities</a>
    <a href="#">Search</a>
    <a href="#">Time</a>
    <div class="effect"></div>
</nav>
</div>

CSS

.width {
  width: 700px;
  margin: 0 auto;
}
nav {
    margin-top:20px;
    font-size: 110%;
    display: table;
    background: #FFF;
    overflow: hidden;
    position: relative;
    width: 100%;
}
nav a {
    text-align:center;
    background: #FFF;
    display: block;
    float: left;
    padding: 2% 0;
    width: 25%;
    text-decoration: none;
    color: /*#555*/black;
    transition: .4s;
    color: /*#00ABE8*/ red;
}
/* ========================
    Lava-lamp-line:
   ======================== */
 .effect {
    position: absolute;
    left: 0;
    transition: 0.4s ease-in-out;
}
nav a:nth-child(1).active ~ .effect {
    left: 0%;
    /* the middle of the first <a> */
}
nav a:nth-child(2).active ~ .effect {
    left: 25%;
    /* the middle of the second <a> */
}
nav a:nth-child(3).active ~ .effect {
    left: 50%;
    /* the middle of the third <a> */
}
nav a:nth-child(4).active ~ .effect {
    left: 75%;
    /* the middle of the forth <a> */
}
.ph-line-nav .effect {
    width: /*55px*/ 25%;
    height: 2px;
    bottom: 5px;
    background: /*#00ABE8*/black;
    margin-left:/*-45px*/auto;
    margin-right:/*-45px*/auto;
}

JS

$(document).ready(function() {
    $('.ph-line-nav').on('click', 'a', function() {
        $('.ph-line-nav a').removeClass('active');
        $(this).addClass('active');
    });
});

If possible, I prefer to stick to CSS-only tutorials without relying on JavaScript. However, I can make exceptions if necessary. I may delete this question if it seems unnecessary...

Update: I found something similar to what I want here: example but it includes JavaScript. Should I still consider it?

Answer №1

I believe this information meets your requirements

HTML:

<div class="nav-wrap">
 <ul class="group" id="example-one">
    <li class="current_page_item"><a href="#">Home</a></li>
    <li><a href="#">Buy Tickets</a></li>
    <li><a href="#">Group Sales</a></li>
    <li><a href="#">Reviews</a></li>
    <li><a href="#">The Show</a></li>
    <li><a href="#">Videos</a></li>
    <li><a href="#">Photos</a></li>
    <li><a href="#">Magic Shop</a></li>
 </ul>
</div>

CSS:

    /* Example One */
#example-one { 
    margin: 0 auto; 
    list-style: none; 
    position: relative; 
    width: 960px; 
}
#example-one li { 
    display: inline-block;  
}
#example-one a { 
    color: #bbb; 
    font-size: 14px; 
    float: left;
    padding: 6px 10px 4px 10px;
    text-decoration: none;
    text-transform: uppercase;
}
#example-one a:hover { 
    color: black; 
}
#magic-line { 
    position: absolute;
    bottom: -2px; 
    left: 0; 
    width: 100px; 
    height: 2px; 
    background: #fe4902;
}
.current_page_item a { 
    color: black !important; 
}
.ie6 #example-one li, .ie7 #example-one li { 
    display: inline; 
}
.ie6 #magic-line {
    bottom: -3px;
}

Jquery:

$(function() {

    var $el, leftPos, newWidth,
        $mainNav = $("#example-one");

    $mainNav.append("<li id='magic-line'></li>");
    var $magicLine = $("#magic-line");

    $magicLine
        .width($(".current_page_item").width())
        .css("left", $(".current_page_item a").position().left)
        .data("origLeft", $magicLine.position().left)
        .data("origWidth", $magicLine.width());

    $("#example-one li a").hover(function() {
        $el = $(this);
        leftPos = $el.position().left;
        newWidth = $el.parent().width();
        $magicLine.stop().animate({
            left: leftPos,
            width: newWidth
        });
    }, function() {
        $magicLine.stop().animate({
            left: $magicLine.data("origLeft"),
            width: $magicLine.data("origWidth")
        });    
    });
});

JSFiddle

Answer №2

Utilizing some mathematical calculations is necessary when working with absolute positioned elements (such as divs with the effect class). If you're using a CSS pre-processor like Sass, this task becomes much easier. However, if you prefer to stick with plain CSS, manual adjustments for each "nth-child" are required. This can also be achieved effortlessly using JavaScript.

CSS METHOD

In your layout of 700px width, each anchor tag (nav a) within it occupies 25% width. Therefore, each anchor has a width of 175px (700 * 0.25). You also need an underline with a fixed width of 55px.

.ph-line-nav .effect {
    width: 55px;
    height: 2px;
    bottom: 5px;
    background: /*#00ABE8*/black;
}

If the active anchor is the first one, the underline should start 60px from the beginning.

(175 - 55) / 2 = 60

60px(space) + 55px(underline) + 60px(space)

nav a:nth-child(1).active ~ .effect {
    left: 60px;
}

For the second anchor, you would need to position it at 235px (175 + 60).

nav a:nth-child(2).active ~ .effect {
    left: 235px;
}

Following this formula, you can calculate the positioning for each nth child element.

left = (nth-child - 1) * 175 + 60

Hence,

nth-child(3) = (3 - 1) * 175 + 60 = 410

nth-child(4) = (4 - 1) * 175 + 60 = 585


UPDATE: It seems you are using jQuery. In that case;

JQUERY METHOD

var layoutWidth = 700,
    underlineWidth = 55,
    menuCount = 4,
    menuWidth = layoutWidth / menuCount, //175px
    leftSpace = (menuWidth - underlineWidth) / 2; //60px

$('.ph-line-nav .effect').css('width', underlineWidth);

for(var i = 1; i < menuCount + 1; i++) {
    var left = (i - 1) * menuWidth + leftSpace; 
    $('nav a:nth-child(' + i + ').active ~ .effect').css('left', left)
}

By adjusting the underlineWidth and/or menuCount variables, the positioning will be calculated dynamically.

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

Disable javascript when using an iPad

I'm working on a website with parallax scrolling that I don't want to function on iPads. Is there a way to prevent the parallax effect from happening when the site is accessed on an iPad? Any guidance on how to disable parallax scrolling based o ...

The enigmatic discrepancy in height across various browsers

I have encountered an issue with the layout of my HTML document. Both the BODY and HTML elements are set to a height of 100%. Within these elements, I have two child elements - one with a fixed height of 100px and the other set to height:100%. However, th ...

Experiencing an issue with referrer: The global symbol needs an explicit package name

my $refer = $ENV{HTTP_REFERER}; my $gk1 = substr($str1, -4); if ($gk1 = .swf) { my $antigk = "gk detected"; } else { my $antigk = $link; } I am encountering issues with this code after making some modifications. What could be causing the errors? I ...

"Implementing the Three.js OBJloader feature with the enhanced functionality of

I'm looking to create a simple 3D model viewer with rotation capabilities, but I've run into an issue. When I add OrbitControls to my code, the page just shows up as blank: controls = new THREE.OrbitControls( camera ); controls.addEventListener( ...

Steps for Integrating Kendo Mobile's "Tap to Load More" Feature in Knockout JS

I have a series of data on one page where I'm currently retrieving data from the past two days using linq. I would like to implement a button that, when clicked, will fetch data for the next 5 days. Below is the code snippet used to retrieve data for ...

What is the process for changing the border color of a Select Component?

Is there a way to change the border color of a select component in Material UI library without directly setting the property in inspect elements? I can see it working when I set the property that way, but how can this be achieved using class override? htt ...

Inquiry into the use of Jquery.ajax()

Hey there, I'm curious about using Jquery Ajax to retrieve a numeric value from a website. Any suggestions on where I should begin? Any advice would be greatly appreciated. Thanks in advance! Best regards, SWIFT ...

What is the best way to display a collection of square Views in a FlatList in a react native application?

How can you create a scrollable square grid with two columns of squares in a FlatList using react-native and ensure it is responsive to different screen sizes? Which CSS properties in react-native are necessary to achieve square shapes for each <Item/& ...

How can we delete a specific word from a string if it is found in an

Facing a seemingly simple problem that's proving tricky to solve. I have an array of product names and a sentence. The goal is to remove any product names from the sentence if they appear in it. const products = ["premium t-shirt", "t-shirt", "swea ...

What purpose do controller.$viewValue and controller.$modelValue serve in the Angular framework?

I'm confused about the connection between scope.ngModel and controller.$viewValue/controller.$modelValue/controller.$setViewValue(). I'm specifically unsure of the purpose of the latter three. Take a look at this jsfiddle: <input type="text" ...

You cannot convert a function to a string while utilizing axios get in nuxtServerInit

While attempting to connect my app to the backend using Udemy's Nuxt.js course, I encountered a GET http://localhost:3000/ 500 (Internal Server Error) on the client side with the following code: import Vuex from 'vuex'; import axios from &a ...

What could be the reason behind my image displaying correctly in the majority of browsers, yet not in Internet Explorer

The HAML code below is what I have: %header .grid %a{:name => "top"} .logo %a{:href => root_path} =image_tag("logo3.png") .tagline .clearfloat %p Fast Facts About Your Website, Your Competitors And Best ...

Content positioned beside an image with the help of Bootstrap 4 framework

How can I align text to the right of an image, like a table layout? I experimented with grid layout using <div class="span2"> and <div class="span10"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bo ...

Hear and register keypress in Angular service

I offer a dialog service Check it out below @Injectable() export class HomeDialogService { public constructor(private readonly dialogService: DialogService, private readonly userAgent: UserAgentService) {} @HostListener('document:keydown.escape ...

The CSS JSON code I have written is not having any impact on the appearance of my div

<!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="styles/common.css"> <script src="http://code.jquery.com/jquery-latest.min.js"></script> <script type='text/javascript'> ...

Start a new typescript project from scratch

Seeking assistance in setting up a blank TypeScript project with a package.json, TypeScript and HTML file. I am looking for something akin to the Stackblitz blank-typescript project. If anyone could provide me with a step-by-step guide on how to create su ...

Working with JavaScript Arrays within a JSON file data

I am currently learning React and attempting to display random images from the Picsum website using their API. The JSON file I receive contains various information, but I am specifically interested in extracting the image URLs. Although it appears that my ...

The UI Bootstrap date picker is malfunctioning on a custom page within ng-admin

I'm a beginner in angularjs and ng-admin. Currently, I am working on a project where I need to integrate a custom UI bootstrap date picker but I am facing an issue with the popup not appearing. Below is the code for my custom page: Here is my custom ...

The Heroku app seems to be malfunctioning (Issue with deployment?)

After deploying my application that utilizes JavaScript, Express, and Node.js on Heroku, I encountered an issue where the functionality of the app is not working at all when accessed through Heroku. Interestingly, everything works perfectly fine when teste ...

I'm confused about what I did wrong with Node.js. The server.js is up and running, but I'm unable to view the

I have made some progress so far and I am currently running this code on Putty. var http = require('http'); var fs = require('fs'); const PORT = 8080; http.createServer(function(request, response) { var url = request.url; switc ...