18

I'm trying to have a CSS tooltip with white background color and 1px border. How to have a border instead of plain black arrow?

.up-arrow {
    display: inline-block;
    position: relative;
    border: 1px solid #777777;
    text-decoration: none;
    border-radius: 2px;
    padding: 20px;
}
.up-arrow:after {
    content: '';
    display: block;  
    position: absolute;
    left: 140px;
    bottom: 100%;
    width: 0;
    height: 0;
    border-bottom: 10px solid black;
    border-top: 10px solid transparent;
    border-left: 10px solid transparent;
    border-right: 10px solid transparent;
}
<div href="#" class="up-arrow">Button with Up Arrow</div>

PS: Even if it looks similar to another question, the details of design are very important. For example, there was originally here 3 different answers (now 2 of them deleted), slightly different in design. Even if very little different, their arrow look was a bit less perfect that the current perfect answer! The devil is in the detail!
The goal is here to have a plain white tooltip, with 1px wide border. Even if similar look to some other, it's not a duplicate of other question (speech bubble). Once again details are important to achieve such a sleek look.

Uyghur Lives Matter
  • 18,820
  • 42
  • 108
  • 144
Basj
  • 41,386
  • 99
  • 383
  • 673
  • @jbutler483 : It's a near question but clearly not a duplicate. – Basj Apr 26 '16 at 18:30
  • 1
    My answer there covers adding borders to such tooltips. If you feel your question is not, please edit your question to clarify the differences clearly. – jbutler483 Apr 26 '16 at 18:35
  • It is a dupe @Basj. The outcome is exactly the same, you're just putting the arrow in a different position... – Stewartside Apr 27 '16 at 08:27
  • @Stewartside I added a remark at the end of question. – Basj Apr 27 '16 at 08:55
  • 1
    @Basj it is a duplicate because it is the exact same shape just with a different position. The one in the dupe (which has been around longer and has more upvotes) just has a double border (simple css change) and a gray background (another simple css change). Although the answer below may be perfect, If you had spent 2 minutes attempting to use the dupe'd answer you would have achieved exactly the same outcome. – Stewartside Apr 27 '16 at 08:58
  • I literally changed from `border: 3px double black;` to `1px solid black;` to create [this](https://jsfiddle.net/Lyae1v0L/) – jbutler483 Apr 27 '16 at 09:05
  • @jbutler483 Then I changed your jsfiddle to `border-radius:2px; background: white;` to get the desired behaviour, and it's not like it should be. As I said, the details are really important to get this look, so I don't see the point in forcing a duplicate. But anyway, you choose, I'm not moderator anyway. – Basj Apr 27 '16 at 09:28
  • 4
    https://jsfiddle.net/Lyae1v0L/2/ - This was taken from the linked example code, with minimal alterations – jbutler483 Apr 27 '16 at 09:41
  • @jbutler483 The point is: of course *for you* it is easy because you master such skills, so can animate funny things and add even more variations :)... but from the point of view of someone who doesn't know this yet, they are not easy. Thanks anyway for all these demonstrations! – Basj Apr 27 '16 at 12:43

1 Answers1

58

One of the solutions would be adding another pseudo element :before which is slightly smaller than :after. It's not the nicest solution ever, but it works perfectly fine for particular cases.

(You may notice that I've also cleaned up your code a little and replaced :after with :before to have proper z-index for both pseudo elements. Let me know if you need further explanation)

.up-arrow {
    display: inline-block;
    position: relative;
    border: 1px solid #777777;
    text-decoration: none;
    border-radius: 2px;
    padding: 20px;
    margin-top: 50px;
}
.up-arrow:before {
    content: '';
    display: block;  
    position: absolute;
    left: 140px;
    bottom: 100%;
    width: 0;
    height: 0;
    border: 10px solid transparent;
    border-bottom-color: black;
}

.up-arrow:after {
    content: '';
    display: block;  
    position: absolute;
    left: 141px;
    bottom: 100%;
    width: 0;
    height: 0;
    border: 9px solid transparent;
    border-bottom-color: white;
}
<div href="#" class="up-arrow">Button with Up Arrow</div>
Paweł
  • 1,286
  • 1
  • 14
  • 17
  • 2
    how to make it point from top to bottom? – Oleg Abrazhaev Nov 30 '18 at 15:06
  • 2
    You need to do the following on my high DPI screen to correct for a thin 1/2 pixel line between the triangle and the box: `.up-arrow:after { bottom: calc(100% - 0.5px); }` This also makes the border width around the triangle the same thickness as the 1px border around the box. – EoghanM Feb 20 '19 at 11:35
  • How does it figure out how to make the triangle? I would expect an angle or something. – patrick Jun 02 '22 at 13:12