0

I have put together the following CodePen which works perfectly, but I am wanting to know if there is a better way to apply :before & :after hover effect positions to each of the li link options more globally instead of adding a :before & :after set for every link option separately? They currently use an absolute positioning, where the top and left is defining its position, but ideally I want the :before & :after to be in the same position relative to each of the li.

So currently I am doing this:

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

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

/* List Item 2 */
.myLi-2:hover:after {
  top: 114px;
  left: 284px;
  position: absolute;
}

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

/* List Item 3 */
.myLi-3:hover:after {
  top: 162px;
  left: 284px;
  position: absolute;
}

.myLi-3:hover:before {
  top: 94px;
  left: 284px;
  position: absolute;
}

/* List Item 4 */
.myLi-4:hover:after {
  top: 210px;
  left: 284px;
  position: absolute;
}

.myLi-4:hover:before {
  top: 142px;
  left: 284px;
  position: absolute;
}

/* List Item 5 */
.myLi-5:hover:after {
  top: 258px;
  left: 284px;
  position: absolute;
}

.myLi-5:hover:before {
  top: 190px;
  left: 284px;
  position: absolute;
}

Please see the pen for a live working version and I believe the problem will be far more understandable:

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

  • 1
    Use position relative so you don't have to manually calculate the top/left offset absolutely. – Terry May 20 '21 at 12:10
  • Yes this is what I have been trying to do, but changing the absolute to relative doesn't seem to display my Before & After. – Valleys Group May 20 '21 at 12:17

2 Answers2

0

The problem is that absolute positioned items always behave absolute to the next relative item, which is in your case the ul and not the li. Do the following:

  1. Add to the li position: relative;
  2. Now you only need to add the before and after values to the li (they will all behave the same, so you only need the position inside the li) - no extra classes needed.

So your css should look somethink 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;
}

I am not quite sure about the bottom position in the after element, probably a different value.

JaneMcBrain
  • 330
  • 3
  • 10
0

Do the following:

Add to the li position: relative;

        .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>
Kashif
  • 480
  • 4
  • 11