How can I apply an underline effect when hovering over navigation links in a responsive menu?

I've successfully added an underline effect on hover for the navigation menu. However, I encountered an issue with the responsiveness of the menu. When viewed on screens smaller than 600px, the underline effect covers the entire width of the block instead of just the navigation link, unlike how it behaves on larger screens.

Here's the website, or you can check out the code snippet below.

Any assistance would be greatly appreciated.

function myFunction() {
  var x = document.getElementById("myNavbar");
  if (x.className === "navbar") {
    x.className += " responsive";
  } else {
    x.className = "navbar";
  }
}
@font-face {
  font-family: "Lyon";
  src: url("http://staging1.oakpark.co/wp-content/uploads/2019/07/Lyon-Text-Regular.otf");
  src: url("http://staging1.oakpark.co/wp-content/uploads/2019/07/Lyon-Text-Regular.otf") format("woff"), url("http://staging1.oakpark.co/wp-content/uploads/2019/07/Lyon-Text-Regular.otf") format("opentype"), url("http://staging1.oakpark.co/wp-content/uploads/2019/07/Lyon-Text-Regular.otf") format("svg");
}

body {
  padding: 0;
  margin: 0;
  background: white;
}

* {
  box-sizing: border-box;
}

h1 {
  font-family: 'Lyon';
  font-size: 24px;
  max-width: 800px;
  text-align: center;
  margin: auto;
  padding-top: 16px;
  padding-left: 16px;
  padding-right: 16px;
}

.navbar {
  z-index: 1;
  font-family: 'Lyon';
  background-color: white;
  position: fixed;
  bottom: 0;
  width: 100%;
  border-top: .05rem solid;
  display: flex;
  justify-content: space-between;
  padding: 14px 16px;
}

.navbar a {
  color: black;
  font-family: 'Lyon';
  font-size: 24px;
  text-align: center;
  text-decoration: none;
  position: relative;
}

.navbar a:hover {
  color: black;
  font-family: 'Lyon';
  text-decoration: none;
}

.navbar a:before {
  content: "";
  position: absolute;
  width: 100%;
  height: 2px;
  bottom: 0;
  left: 0;
  background-color: #000;
  visibility: hidden;
  -webkit-transform: scaleX(0);
  transform: scaleX(0);
  -webkit-transition: all 0.3s ease-in-out 0s;
  transition: all 0.3s ease-in-out 0s;
}

.navbar a:hover:before {
  visibility: visible;
  -webkit-transform: scaleX(1);
  transform: scaleX(1);
}

.navbar a.active {
  background-color: white;
  color: black;
  font-style: none;
  font-family: 'Lyon';
}

.navbar .icon {
  display: none;
}

@media screen and (max-width: 600px) {
  .navbar a {
    display: none;
    padding-top: 6px;
  }
  .navbar a.icon {
    float: right;
    display: block;
  }
  .navbar.responsive .icon {
    position: absolute;
    left: 10px;
    top: 8px;
  }
  .navbar.responsive a {
    float;
    none;
    display: block;
    text-align: center;
  }
  .navbar.responsive {
    display: block;
  }
  .navbar.responsive a:before {
    content: "";
    position: absolute;
    width: 100%;
    height: 2px;
    bottom: 0;
    left: 0;
    background-color: #000;
    visibility: hidden;
    -webkit-transform: scaleX(0);
    transform: scaleX(0);
    -webkit-transition: all 0.3s ease-in-out 0s;
    transition: all 0.3s ease-in-out 0s;
  }
  .navbar.responsive a:hover:before {
    visibility: visible;
    -webkit-transform: scaleX(1);
    transform: scaleX(1);
  }
}

p {
  margin: 10px 0;
}
<div class="navbar" id="myNavbar">
  <a href="#about" class="active">About</a>
  <a href="#lindsay">Lindsay</a>
  <a href="#contact">Branding</a>
  <a href="#contact">Photography</a>
  <a href="#contact">Instagram</a>
  <a href="javascript:void(0);" style="font-size:18px;" class="icon" onclick="myFunction()">i</a>
</div>

Answer №1

I've reviewed your CSS, and I noticed that the issue lies with the a tag having the property of display:block, which expands the tag itself rather than the text within it. To maintain space when the display is smaller, consider wrapping each a tag in a list item or a div and applying the property of display:block.

Here's an example illustrating what I advised:

