3

I'm looking to create the following setup for a navigation structure.

enter image description here

I'm able to get the white down triangle working without an issue but how do I place yet another triangle (green lines) over the top of the first one without a full border/background or using an image? I can only get a solid green arrow over the white one and that's not what I want to do.

This is what I currently have.

 .custom-nav li a:after { 
    content: ""; 
    z-index: 99; 
    width: 0; 
    height: 0; 
    border-style: solid; 
    border-width: 40px 150px 0 150px; 
    border-color: #ffffff transparent transparent transparent; 
    position: absolute; 
    top: 173%; left: -75px; 
}
<div>
  <ul class="custom-nav">
    <li><a href="#">Environment</a></li>
    <li><a href="#">Health</a></li>
  </ul>
</div>

2
  • What do you mean with "without a full border/background"? Commented Apr 29, 2020 at 23:36
  • I just need the green lines, not the filled in triangle Commented Apr 30, 2020 at 5:37

2 Answers 2

2

I think the best option to get something like that is to use an SVG:

body {
  margin: 0;
  background: #DEE;
}

.nav {
  display: flex;
}

.button {
  position: relative;
  background: transparent;
  border: 0;
  width: 50%;
  height: 100px;
  padding: 0 0 50px;
  background: content-box white;
  font-family: monospace;
  font-weight: bold;
  outline: none;
  cursor: pointer;
}

.button__text {
  position: relative;
  z-index: 1;
}

.button__triangle {
  position: absolute;
  top: 25px;
  bottom: 0;
  left: 50%;
  width: 100%;
  transition: transform ease-in 150ms;
  transform: translate(-50%, -50%);
}

.button:hover > .button__triangle {
  transform: translate(-50%, 0);
}

.button__triangle--big {
  fill: white;
}

.button__triangle--small {
  fill: white;
  stroke: red;
  stroke-width: 2px;
  stroke-linecap: round;
  opacity: 0;
  transition: opacity ease-in 150ms;
}

.button:hover .button__triangle--small {
  opacity: 1;
}
<nav class="nav">
  <button class="button">
    <span class="button__text">OPTION 1</span>
    
    <svg viewBox="0 0 200 50" class="button__triangle">
      <polygon points="0,0 100,50 200,0" class="button__triangle--big" />
      <polyline points="50,5 100,30 150,5" class="button__triangle--small" />
    </svg>
  </button>
  
  <button class="button">
    <span class="button__text">OPTION 2</span>
    
    <svg viewBox="0 0 200 50" class="button__triangle">
      <polygon points="0,0 100,50 200,0" class="button__triangle--big" />
      <polyline points="50,5 100,30 150,5" class="button__triangle--small" />
    </svg>
  </button>
</nav>

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

5 Comments

Why SVG over straight CSS? Responsiveness or some other reason?
It offers more freedom to generate more complex shapes and gives you additional control with properties like stroke-linecap. You could use CSS borders or gradients to create something similar, but you would not be able to adjust that, for example. Also, at least in Chrome, SVGs look smoother than CSS gradients.
Also, it's easier to play around with what you are designing as each shape is an element. Don't need the white triangle? Remove its polygon. With CSS you usually end up using a combination of HTML elements and CSS pseudoelements and properties to render a single shape, so it's might become harder to adjust it later. For example, take a look at diana-adrianne.com/purecss-francine.
Thank you for the great explanation. BTW, that link is crazy!
We tried both approaches and found the SVG to be a better look. Worked well once we became familiar with how to draw it out. Thanks
2

Multiple background can do this:

.box {
  --w:160px; /* width of the arrow */
  --h:40px;  /* height of the arrow*/
  --b:2px;   /* thickness of the green arrow */
  --o:20%;   /* offset of the green arrow */
  
  /* gadient coloration, white then the green border then white again then transparent */
  --g:#fff var(--o),
      green var(--o) calc(var(--o) + var(--b)),
      #fff calc(var(--o) + var(--b) + 1px) 49.8%,
      transparent 50%;

  height:50px;
  margin:5px;
  border-bottom:var(--h) solid transparent; /* the arrow will take the border space */
  background:
    linear-gradient(to bottom right,var(--g)) calc(50% + calc(var(--w)/4)) 100% border-box,
    linear-gradient(to bottom left ,var(--g)) calc(50% - calc(var(--w)/4)) 100% border-box,
    #fff padding-box;
  background-size:calc(var(--w)/2) var(--h);
  background-repeat:no-repeat;
}


body {
  background:#000;
}
<div class="box"></div>

<div class="box" style="--w:200px;--h:60px;--o:30%;--b:5px"></div>

<div class="box" style="--w:180px;--h:30px;--o:10%;--b:3px"></div>

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.