58

In bootstrap 2 the dropdown menu had an upwards arrow as it can be seen here (i am not talking about the carret). Now using bootstrap 3 or latest git this arrow doesn't exist in my simple example bellow nor in the examples on the bootstrap homepage.

How can I add this arrow again using bootstrap 3?

  <li class="dropdown">
    <a href="#" class="dropdown-toggle" data-toggle="dropdown">
      Menu
      <b class="caret"></b>
    </a>
    <ul class="dropdown-menu">
      <li><a href="#">a</a></li>
      <li><a href="#">b</a></li>
      <li><a href="#">c</a></li>
    </ul>
  </li>

PS:To be precise the picture can be seen in another stackoverflow article.

Community
  • 1
  • 1
user2993108
  • 583
  • 1
  • 5
  • 4

4 Answers4

161

You need to add :after and :before css rules to your dropdown-menu. These rules are taken from Bootstrap 2, and are what draw the triangle above the dropdown.

JSFiddle DEMO

.dropdown-menu:before {
  position: absolute;
  top: -7px;
  left: 9px;
  display: inline-block;
  border-right: 7px solid transparent;
  border-bottom: 7px solid #ccc;
  border-left: 7px solid transparent;
  border-bottom-color: rgba(0, 0, 0, 0.2);
  content: '';
}

.dropdown-menu:after {
  position: absolute;
  top: -6px;
  left: 10px;
  display: inline-block;
  border-right: 6px solid transparent;
  border-bottom: 6px solid #ffffff;
  border-left: 6px solid transparent;
  content: '';
}

Confused how? See here for an animation that explains css triangles

Alexander Mistakidis
  • 3,130
  • 2
  • 20
  • 23
  • 1
    This isn't responsive though, i.e. the placement of the arrow is incorrect. – user2993108 Nov 14 '13 at 21:48
  • 1
    What is the need for both `:before` and `:after`? It appears to work with just one of the two. http://jsfiddle.net/kq5Ef/387/ – mellis481 Jul 29 '15 at 13:12
  • 1
    @im1dermike Looks like your fiddle has both... but to answer your question: `:before` creates a gray (#ccc) triangle, and `:after` creates a white triangle. The gray one is placed behind to create the border around the white triangle. – Alexander Mistakidis Jul 30 '15 at 14:09
  • 1
    You should wrap the code with `@media (min-width: 768px) {}` to make sure the arrow doesn't appear in mobile navbar. – Alexey Kosov Apr 11 '16 at 11:50
  • Works! But how to place arrow at middle? – Gereltod Sep 28 '16 at 03:52
  • @AlexanderMistakidis any idea how we can make the arrow larger? similar to this [example](https://twentysixteendemo.wordpress.com/style-guide/) ? – Rain Man Nov 30 '16 at 11:08
  • @RainMan simply increase the size of the border and reposition top/left as needed – Alexander Mistakidis Dec 03 '16 at 22:22
  • @AlexanderMistakidis thanks for comment, that is what I tried but I can't get the triangle image aligned. I increased everything by 3px – Rain Man Dec 07 '16 at 11:54
18

Just to follow up on this - if you want the arrow to position itself correctly (like when using it on a navbar element that is right-aligned, you need the following additional CSS to ensure the arrow is right-aligned:

.navbar .navbar-right > li > .dropdown-menu:before,
.navbar .nav > li > .dropdown-menu.navbar-right:before {
    right: 12px; left: auto;
}

.navbar .navbar-right > li > .dropdown-menu:after,
.navbar .nav > li > .dropdown-menu.navbar-right:after {
    right: 13px; left: auto;
}

Note the "navbar-right" - that was introduced in BS3 instead of pull-right for navbars.

cdarken
  • 419
  • 4
  • 9
Joyrex
  • 1,103
  • 14
  • 24
3

The CSS that Alexander Mistakidis provided is correct. Which is to say, it creates the arrow atop the dropdown menu in Bootstrap. In order to position it correctly in a responsive view (@user2993108), you can change the left attribute for each of the class selectors (.dropdown-menu:before,.dropdown-menu:after) at different media queries or breakpoints.

For example...

@media (max-width: 400px) {

.dropdown-menu:before {
  position: absolute;
  top: -7px;
  left: 30px; /* change for positioning */
  ...
}

.dropdown-menu:after {
  position: absolute;
  top: -6px;
  left: 31px; /* change for positioning */
  ...
}

}

@media (max-width: 767px) and (min-width: 401px) {

.dropdown-menu:before {
  position: absolute;
  top: -7px;
  left: 38px; /* change for positioning */
  ...
}

.dropdown-menu:after {
  position: absolute;
  top: -6px;
  left: 39px; /* change for positioning */
  ...
}

}

and so on...

Dan
  • 371
  • 2
  • 4
2

This builds on the work by Alexander Mistakidis and Joyrex to support optional arrows and dropup menus. In my case I did not want to have an arrow on all of the dropdown menus, only some.

With this, you add the arrow class to the dropdown-menu element to get the arrow. If Bootstrap is positioning the dropdown/dropup to the left, also add arrow-right to shift the arrow to the other side.

// add an arrow to the dropdown menus
.dropdown-menu.arrow:before {
  position: absolute;
  left: 9px;
  display: inline-block;
  border-right: 7px solid transparent;
  border-left: 7px solid transparent;
  content: '';
}
.dropdown-menu.arrow:after {
  position: absolute;
  left: 10px;
  display: inline-block;
  border-right: 6px solid transparent;
  border-left: 6px solid transparent;
  content: '';
}

// postion at the top for a 'down' menu
.dropdown .dropdown-menu.arrow:before {
  top: -7px;
  border-bottom: 7px solid #ccc;
  border-bottom-color: rgba(0, 0, 0, 0.2);
}
.dropdown .dropdown-menu.arrow:after {
  top: -6px;
  border-bottom: 6px solid #ffffff;
}

// postion at the bottom for an 'up' menu
.dropup .dropdown-menu.arrow:before {
  bottom: -7px;
  border-top: 7px solid #ccc;
  border-top-color: rgba(0, 0, 0, 0.2);
}
.dropup .dropdown-menu.arrow:after {
  bottom: -6px;
  border-top: 6px solid #ffffff;
}

// support to move the arrow to the right-hand-side
.dropdown-menu.arrow.arrow-right:before,
.dropup .dropdown-menu.arrow.arrow-right:before {
  right: 15px;
  left: auto;
}
.dropdown-menu.arrow.arrow-right:after,
.dropup .dropdown-menu.arrow.arrow-right:after {
  right: 16px;
  left: auto;
}
Lucas Nelson
  • 2,511
  • 1
  • 17
  • 14