function myFunction() {
  var x = document.getElementById("myNavbar");
  if (x.className === "navbar") {
    x.className += " responsive";
  } else {
    x.className = "navbar";
  }
}
@font-face {
  font-family: "Lyon";
  src: url("http://staging1.oakpark.co/wp-content/uploads/2019/07/Lyon-Text-Regular.otf");
  src: url("http://staging1.oakpark.co/wp-content/uploads/2019/07/Lyon-Text-Regular.otf") format("woff"), url("http://staging1.oakpark.co/wp-content/uploads/2019/07/Lyon-Text-Regular.otf") format("opentype"), url("http://staging1.oakpark.co/wp-content/uploads/2019/07/Lyon-Text-Regular.otf") format("svg");
}

body {
  padding: 0;
  margin: 0;
  background: white;
}

* {
  box-sizing: border-box;
}

h1 {
  font-family: 'Lyon';
  font-size: 24px;
  max-width: 800px;
  text-align: center;
  margin: auto;
  padding-top: 16px;
  padding-left: 16px;
  padding-right: 16px;
}
.navbar {
  z-index: 1;
  font-family: 'Lyon';
  background-color: white;
  position: fixed;
  bottom: 0;
  width: 100%;
  border-top: .05rem solid;
  display: flex;
  justify-content: space-between;
  padding: 14px 16px;
margin: 0;
}

.navbar a {
  color: black;
  font-family: 'Lyon';
  font-size: 24px;
  text-align: center;
  text-decoration: none;
  position: relative;
}

.navbar a:hover {
  color: black;
  font-family: 'Lyon';
  text-decoration: none;
}
.navbar li{
list-style:none;
}

.navbar a:before {
  content: "";
  position: absolute;
  width: 100%;
  height: 2px;
  bottom: 0;
  left: 0;
  background-color: #000;
  visibility: hidden;
  -webkit-transform: scaleX(0);
  transform: scaleX(0);
  -webkit-transition: all 0.3s ease-in-out 0s;
  transition: all 0.3s ease-in-out 0s;
}

.navbar a:hover:before {
  visibility: visible;
  -webkit-transform: scaleX(1);
  transform: scaleX(1);
}

.navbar a.active {
  background-color: white;
  color: black;
  font-style: none;
  font-family: 'Lyon';
}

.navbar .icon {
  display: none;
}

@media screen and (max-width: 600px) {
  .navbar a{
    display: none;
    padding-top: 6px;
  }
  .navbar .icon {
    float: right;
    display: block;
  }
  .navbar.responsive .icon {
    position: absolute;
 left: 10px;
    top: 8px;
  }
  .navbar.responsive li a {
    float;
    none;
    display: inline;
    text-align: center;
margin: 4px;
  }
.navbar.responsive li {
    float;
    none;
    text-align: center;
margin: 6px 00px;
  }
  .navbar.responsive {
   align-content: center;
flex-flow:column;
  }
  .navbar.responsive li a:before {
    content: "";
    position: absolute;
    width: 100%;
    height: 2px;
    bottom: 0;
    left: 0;
    background-color: #000;
    visibility: hidden;
    -webkit-transform: scaleX(0);
    transform: scaleX(0);
    -webkit-transition: all 0.3s ease-in-out 0s;
    transition: all 0.3s ease-in-out 0s;
  }
  .navbar.responsive li a:hover:before {
    visibility: visible;
    -webkit-transform: scaleX(1);
    transform: scaleX(1);
  }
}
<ul class="navbar" id="myNavbar">
<a href="javascript:void(0);" style="font-size:18px;" class="icon" onclick="myFunction()">i</a>
<li><a href="#about" class="active">About</a></li>
<li><a href="#lindsay">Lindsay</a></li>
<li><a href="#contact">Branding</a></li>
<li><a href="#contact">Photography</a></li>
<li><a href="#contact">Instagram</a></li>
</ul>

Answer №2

Anticipating something like this?

Quick Fix

I've just implemented nth-child and added scaling for each link.

function myFunction() {
  var x = document.getElementById("myNavbar");
  if (x.className === "navbar") {
    x.className += " responsive";
  } else {
    x.className = "navbar";
  }
}
@font-face {
  font-family: "Lyon";
  src: url("http://staging1.oakpark.co/wp-content/uploads/2019/07/Lyon-Text-Regular.otf");
  src: url("http://staging1.oakpark.co/wp-content/uploads/2019/07/Lyon-Text-Regular.otf") format("woff"), url("http://staging1.oakpark.co/wp-content/uploads/2019/07/Lyon-Text-Regular.otf") format("opentype"), url("http://staging1.oakpark.co/wp-content/uploads/2019/07/Lyon-Text-Regular.otf") format("svg");
}

