DEV Community

Cover image for How To Make A Triangle With Double Border in CSS
Manuel Ricci
Manuel Ricci

Posted on

How To Make A Triangle With Double Border in CSS

In this tutorial I want to share with you my personal approach to design a triangle with a double border in CSS.

Let me better explain the problem that I've dealt with. I was developing a React component that shows a list of notifications.

This component will appear when a user click on the specific icon in the UI and from the design system shared by the UX teams of my client the component must have a border and in that border it's included the small arrow in the top right corner.

Now, the solution it would have been super simple if the border around the component was not there. One color and the arrow positioned right above that mix up with the main div. In this case instead, I need to figuring out how to obtain this border even around the triangle, that already use the border property, as written in this article on CSS Tricks.

The following image explain better what I need to obtain.
Arrow on the up right corner of a div

So let's see how I resolved this issue. Clearly if you know a different solution, share it I'll love to read it.

The Markup

Let's start with a simple markup.

<div class="message-box"></div>
Enter fullscreen mode Exit fullscreen mode

Nothing super fancy, just an empty div. Obviously you can enter what you want. This tutorial is focused only on the CSS triangle.

The Style

Let's add some style to the markup

.message-box {
  width: 100px; /* Just for demo purpose */
  height: 100px; /* Just for demo purpose */
  background-color: #fff;
  border: 1px solid #E6E8EB;
  box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.08);
  position: relative;
}
Enter fullscreen mode Exit fullscreen mode

If you're a seasoned CSS enthusiast this pretty easy to understand, but if you're a beginner instead let's make it clear.

I set a fixed width and height because my div is empty and I need to see what I'm doing. Next I set the background with a plain white and a silver border of 1px. I set a shadow, just because I love shadows and finally I set the position to relative, beacause the arrow that I'll create in a moment will have a position absolute.

If this part is clear let's add our triangle.

The (first) triangle

To add an arrow or a triangle, call it as you wish, I can use the pseudo-element ::before. Let's do it.

.message-box::before {
  content: "";
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid #E6E8EB;
}
Enter fullscreen mode Exit fullscreen mode

Here I create the pseudo-element and create the triangle. If you want to understand better how it's works read the article I mentioned early.

So far, so good. This is the result at this point:
Partial results

Note: The border is a little bigger because I zoomed in, so it's fine if you have a smaller one. After all it should be 1px, right? :)

Here we go with the solution to my issue

The (second) triangle

Now I need to create a second triangle, using as before the pseudo-elements, but this time I'll use ::after.

.message-box::after {
  content: "";
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid #fff;
  position: absolute;
  top: -5px;
  right: 10px;
}

Enter fullscreen mode Exit fullscreen mode

Well, that's it's not what I want, right now I can see only the white triangle. That's right, I simply duplicate the old one, but now I need to make some adjustment.

.message-box::after {
  content: "";
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-bottom: 4px solid #fff;
  position: absolute;
  top: -3.8px;
  right: 11px;
}
Enter fullscreen mode Exit fullscreen mode

What happened? I reduced of 1px the borders and play with the top and right values to achieve this results:

Final results

That's it, nothing more than this to get a second border to our triangle made in CSS.

Here the complete code:

.message-box {
  width: 100px; /* Just for demo purpose */
  height: 100px; /* Just for demo purpose */
  background-color: #fff;
  border: 1px solid #E6E8EB;
  box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.08);
  position: relative;
}

.message-box::before,
.message-box::after {
  content: "";
  width: 0;
  height: 0;
  position: absolute;
}

.message-box::before {
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid #E6E8EB;
  top: -5px;
  right: 10px;
}

.message-box::after {
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-bottom: 4px solid #fff;
  top: -3.8px;
  right: 11px;
}
Enter fullscreen mode Exit fullscreen mode

You've a different approach? Tell me about it in the comments.

Thanks for reading 👋

📸 Will Francis

Top comments (0)