I'm looking for a more efficient CSS solution to apply my :before & :after to all menu links collectively, rather than having to add them individually to each one

I have created a CodePen with a working hover effect using :before & :after on li link options. However, I am looking for a more efficient way to globally apply the position of these pseudo-elements without adding separate styles for each link option. Currently, the positioning is defined using absolute values for top and left, but I want the :before & :after to be in consistent positions relative to each li.

This is what I have so far:

.myLi-1:hover:after {
  top: 66px;
  left: 284px;
  position: absolute;
}

.myLi-1:hover:before {
  top: -2px;
  left: 284px;
  position: absolute;
}

/* Repeated for List Item 2, 3, 4, 5 ... */

You can view the live version on CodePen for better understanding of the issue:

https://codepen.io/dayley-senior/pen/BaWKqPw

Answer №1

Execute the following steps:

Include position: relative; to the li element

        .nav {
            width: 50%;
            background: #f03c9f;
            padding: 10px 0px 10px 10px;
        }

        li {
            list-style-type: none;
            font-family: helvetica;
            color: white;
            padding: 15px 25px 15px 25px;
            position: relative;
        }

        li a {
            padding: 15px 25px 15px 25px;
        }

        li:hover {
            border-radius: 10px 0px 0px 10px;
            background-color: #f2f2f2;
            color: black;
        }

        /* List Item 1 */
        .nav li:hover:after {
            top: 48px;
            left: 272px;
            position: absolute;
            border-top-right-radius: 10px;
            box-shadow: 0 -10px 0 0 #f2f2f2;
        }

        .nav li:hover:before {
            top: -20px;
            left: 272px;
            position: absolute;
            border-bottom-right-radius: 10px;
            box-shadow: 0 10px 0 0 #f2f2f2;
        }
        .nav li:before,
        .nav li:after {
            content: "";
            position: relative;
            height: 20px;
            width: 20px;
        }
<div class="nav">
    <li class="myLi-1"><a><span class="mySpan">Option 1</span></a></li>
    <li class="myLi-2"><a><span class="mySpan">Option 2</span></a></li>
    <li class="myLi-3"><a><span class="mySpan">Option 3</span></a></li>
    <li class="myLi-4"><a><span class="mySpan">Option 4</span></a></li>
    <li class="myLi-5"><a><span class="mySpan">Option 5</span></a></li>
</div>

Answer №2

The issue arises when dealing with absolutely positioned elements, as they are always relative to the next nearest element with a relative position - in this case, the ul and not the li. To resolve this problem, follow these steps:

  1. Apply a position: relative; to the li element.
  2. You can then add the before and after styles directly to the li (as they will behave similarly without the need for extra classes).

Your CSS should resemble something like this:

li:hover {
  border-radius: 10px 0px 0px 10px;
  background-color: #f2f2f2;
  color: black;
  position: relative;
}
li:hover:after, li:hover:before{
  left: 284px;
}
li:hover:after {
  bottom: -2px;
  position: absolute;
  border-top-right-radius: 10px;
  box-shadow: 0 -10px 0 0 #f2f2f2;
}
li:hover:before {
  top: -2px;
  position: absolute;
  border-bottom-right-radius: 10px;
  box-shadow: 0 10px 0 0 #f2f2f2;
}

It is advisable to double-check the bottom positioning for the after element, as it may require a different value.

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

Exploring the functionality of setAttribute method in JavaScript

Snippet: activeCell.onclick = function() { console.log(element); element.value = this.value; console.log(element.value); console.log(element); }; Imagine activeCell as a span with value = "678", while element is represented by a simple in ...

Converting JSON data into a JavaScript array and retrieving the array through an AJAX request from PHP

Currently, I am working on a project where I have created a function named AjaxRequest to manage all my AJAX requests. While making the requests is not an issue, receiving and placing the data back onto the page has proven to be quite challenging. Within ...

The React page loads before verifying the clients' permissions

In my application, I am using a Javascript query to fetch the data of the current user. This data is then used to verify the user's access permissions for different pages in my React app with the help of Apollo Client and GraphQL. Unfortunately, ther ...

Error thrown by custom draggable directive in AngularJS due to range issue