body {
  padding: 0;
  margin: 0;
  background: white;
}

* {
  box-sizing: border-box;
}

h1 {
  font-family: 'Lyon';
  font-size: 24px;
  max-width: 800px;
  text-align: center;
  margin: auto;
  padding-top: 16px;
  padding-left: 16px;
  padding-right: 16px;
}

.navbar {
  z-index: 1;
  font-family: 'Lyon';
  background-color: white;
  position: fixed;
  bottom: 0;
  width: 100%;
  border-top: .05rem solid;
  display: flex;
  justify-content: space-between;
  padding: 14px 16px;
}

.navbar a {
  color: black;
  font-family: 'Lyon';
  font-size: 24px;
  text-align: center;
  text-decoration: none;
  position: relative;
}

.navbar a:hover {
  color: black;
  font-family: 'Lyon';
  text-decoration: none;
}

.navbar a:before {
  content: "";
  position: absolute;
  width: 100%;
  height: 2px;
  bottom: 0;
  left: 0;
  background-color: #000;
  visibility: hidden;
  -webkit-transform: scaleX(0);
  transform: scaleX(0);
  -webkit-transition: all 0.3s ease-in-out 0s;
  transition: all 0.3s ease-in-out 0s;
}

.navbar a:hover:before {
  visibility: visible;
  -webkit-transform: scaleX(1);
  transform: scaleX(1);
}

.navbar a.active {
  background-color: white;
  color: black;
  font-style: none;
  font-family: 'Lyon';
}

.navbar .icon {
  display: none;
}

@media screen and (max-width: 600px) {
  .navbar a {
    display: none;
    padding-top: 6px;
  }
  .navbar a.icon {
    float: right;
    display: block;
  }
  .navbar.responsive .icon {
    position: absolute;
    left: 10px;
    top: 8px;
  }
  .navbar.responsive a {
    float:none;
    display: block;
    text-align: center;
  }
  .navbar.responsive {
    display: block;
  }
  .navbar.responsive a:before {
    content: "";
    position: absolute;
    height: 2px;
    width:100%;

    bottom: 0;
    left: 0;
    background-color: #000;
    visibility: hidden;
    -webkit-transform: scaleX(0);
    transform: scaleX(0);
    -webkit-transition: all 0.3s ease-in-out 0s;
    transition: all 0.3s ease-in-out 0s;
  }
  .navbar.responsive a:hover:nth-child(1):before {
    visibility: visible;
    -webkit-transform: scaleX(.18);
    transform: scaleX(.18);
  }
  .navbar.responsive a:hover:nth-child(2):before {
    visibility: visible;
    -webkit-transform: scaleX(.22);
    transform: scaleX(.22);
  }
  .navbar.responsive a:hover:nth-child(3):before {
    visibility: visible;
    -webkit-transform: scaleX(.25);
    transform: scaleX(.25);
  }
  .navbar.responsive a:hover:nth-child(4):before {
    visibility: visible;
    -webkit-transform: scaleX(.33);
    transform: scaleX(.33);
  }
  .navbar.responsive a:hover:nth-child(5):before {
    visibility: visible;
    -webkit-transform: scaleX(.26);
    transform: scaleX(.26);
  }
}

p {
  margin: 10px 0;
}
<div class="navbar" id="myNavbar">
  <a href="#about" class="active">About</a>
  <a href="#lindsay">Lindsay</a>
  <a href="#contact">Branding</a>
  <a href="#contact">Photography</a>
  <a href="#contact">Instagram</a>
  <a href="javascript:void(0);" style="font-size:18px;" class="icon" onclick="myFunction()">i</a>
</div>


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

Discovering ways to showcase JSON response in JavaScript or PHP

