1

I am trying to get a horizontal bar to appear below a link when a user hovers over the link.

let galleryAnchor = document.querySelector('#gallery-anchor')
let galleryAnchorBar = document.querySelector('#gallery-anchor-bar')

console.log('galleryAnchorBar.style.left = ' + galleryAnchorBar.style.left)
console.log('galleryAnchorBar.style.top = ' + galleryAnchorBar.style.top)

galleryAnchorBar.style.left = galleryAnchor.style.left
galleryAnchorBar.style.top = parseInt(galleryAnchor.style.bottom, 10) + 2 + 'px'

console.log('galleryAnchorBar.style.left = ' + galleryAnchorBar.style.left)
console.log('galleryAnchorBar.style.top = ' + galleryAnchorBar.style.top)

galleryAnchor.addEventListener('mouseenter', () => {
    galleryAnchorBar.style.width = galleryAnchor.style.width
})

galleryAnchor.addEventListener('mouseleave', () => {
    galleryAnchorBar.style.width = 0
})
#gallery-anchor-bar {
    position: fixed;
    width: 0px;
    height: 2px;
    background: linear-gradient(to right, #FF9966, #FF6565);
    border-radius: 1px;
    transition: all 500ms;
}
<div id="nav-anchor-grid">
    <a id="gallery-anchor" href="gallery.html">Gallery</a>
    <a id="organizations-anchor" href="organizations.html">Organizations</a>
    <a id="about-anchor" href="about-me.html">About Me</a>
</div>
<div id="gallery-anchor-bar"></div>

With this code, nothing happens when I hover over the link. If instead I add left: 500px; (or any other value), top: 30px (or any other value) and set width: 500px (or any other value) to my CSS, the bar appears on page load. When I hover over the gallery link and then move the cursor elsewhere, it disappears. And when I hover over the link again, it expands to the width set in the CSS (not the width of the anchor as I have specified in the JavaScript). I cannot figure out what is happening. The console.log() statements only print the hardcoded string without the values I have specified. What surprises me most is that the bar expands to the width specified in the CSS when code for the eventListener on mouseenter runs, not the width of the anchor.

The snippet with the modified CSS:

let galleryAnchor = document.querySelector('#gallery-anchor')
let galleryAnchorBar = document.querySelector('#gallery-anchor-bar')

console.log('galleryAnchorBar.style.left = ' + galleryAnchorBar.style.left)
console.log('galleryAnchorBar.style.top = ' + galleryAnchorBar.style.top)

galleryAnchorBar.style.left = galleryAnchor.style.left
galleryAnchorBar.style.top = parseInt(galleryAnchor.style.bottom, 10) + 2 + 'px'

console.log('galleryAnchorBar.style.left = ' + galleryAnchorBar.style.left)
console.log('galleryAnchorBar.style.top = ' + galleryAnchorBar.style.top)

galleryAnchor.addEventListener('mouseenter', () => {
    galleryAnchorBar.style.width = galleryAnchor.style.width
})

galleryAnchor.addEventListener('mouseleave', () => {
    galleryAnchorBar.style.width = 0
})
#gallery-anchor-bar {
    position: fixed;
    left: 500px;
    top: 30px;
    width: 500px;
    height: 2px;
    background: linear-gradient(to right, #FF9966, #FF6565);
    border-radius: 1px;
    transition: all 500ms;
}
<div id="nav-anchor-grid">
    <a id="gallery-anchor" href="gallery.html">Gallery</a>
    <a id="organizations-anchor" href="organizations.html">Organizations</a>
    <a id="about-anchor" href="about-me.html">About Me</a>
</div>
<div id="gallery-anchor-bar"></div>
Huzaifa
  • 482
  • 1
  • 7
  • 20
  • 3
    Why are you using JavaScript to do something CSS can do with a simple `:hover` selector? – Heretic Monkey Nov 03 '20 at 17:52
  • 1
    Try using the `::after` pseudo element instead of a separate div. Basically, on hover, transition the width of `::after`. Try this: https://stackoverflow.com/questions/26726436/css-bottom-border-transition-expand-from-middle – Gabriel Lupu Nov 03 '20 at 17:53
  • #nav-anchor-grid a:hover - apply css on hover – Sarun UK Nov 03 '20 at 17:58
  • @GabrielLupu Thanks. I followed your advice and using `::after` with `:hover` was a simpler solution than what I was trying. – Huzaifa Nov 04 '20 at 17:05

3 Answers3

2

Progressive underline of the link - Only CSS solution

You can change the line thickness by setting the value to bottom: -2px; on class .link::after

.link {
    display: inline-block;
    position: relative;
    text-decoration: none;
}

.link::after {
    position: absolute;
    content: '';
    top: 100%;
    right: 0px;
    bottom: -2px;
    left: 0px;
    width: 0%;
    background: linear-gradient(to right, #FF9966, #FF6565);
    transition: width 1s;   
}

.link:hover::after {
    content: '';
    width: 100%;
}
<div>
    <a class="link" href="gallery.html">Gallery</a>
    <a class="link" href="organizations.html">Organizations</a>
    <a class="link" href="about-me.html">About Me</a>
</div>
54ka
  • 3,501
  • 2
  • 9
  • 24
  • 1
    Thanks. Your solution is correct (although I didn't follow it), except that you should add `border-radius: 1px;` to the `::after` pseudo-element. – Huzaifa Nov 04 '20 at 17:15
1

Simple underline without add an other <div>:

a{
  text-decoration: none;
}

a:hover{
  /*text-decoration: underline; deafult behaviour*/
  border-bottom: 2px solid red; /*with your style*/
}
<div id="nav-anchor-grid">
    <a id="gallery-anchor" href="gallery.html">Gallery</a>
    <a id="organizations-anchor" href="organizations.html">Organizations</a>
    <a id="about-anchor" href="about-me.html">About Me</a>
</div>

Or solution all in html part

<div id="nav-anchor-grid">
    <a id="gallery-anchor" href="gallery.html"
    style="text-decoration:none" onmouseover="style='text-decoration:underline'" onmouseout="style='text-decoration:none'"
    >Gallery</a>
    <a id="organizations-anchor" href="organizations.html"
    style="text-decoration:none" onmouseover="style='text-decoration:underline'" onmouseout="style='text-decoration:none'">Organizations</a>
    <a id="about-anchor" href="about-me.html"
    style="text-decoration:none" onmouseover="style='text-decoration:underline'" onmouseout="style='text-decoration:none'">About Me</a>
</div>
zerbene
  • 1,249
  • 2
  • 7
  • 21
0

#nav-anchor-grid a:hover {   
    border-bottom: 2px solid red;
}
<div id="nav-anchor-grid">
    <a id="gallery-anchor" href="gallery.html">Gallery</a>
    <a id="organizations-anchor" href="organizations.html">Organizations</a>
    <a id="about-anchor" href="about-me.html">About Me</a>
</div>
<div id="gallery-anchor-bar"></div>
Sarun UK
  • 6,210
  • 7
  • 23
  • 48