I am having trouble with a custom draggable directive in AngularJS. I keep getting a RangeError. Can someone please help me diagnose the issue in this code? (function (window, angular, undefined) { var app = angular.module('ngDraggableModule&a ...

Meshes that overlap with transparency features

Could anyone help me with this issue I'm facing? I have a scenario where I am rendering multiple meshes in Three.JS with different solid colors and transparency. However, these meshes are overlapping and the colors are blending together in the overlap ...

The function replace does not exist in t(…)trim

I encountered an error in my code that breaks the functionality when checked using console.log. var map = L.map('map').setView([0, 0], 2); <?php $classesForCountries = []; if (have_posts()) : while (have_posts()) : the_post(); ...

What could be causing my 3D Model to fail to load in three.js when using the glTF loader?

I'm trying to load a 3D object into my three.js project for the first time. I have the object downloaded on my computer and have connected the three.js library and the glTF loader to my HTML document. However, every time I run the code, I encounter th ...

Occupying both horizontal and vertical space in a Bootstrap column

I have set up my buttons like this: https://i.stack.imgur.com/OMfhp.png In the image, you can see that the Left Option Button is larger, and I want all buttons to be like that. They are supposed to be aligned next to each other as I am using the Bootstra ...

Accessing an object's property within a mapped array in a Next.js application is possible

Currently, I am attempting to iterate through an array of objects and extract the link property as a <li></li> element. However, I am facing an issue where nothing is being returned: import { useState, useEffect } from "react"; import ...

Ways to alter the color of individual pseudo elements using a CSS loop

While working on creating a typewriter animation effect for my website using only CSS that I discovered through some online research, a question popped into my mind - is it possible to set different colors for each text in the animation? I have included t ...

Determining the completion of multiple asynchronous calls in AngularJS: A guide

I have a SQLService running on my PhoneGap/AngularJS app that processes a long array of Guidelines with DB transactions. How can I indicate when the final transaction is completed? I envision a flow like this: In the controller, call `SQLService.ParseJS ...

What is the most efficient way to use a for loop with JavaScript querySelectorAll to move multiple images?

I'm trying to move multiple images by defining each one with a for loop. Below is the code I have: var elem = document.querySelectorAll(".yikama"); var el; for (i = 0; i < elem.length; i++) { var el = elem[i] el.addEventListener(& ...

Using the HTML form element to achieve two-way binding on array elements

I am working with an array of objects within a component that will be iterated in the template. app.component.ts import {Component, OnInit} from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.compone ...

Error: Unable to extract the 'id' property from 'this.props.Name' because it is undefined in ReactJS

Can you please assist me in resolving this issue? Error: Cannot destructure property 'id' of 'this.props.Name' as it is undefined. src/component/Detail.js file import React, { Component } from 'react'; import { Character } f ...

Is it possible for two node scripts running on the same machine to interfere with each other's execution

In the scenario where a parent node file (such as an express server) spawns child nodes that execute computationally intense tasks, will these children cause blocking for the parent process? ...

Utilizing an Image as a Link in the Background

I am working on a way to convert the CSS background image I have into a clickable link that can be referenced. Here is my CSS code: #wrapper { height: 100%; padding: 66px; } #ad_11 { background-image: url(images/index1.png); display: block; text-indent: ...

Alternative method to jQuery's "find" selector

$('.wrapper a').filter('a'); //returns all anchors I am trying to find a way to select all anchor elements using a specific selector. The issue is that the find method only looks at descendants, so I need an alternative solution. Any s ...

How to create a loop in Selenium IDE for selecting specific values from a drop-down list?

Is there a way to use Selenium IDE and JavaScript to test a drop-down box with specific items, not all of them, and continuously loop through until the entire list is covered? Any tips or recommendations on how to accomplish this? ...

Production environment experiencing issues with jQuery tabs functionality

Currently, I have implemented jQuery tabs on a simple HTML page. The tabs are functioning correctly and smoothly transitioning between different content sections. However, upon integrating this setup into my actual project environment, I encountered an is ...

What is the best way to dynamically assign an id to an ajax Actionlink in ASP.NET?

I have a collection of items and each item contains an Ajax.ActionLink. I would like to dynamically set the id for each action link based on the item's id. @Ajax.ActionLink("Join","ajaxview", new{id = tour.TourId}, new { HttpMethod = "GET", Insertion ...