简体   繁体   中英

Underline transition in Nav Menu

I don't know if this is a dumb question or not. I was just wondering if there's any better or updated tutorials out there for the underline to slide from one link to another when hovered over and stay at a clicked link.

So far I found this nice tutorial from Underline transition in menu which looks like it use the tutorial from Css-only Lavalamp-like Fancy Menu Effect .

Still I do have some problems with that code in codepen

  1. Since I was able to specific the width of the underline, I wasn't able to center the underline under the link since the position is absolute. I could center it by using the left element but it requires trials and errors before finding the right number. So I would like to center the underline if possible with margin: 0 auto or text-align: center.

  2. I can't think of anything else but it's for wordpress nav menu so I wonder if you have any tips.

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;
  /*border-right: 1px solid red;
  border-left: 1px solid 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');
    });
});

I don't really care for javascript unless it's absolute necessary, so in a sense, I would like to use css-only tutorial if possible. Anyway, I will delete this question soon if it turns out to be a stupid question...

Update: This is kinda what I was looking for: example however, it has javascript....but I guess it doesn't matter after all?

I think this is what you need

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

You just need some math there since you're using absolute positioned element(effect classed div). If you use any of CSS pre-processors (I prefer Sass) it would easily done. But if you want to use plain CSS, you should do it manually to each "nth-child" like this. (You could also do this with javascript easily)

CSS WAY

You have layout with 700px width. And each anchor (nav a) tags inside of it has 25% width. So your anchors has 175px width. (700 * 0.25) And you need that underline with fixed width which is 55px.

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

If your active anchor is first, your underline needs to be 60px from beginning.

(175 - 55) / 2 = 60

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

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

And second one you must use 175 + 60 = 235px.

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

You got the formula, right?

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

So,

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

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


UPDATE: I saw you use jquery. Then;

JQUERY WAY

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)
}

When you change underlineWidth and/or menuCount variables, they will be programatically calculated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM