How can I make this navigation?

Hi,

I’m trying to create a nav bar where you get a triangle when you hover over a menu item. You can see what I have so far on Codepen.
However, I’m struggling to display the hover triangles. For the two first menu items, it works great:

Due to the diagonal shape however, the further nav items look like this when being hovered on:

I’ve already tried to overwrite the css and change the ‘top’ value of the triangle (it’s positioned absolute relative to the li) for every menu item and it works good on first site. However, when making the browser smaller the diagonal gets steeper and the whitespace above the triangle is back.

I guess I could fix it with jQuery (calculating the space between the nav bar and the triangle) but it feels like I’m overthinking this.

Would love to hear your suggestions :slight_smile:

Hi there Thibault,

here is an example for you to play with…

<!DOCTYPE html>
<html lang="en">
<head>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">

<title>untitled document</title>

<link rel="stylesheet" href="screen.css" media="screen">

<style media="screen">
body {
    margin: 0;
 }
#container {
    overflow: hidden;
 }
#inner {
    position: relative; 
    left: -99%;
    top: 50%;
    width: 200%;
    height: 8em;
    margin-bottom: 1em;
    background: #102e2f;
    transform: rotate(-1deg) ;
 }
ul {
    line-height: 8em;
    padding: 0 1em;
    margin: 0;
    list-style: none; 
    transform: rotate(1deg) 
 }
ul li {
    position: relative;
    float: right;
    margin: 0 0.5em; 
 }
#logo {
    float: left;
    margin-left: 52%;
 }
#logo::after {
    border: none;
 }
a {
    display: block;
    font-size:1.2em;
    color: #fff;  
    text-decoration: none;
 }
ul li:hover::after{
    position: absolute;
    width: 0;
    height: 0;
    left: 0.4em;
    border-left: 1em solid transparent;
    border-right: 1em solid transparent;
    border-top: 1em solid #103e2f;
    content: '';
    transform: rotate(-1deg);
 }

ul li:nth-child(2)::after {bottom: 0.44em;}
ul li:nth-child(3)::after {bottom: 0.37em;}
ul li:nth-child(4)::after {bottom: 0.31em;}
ul li:nth-child(5)::after {bottom: 0.25em;}

@media screen and (max-width:64em) {
ul li:nth-child(2)::after {bottom: 0.06em;}
ul li:nth-child(3)::after {bottom: 0;}
ul li:nth-child(4)::after {bottom: -0.06em;}
ul li:nth-child(5)::after {bottom: -0.12em;}
 }

@media screen and (max-width:50em) {
ul li:nth-child(2)::after {bottom: -0.19em;}
ul li:nth-child(3)::after {bottom: -0.25em;}
ul li:nth-child(4)::after {bottom: -0.31em;}
ul li:nth-child(5)::after {bottom: -0.37em;}
 }

@media screen and (max-width:40em) {
ul li:nth-child(2)::after {bottom: -0.37em;}
ul li:nth-child(3)::after {bottom: -0.44em;}
ul li:nth-child(4)::after {bottom: -0.5em;}
ul li:nth-child(5)::after {bottom: -0.56em;}
 }

@media screen and (max-width:30em) {
ul li:nth-child(2)::after {bottom: -0.52em;}
ul li:nth-child(3)::after {bottom: -0.62em;}
ul li:nth-child(4)::after {bottom: -0.69em;}
ul li:nth-child(5)::after {bottom: -0.75em;}
 }
@media screen and (max-width:28em) {
#inner {
    position: static;
    width: auto;
    height: auto;
    padding: 0.25em;
    transform: rotate(0deg) ;
 }
ul {
    line-height: 1.5em;
    padding: 0;
    transform: rotate(0deg) 
 }
ul li, #logo {
    float: none;
    margin:0 0 0.25em; 
 }
ul li:hover::after {border: none;}
ul a {
    line-height: 2em;
    text-indent: 1em;
 }
ul a:hover {
    background:  #224f4f;
 }
}
</style>
</head>
<body> 
<div id="container">
<div id="inner">
 <ul>
  <li id="logo"><a href="#">Demo Company</a></li>
   <li><a href="#">Item</a></li>
   <li><a href="#">Item</a></li>
   <li><a href="#">Item</a></li>
   <li><a href="#">Item</a></li>
 </ul>
</div>
</div>
</body>
</html>

coothead

2 Likes

The diagonal may be steeper, but that is long after it has triggered a scroll bar because the menu is a fixed 1000px.

To your existing code, you can add the following to the bottom of the CSS, however, it will not be any more resonsive than the code you have posted.

ul li:nth-child(5):hover:after {
    top: 78px;
}
ul li:nth-child(4):hover:after {
    top: 76px;
}
ul li:nth-child(3):hover:after {
    top: 74px;
}
ul li:nth-child(2):hover:after {
    top: 72px;
}

With regards to nav bar pointers reminds me of the following thread:

Thanks a lot for the code, @coothead, it’ll definitely come in handy!

The Codepen version is actually a simplified version of my navigation, so you’re right that this version isn’t responsive. Changing the top value for every triangle is something I already tried, but I was hoping that I could avoid this.

Guess I’ll just have to write media queries that change the top value for every triangle. Doesn’t really feel like high quality coding though.

Thanks a lot for your effort, guys! Really appreciate it :slight_smile:

1 Like

You could do it automatically if you didn’t mind the text being stepped:)

Of course that just moves the problem elsewhere.

That’s really nifty done! Shame about the steps indeed. I fixed it with a lot of media queries now… I always feel ‘dirty’ when writing this kind of code lol. Feels like I just cheated and I have that guilty dog look on my face.

https://m.popkey.co/f6d204/LWYby_s-200x150.gif

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.