1

I have a list of links that when hovered have a stylish underline using :after - however, I need to add another effect when an item is active/ hovered on (pictured below).

When active, a "cut out triangle" should be at the end of the element to connect it visually to the wide expanded content to the right.

DESIRED END OUTCOME

I'm already adding an :after class on the link elements, so not sure how I can achieve this design?

.content-links {
  width: 25%;
  background-color: #fafafa;
  padding-left: 5.6rem;
  padding-top: 8rem;
  min-height: 100vh;
}

.content-links ul li {
  margin-bottom: 32px;
}

.content-links li {
  list-style: none;
}

.content-links a {
  text-decoration: none;
  font-size: 16px;
  line-height: 24px;
}

li a:after {
    z-index: 1;
    position: absolute;
    bottom: -8px;
    left: 0;
    right: 0;
    margin: auto;
    width: 0%;
    content: '.';
    color: transparent;
    background: black;
    height: 3px;
  }

  li a {
    position: relative;
  }

  li a:hover {
    color: green;
    font-weight: 600;
  }

  li a:hover:after,
  li a:active:after {
    transition: all 0.2s;
    width: 100%;
  }
  
  .content-panel {
    background-color: red;
  }
<div class="content-links">
  <ul>
    <li>
      <a href="#">Festivals</a>
    </li>
    <li>
      <a href="#">Events</a>
    </li>
    <li>
      <a href="#">Concerts</a>
    </li>
  </ul>
</div>

<div class="content-panel"></div>

EDIT: having explored :after and :before further, I'm not sure this is the most effective way of making this happen, I intended on using a triangle like so:

width: 0;
height: 0;
border-top: 25px solid transparent;
border-right: 50px solid #555;
border-bottom: 25px solid transparent;

but achieving both the borders (to make it look like a part of the container on the right) and actually the positioning (to be totally responsive) is proving to be a little hacky.

4
  • 4
    use the other pseudo-element :before? Commented May 3, 2023 at 14:32
  • There's no downside that it's technically :after? Commented May 3, 2023 at 15:02
  • Before and after in this context means, that the pseudoelements appear before or after the element in the DOM (developer.mozilla.org/en-US/docs/Web/CSS/::before). So to my knowledge there is no downside. Commented May 3, 2023 at 15:07
  • You might want to use CSS masks. developer.mozilla.org/en-US/docs/Web/CSS/mask . But don't know how to make it appear at the same level of an element. Commented May 3, 2023 at 17:00

1 Answer 1

1

The most correct would be to use a pseudo-element for the list item. It is also desirable to set the display: flex property to the list.

.content-links {
  min-height: 100vh;
  width: 25%;
  padding-top: 8rem;
  padding-left: 5.6rem;
  background-color: #fafafa;
  box-shadow: inset -4px 0 0 -2px #eeeee7;
}

.content-links ul {
  list-style: none;
  margin: 0;
  display: flex;
  flex-flow: column nowrap;
  gap: 32px;
  padding: 0;
}

.content-links ul li {
  position: relative;
}

li::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  z-index: 1;
  height: 100%;
  aspect-ratio: 1 / 1;
  background: #fff;
  box-shadow: inset 2px 2px 0 0 #eeeee7;
  transform: translatex(calc(50% - 2px)) rotate(-45deg) scale(0);
  pointer-events: none;
  transition: transform 0.2s ease-in-out;
}

li.active-item::before, /* .active-item for JS */
li:has(> a:hover)::before {
  transform: translatex(calc(50% - 2px)) rotate(-45deg) scale(1);
}

.content-links a {
  font-size: 16px;
  line-height: 24px;
  text-decoration: none;
}

li a {
  position: relative;
}

li a::after {
  content: '.';
  position: absolute;
  bottom: -8px;
  left: 0;
  right: 0;
  z-index: 1;
  margin: auto;
  height: 3px;
  width: 0%;
  color: transparent;
  background: black;
  pointer-events: none;
}

li a:hover {
  font-weight: 600;
  letter-spacing: -.35px;
  color: green;
}

li a:hover::after,
li a:active::after {
  width: 100%;
  transition: all 0.2s;
}

.content-panel {
  background-color: red;
}
<div class="content-links">
  <ul>
    <li>
      <a href="#">Festivals</a>
    </li>
    <li>
      <a href="#">Events</a>
    </li>
    <li>
      <a href="#">Concerts</a>
    </li>
  </ul>
</div>

<div class="content-panel"></div>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.