Currently, I am integrating the Coin Warz API into my website. The API sends responses in JSON format. I have attempted to display this data in a table format using PHP, but unfortunately, I am encountering difficulties. The JSON Response is as follows: [ ...

Modify how the browser typically processes script tags as its default behavior

Most of us are familiar with the functionality of <script src="/something.js"></script>. This loads the specified file onto the page and executes the script contained within. Is there a way to modify how <script> elements are interpreted ...

Step-by-step guide for properly transferring PHP MySQL data to ChartJs

I am looking to create bar charts and pie charts using ChartJs, with data fetched from php and mysql. Specifically, I want to generate a bar chart that illustrates the statistics of male and female students, along with the total number of students. The des ...

Stop the repetition of event handlers by utilizing the .off() method to remove duplicates

Here's a scenario where I've assigned two event handlers: $('#myElement').on('click', '.classA', doSomething); $('#myElement').on('click', '.classB', doSomethingElse); Now, the task at ...

Best practices for executing an asynchronous forEachOf function within a waterfall function

I've been working with the async library in express js and I'm encountering an issue when using two of the methods alongside callbacks. The variable result3 prints perfectly at the end of the waterfall within its scope. However, when attempting t ...

Disabling the child element from triggering the parent element's onclick function, while still allowing it to respond to its own content

My list elements have onclick-functions that change the display of each element and its child div, moving them to the top of the list. Clicking again reverses this effect. The issue arises because the child div contains search fields, clickable pictures, ...

Having trouble resolving the dependency tree within react-navigation-stack

Trying to understand navigation in React-native and attempting to execute the following code: import React, {Component} from 'react'; import {StyleSheet, Text, View} from 'react-native'; import {createAppContainer} from 'react-nav ...

Tips for implementing a search filter in a select dropdown menu using Angular

I am attempting to enhance my select option list by including a search filter. With numerous options available, I believe that having a search function will make it easier for the user to locate their desired selection. I hope my message is clear despite ...

Endless [React Native] onFlatList onEndReached callback invoked

Attempting to create my debut app using ReactNative with Expo, I've hit a snag with FlatList. The components are making infinite calls even when I'm not at the end of the view. Another issue might be related; across multiple screens, the infinite ...

Filtering in JavaScript can be efficiently done by checking for multiple values and only including them if they are not

In my current coding challenge, I am attempting to create a filter that considers multiple values and only acts on them if they are not empty. Take the following example: jobsTracked = [ { "company": "Company1", ...

The count of records in MongoDB by the current month

Recently delving into MongoDB, I found myself in need of a way to retrieve the count of posts made in the current month. Keeping timestamps true in my PlateModel model, it appears as follows: { timestamps: true } The current code snippet in my Controller ...

Unexpected activation of Internet Explorer media queries causing display issues

Check out my CSS code below: @media all and (max-width: 500px){ .calendar_head{ height: 120px; line-height: 60px; } } .calendar_head{ width: 100%; font-weight: 700; color: #6a7783; text-align: center; line-heigh ...

Optimizing Nginx for caching server-side rendered (SSR) web pages developed using React and Next.js

After creating an application where some pages are rendered on the server side, I noticed that something wasn't right. When viewing the requested pages in my browser, everything seemed normal. However, when I sent a CURL request to the page and saved ...

Unexpected behavior observed when trying to smoothly scroll to internal links within a div, indicating a potential problem related to CSS dimensions and

Within a series of nested div containers, I have one with the CSS property overflow:hidden. My goal is to smoothly scroll to internal links within this specific div using jQuery. The snippet of code below has worked successfully in previous projects: ...

Retrieve a photo from a website address and determine its dimensions

When grabbing an image from a URL using this function: const fetch = require("node-fetch"); function getImageFromUrl(url) { return fetch(url).then((response) => response.blob()); } To determine the dimensions of the images, I am utilizing ...

How can we apply a hover effect to combine two rows in a table as one using CSS?

I'm having trouble figuring out how to highlight every two rows in a table as one when hovering over the current row. For example, if I hover on row 2, rows 2 and 3 should be highlighted. Then when I move to row 4, rows 4 and 5 should be highlighted, ...

How to implement scrollIntoView in Vue 3 with script setup

Having some trouble with scrolling to a specific element when clicked. I keep getting this error message. Uncaught TypeError: element.scrollIntoView is not a function Here is my script <script setup> import { ref } from 'vue' function goT ...

Ways to Execute the Constructor or ngOnInit Multiple Times

Here's the scenario I'm facing: I have developed an app with multiple screens. One of these screens displays a list of articles. When a user clicks on an article, they are directed to another screen that shows the details of that specific item. ...

The color of the top bar remains unchanged when hovered over

I am struggling to design my personal website, and I can't seem to get the top bar to change color on hover. If you believe you have a solution, please provide your answer. index.html appears to be functioning properly, but perhaps additional adjustm ...

What is the best way to comprehend IE comments in a given condition?

I recently came across some conditional comments in a theme I'm working on that dynamically add classes to the html tag depending on the version of Internet Explorer being used. <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" ...