Home / Make a box pop with a pointer on the side

Make a box stand out by adding a pointer

Having a div with a border is pretty standard. But there are situations where you want the box to stand out.

One way is to add a pointer element to the div to call attention to something else.

Here is the markup for a classic div.

<div class="box">
  <h3>Hello there</h3>
  <p>
    this is another line
  </p>
</div>

Let's add some styling such as a border.

.box {
  position: relative;
  border: 2px solid #33ff33;
  padding: 50px;
  width: 200px;
}

box 1

How to we extend the styling to show a pointer or other elements around it without adding extra divs?

The answer is the :before and :after pseudo elements.

body {
  font-family: Helvetica, sans-serif;
}

.box {
  position: relative;
  border: 2px solid #33ff33;
  padding: 50px;
  width: 200px;
}

.box:after {
  position: absolute;
  content: "";
  right: 0px;
  top: 50%;
  width: 50px;
  height: 50px;
  transform: translateY(-50%) translateX(100%);
  border: 2px solid #33ff33;
  background: #fff;
}

That is great, but we only added a box. Our element looks a bit like battery at the moment.

box 1

We will need to do a few things.

  1. Create a triangle
  2. Show a border around that shape

The first part can be done with the use of clip-path

Using Clippy the css-clip path genrator, we can get the shape we are looking for.

clip-path: polygon(0 0, 0% 100%, 100% 50%); will create a triangle pointing to the right.

body {
  font-family: Helvetica, sans-serif;
}

.box {
  position: relative;
  border: 2px solid #33ff33;
  padding: 50px;
  width: 200px;
}

.box:after {
  position: absolute;
  content: "";
  right: 0px;
  top: 50%;
  width: 50px;
  height: 50px;
  transform: translateY(-50%) translateX(100%);
  clip-path: polygon(0 0, 0% 100%, 100% 50%);
  background: #33ff33;
}

box 3

This gets us closer to what we are looking for, but we are left with a green triangle. We want to match the border. clip-path does not have an option to create a border around the shape.

The best way to deal with this is to leverage pseudo elements again. This time we will use the :before element to create an overlapping triangle that we can offset enough to show a border.

body {
  font-family: Helvetica, sans-serif;
}

.box {
  position: relative;
  border: 2px solid #33ff33;
  padding: 50px;
  width: 200px;
}

.box:after {
  position: absolute;
  content: "";
  right: 0px;
  top: 50%;
  width: 50px;
  height: 50px;
  transform: translateY(-50%) translateX(100%);
  clip-path: polygon(0 0, 0% 100%, 100% 50%);
  background: #fff;
}

.box:before {
  position: absolute;
  content: "";
  right: -2px;
  top: 50%;
  width: 50px;
  height: 50px;
  background: #33ff33;
  transform: translateY(-50%) translateX(100%);
  clip-path: polygon(0 0, 0% 100%, 100% 50%);
}

With that change we also resolve the issue of hiding the main box border that is adjacent to the triangle. This gives us seamless border that trasnitions from the rectangular box to the arrow to the right.

Complete box

Checkout the full code on Codepen