| commit | author | age | ||
| 83c3f6 | 1 | --- |
| SP | 2 | layout: docs |
| 3 | title: Popovers | |
| 4 | description: Documentation and examples for adding Bootstrap popovers, like those found in iOS, to any element on your site. | |
| 5 | group: components | |
| 6 | toc: true | |
| 7 | --- | |
| 8 | ||
| 9 | ## Overview | |
| 10 | ||
| 11 | Things to know when using the popover plugin: | |
| 12 | ||
| 13 | - Popovers rely on the 3rd party library [Popper.js](https://popper.js.org/) for positioning. You must include [popper.min.js]({{ site.cdn.popper }}) before bootstrap.js or use `bootstrap.bundle.min.js` / `bootstrap.bundle.js` which contains Popper.js in order for popovers to work! | |
| 14 | - Popovers require the [tooltip plugin]({{ site.baseurl }}/docs/{{ site.docs_version }}/components/tooltips/) as a dependency. | |
| 15 | - If you're building our JavaScript from source, it [requires `util.js`]({{ site.baseurl }}/docs/{{ site.docs_version }}/getting-started/javascript/#util). | |
| 16 | - Popovers are opt-in for performance reasons, so **you must initialize them yourself**. | |
| 17 | - Zero-length `title` and `content` values will never show a popover. | |
| 18 | - Specify `container: 'body'` to avoid rendering problems in more complex components (like our input groups, button groups, etc). | |
| 19 | - Triggering popovers on hidden elements will not work. | |
| 20 | - Popovers for `.disabled` or `disabled` elements must be triggered on a wrapper element. | |
| 21 | - When triggered from anchors that wrap across multiple lines, popovers will be centered between the anchors' overall width. Use `.text-nowrap` on your `<a>`s to avoid this behavior. | |
| 22 | - Popovers must be hidden before their corresponding elements have been removed from the DOM. | |
| 23 | - Popovers can be triggered thanks to an element inside a shadow DOM. | |
| 24 | ||
| 25 | {% include callout-info-prefersreducedmotion.md %} | |
| 26 | ||
| 27 | Keep reading to see how popovers work with some examples. | |
| 28 | ||
| 29 | ## Example: Enable popovers everywhere | |
| 30 | ||
| 31 | One way to initialize all popovers on a page would be to select them by their `data-toggle` attribute: | |
| 32 | ||
| 33 | {% highlight js %} | |
| 34 | $(function () { | |
| 35 | $('[data-toggle="popover"]').popover() | |
| 36 | }) | |
| 37 | {% endhighlight %} | |
| 38 | ||
| 39 | ## Example: Using the `container` option | |
| 40 | ||
| 41 | When you have some styles on a parent element that interfere with a popover, you'll want to specify a custom `container` so that the popover's HTML appears within that element instead. | |
| 42 | ||
| 43 | {% highlight js %} | |
| 44 | $(function () { | |
| 45 | $('.example-popover').popover({ | |
| 46 | container: 'body' | |
| 47 | }) | |
| 48 | }) | |
| 49 | {% endhighlight %} | |
| 50 | ||
| 51 | ## Example | |
| 52 | ||
| 53 | {% capture example %} | |
| 54 | <button type="button" class="btn btn-lg btn-danger" data-toggle="popover" title="Popover title" data-content="And here's some amazing content. It's very engaging. Right?">Click to toggle popover</button> | |
| 55 | {% endcapture %} | |
| 56 | {% include example.html content=example %} | |
| 57 | ||
| 58 | ### Four directions | |
| 59 | ||
| 60 | Four options are available: top, right, bottom, and left aligned. | |
| 61 | ||
| 62 | <div class="bd-example popover-demo"> | |
| 63 | <div class="bd-example-popovers"> | |
| 64 | <button type="button" class="btn btn-secondary" data-container="body" data-toggle="popover" data-placement="top" data-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus."> | |
| 65 | Popover on top | |
| 66 | </button> | |
| 67 | <button type="button" class="btn btn-secondary" data-container="body" data-toggle="popover" data-placement="right" data-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus."> | |
| 68 | Popover on right | |
| 69 | </button> | |
| 70 | <button type="button" class="btn btn-secondary" data-container="body" data-toggle="popover" data-placement="bottom" data-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus."> | |
| 71 | Popover on bottom | |
| 72 | </button> | |
| 73 | <button type="button" class="btn btn-secondary" data-container="body" data-toggle="popover" data-placement="left" data-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus."> | |
| 74 | Popover on left | |
| 75 | </button> | |
| 76 | </div> | |
| 77 | </div> | |
| 78 | ||
| 79 | {% highlight html %} | |
| 80 | <button type="button" class="btn btn-secondary" data-container="body" data-toggle="popover" data-placement="top" data-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus."> | |
| 81 | Popover on top | |
| 82 | </button> | |
| 83 | ||
| 84 | <button type="button" class="btn btn-secondary" data-container="body" data-toggle="popover" data-placement="right" data-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus."> | |
| 85 | Popover on right | |
| 86 | </button> | |
| 87 | ||
| 88 | <button type="button" class="btn btn-secondary" data-container="body" data-toggle="popover" data-placement="bottom" data-content="Vivamus | |
| 89 | sagittis lacus vel augue laoreet rutrum faucibus."> | |
| 90 | Popover on bottom | |
| 91 | </button> | |
| 92 | ||
| 93 | <button type="button" class="btn btn-secondary" data-container="body" data-toggle="popover" data-placement="left" data-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus."> | |
| 94 | Popover on left | |
| 95 | </button> | |
| 96 | {% endhighlight %} | |
| 97 | ||
| 98 | ### Dismiss on next click | |
| 99 | ||
| 100 | Use the `focus` trigger to dismiss popovers on the user's next click of a different element than the toggle element. | |
| 101 | ||
| 102 | {% capture callout %} | |
| 103 | #### Specific markup required for dismiss-on-next-click | |
| 104 | ||
| 105 | For proper cross-browser and cross-platform behavior, you must use the `<a>` tag, _not_ the `<button>` tag, and you also must include a [`tabindex`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex) attribute. | |
| 106 | {% endcapture %} | |
| 107 | {% include callout.html content=callout type="danger" %} | |
| 108 | ||
| 109 | {% capture example %} | |
| 110 | <a tabindex="0" class="btn btn-lg btn-danger" role="button" data-toggle="popover" data-trigger="focus" title="Dismissible popover" data-content="And here's some amazing content. It's very engaging. Right?">Dismissible popover</a> | |
| 111 | {% endcapture %} | |
| 112 | {% include example.html content=example %} | |
| 113 | ||
| 114 | {% highlight js %} | |
| 115 | $('.popover-dismiss').popover({ | |
| 116 | trigger: 'focus' | |
| 117 | }) | |
| 118 | {% endhighlight %} | |
| 119 | ||
| 120 | ### Disabled elements | |
| 121 | ||
| 122 | Elements with the `disabled` attribute aren't interactive, meaning users cannot hover or click them to trigger a popover (or tooltip). As a workaround, you'll want to trigger the popover from a wrapper `<div>` or `<span>` and override the `pointer-events` on the disabled element. | |
| 123 | ||
| 124 | For disabled popover triggers, you may also prefer `data-trigger="hover"` so that the popover appears as immediate visual feedback to your users as they may not expect to _click_ on a disabled element. | |
| 125 | ||
| 126 | {% capture example %} | |
| 127 | <span class="d-inline-block" data-toggle="popover" data-content="Disabled popover"> | |
| 128 | <button class="btn btn-primary" style="pointer-events: none;" type="button" disabled>Disabled button</button> | |
| 129 | </span> | |
| 130 | {% endcapture %} | |
| 131 | {% include example.html content=example %} | |
| 132 | ||
| 133 | ## Usage | |
| 134 | ||
| 135 | Enable popovers via JavaScript: | |
| 136 | ||
| 137 | {% highlight js %}$('#example').popover(options){% endhighlight %} | |
| 138 | ||
| 139 | ### Options | |
| 140 | ||
| 141 | Options can be passed via data attributes or JavaScript. For data attributes, append the option name to `data-`, as in `data-animation=""`. | |
| 142 | ||
| 143 | <table class="table table-bordered table-striped"> | |
| 144 | <thead> | |
| 145 | <tr> | |
| 146 | <th style="width: 100px;">Name</th> | |
| 147 | <th style="width: 100px;">Type</th> | |
| 148 | <th style="width: 50px;">Default</th> | |
| 149 | <th>Description</th> | |
| 150 | </tr> | |
| 151 | </thead> | |
| 152 | <tbody> | |
| 153 | <tr> | |
| 154 | <td>animation</td> | |
| 155 | <td>boolean</td> | |
| 156 | <td>true</td> | |
| 157 | <td>Apply a CSS fade transition to the popover</td> | |
| 158 | </tr> | |
| 159 | <tr> | |
| 160 | <td>container</td> | |
| 161 | <td>string | element | false</td> | |
| 162 | <td>false</td> | |
| 163 | <td> | |
| 164 | <p>Appends the popover to a specific element. Example: <code>container: 'body'</code>. This option is particularly useful in that it allows you to position the popover in the flow of the document near the triggering element -Â which will prevent the popover from floating away from the triggering element during a window resize.</p> | |
| 165 | </td> | |
| 166 | </tr> | |
| 167 | <tr> | |
| 168 | <td>content</td> | |
| 169 | <td>string | element | function</td> | |
| 170 | <td>''</td> | |
| 171 | <td> | |
| 172 | <p>Default content value if <code>data-content</code> attribute isn't present.</p> | |
| 173 | <p>If a function is given, it will be called with its <code>this</code> reference set to the element that the popover is attached to.</p> | |
| 174 | </td> | |
| 175 | </tr> | |
| 176 | <tr> | |
| 177 | <td>delay</td> | |
| 178 | <td>number | object</td> | |
| 179 | <td>0</td> | |
| 180 | <td> | |
| 181 | <p>Delay showing and hiding the popover (ms) - does not apply to manual trigger type</p> | |
| 182 | <p>If a number is supplied, delay is applied to both hide/show</p> | |
| 183 | <p>Object structure is: <code>delay: { "show": 500, "hide": 100 }</code></p> | |
| 184 | </td> | |
| 185 | </tr> | |
| 186 | <tr> | |
| 187 | <td>html</td> | |
| 188 | <td>boolean</td> | |
| 189 | <td>false</td> | |
| 190 | <td>Insert HTML into the popover. If false, jQuery's <code>text</code> method will be used to insert content into the DOM. Use text if you're worried about XSS attacks.</td> | |
| 191 | </tr> | |
| 192 | <tr> | |
| 193 | <td>placement</td> | |
| 194 | <td>string | function</td> | |
| 195 | <td>'right'</td> | |
| 196 | <td> | |
| 197 | <p>How to position the popover - auto | top | bottom | left | right.<br>When <code>auto</code> is specified, it will dynamically reorient the popover.</p> | |
| 198 | <p>When a function is used to determine the placement, it is called with the popover DOM node as its first argument and the triggering element DOM node as its second. The <code>this</code> context is set to the popover instance.</p> | |
| 199 | </td> | |
| 200 | </tr> | |
| 201 | <tr> | |
| 202 | <td>selector</td> | |
| 203 | <td>string | false</td> | |
| 204 | <td>false</td> | |
| 205 | <td>If a selector is provided, popover objects will be delegated to the specified targets. In practice, this is used to enable dynamic HTML content to have popovers added. See <a href="https://github.com/twbs/bootstrap/issues/4215">this</a> and <a href="https://codepen.io/Johann-S/pen/djJYPb">an informative example</a>.</td> | |
| 206 | </tr> | |
| 207 | <tr> | |
| 208 | <td>template</td> | |
| 209 | <td>string</td> | |
| 210 | <td><code>'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'</code></td> | |
| 211 | <td> | |
| 212 | <p>Base HTML to use when creating the popover.</p> | |
| 213 | <p>The popover's <code>title</code> will be injected into the <code>.popover-header</code>.</p> | |
| 214 | <p>The popover's <code>content</code> will be injected into the <code>.popover-body</code>.</p> | |
| 215 | <p><code>.arrow</code> will become the popover's arrow.</p> | |
| 216 | <p>The outermost wrapper element should have the <code>.popover</code> class.</p> | |
| 217 | </td> | |
| 218 | </tr> | |
| 219 | <tr> | |
| 220 | <td>title</td> | |
| 221 | <td>string | element | function</td> | |
| 222 | <td>''</td> | |
| 223 | <td> | |
| 224 | <p>Default title value if <code>title</code> attribute isn't present.</p> | |
| 225 | <p>If a function is given, it will be called with its <code>this</code> reference set to the element that the popover is attached to.</p> | |
| 226 | </td> | |
| 227 | </tr> | |
| 228 | <tr> | |
| 229 | <td>trigger</td> | |
| 230 | <td>string</td> | |
| 231 | <td>'click'</td> | |
| 232 | <td>How popover is triggered - click | hover | focus | manual. You may pass multiple triggers; separate them with a space. <code>manual</code> cannot be combined with any other trigger.</td> | |
| 233 | </tr> | |
| 234 | <tr> | |
| 235 | <td>offset</td> | |
| 236 | <td>number | string</td> | |
| 237 | <td>0</td> | |
| 238 | <td>Offset of the popover relative to its target. For more information refer to Popper.js's <a href="https://popper.js.org/popper-documentation.html#modifiers..offset.offset">offset docs</a>.</td> | |
| 239 | </tr> | |
| 240 | <tr> | |
| 241 | <td>fallbackPlacement</td> | |
| 242 | <td>string | array</td> | |
| 243 | <td>'flip'</td> | |
| 244 | <td>Allow to specify which position Popper will use on fallback. For more information refer to | |
| 245 | Popper.js's <a href="https://popper.js.org/popper-documentation.html#modifiers..flip.behavior">behavior docs</a></td> | |
| 246 | </tr> | |
| 247 | <tr> | |
| 248 | <td>boundary</td> | |
| 249 | <td>string | element</td> | |
| 250 | <td>'scrollParent'</td> | |
| 251 | <td>Overflow constraint boundary of the popover. Accepts the values of <code>'viewport'</code>, <code>'window'</code>, <code>'scrollParent'</code>, or an HTMLElement reference (JavaScript only). For more information refer to Popper.js's <a href="https://popper.js.org/popper-documentation.html#modifiers..preventOverflow.boundariesElement">preventOverflow docs</a>.</td> | |
| 252 | </tr> | |
| 253 | </tbody> | |
| 254 | </table> | |
| 255 | ||
| 256 | {% capture callout %} | |
| 257 | #### Data attributes for individual popovers | |
| 258 | ||
| 259 | Options for individual popovers can alternatively be specified through the use of data attributes, as explained above. | |
| 260 | {% endcapture %} | |
| 261 | {% include callout.html content=callout type="info" %} | |
| 262 | ||
| 263 | ### Methods | |
| 264 | ||
| 265 | {% include callout-danger-async-methods.md %} | |
| 266 | ||
| 267 | #### `$().popover(options)` | |
| 268 | ||
| 269 | Initializes popovers for an element collection. | |
| 270 | ||
| 271 | #### `.popover('show')` | |
| 272 | ||
| 273 | Reveals an element's popover. **Returns to the caller before the popover has actually been shown** (i.e. before the `shown.bs.popover` event occurs). This is considered a "manual" triggering of the popover. Popovers whose both title and content are zero-length are never displayed. | |
| 274 | ||
| 275 | {% highlight js %}$('#element').popover('show'){% endhighlight %} | |
| 276 | ||
| 277 | #### `.popover('hide')` | |
| 278 | ||
| 279 | Hides an element's popover. **Returns to the caller before the popover has actually been hidden** (i.e. before the `hidden.bs.popover` event occurs). This is considered a "manual" triggering of the popover. | |
| 280 | ||
| 281 | {% highlight js %}$('#element').popover('hide'){% endhighlight %} | |
| 282 | ||
| 283 | #### `.popover('toggle')` | |
| 284 | ||
| 285 | Toggles an element's popover. **Returns to the caller before the popover has actually been shown or hidden** (i.e. before the `shown.bs.popover` or `hidden.bs.popover` event occurs). This is considered a "manual" triggering of the popover. | |
| 286 | ||
| 287 | {% highlight js %}$('#element').popover('toggle'){% endhighlight %} | |
| 288 | ||
| 289 | #### `.popover('dispose')` | |
| 290 | ||
| 291 | Hides and destroys an element's popover. Popovers that use delegation (which are created using [the `selector` option](#options)) cannot be individually destroyed on descendant trigger elements. | |
| 292 | ||
| 293 | {% highlight js %}$('#element').popover('dispose'){% endhighlight %} | |
| 294 | ||
| 295 | #### `.popover('enable')` | |
| 296 | ||
| 297 | Gives an element's popover the ability to be shown. **Popovers are enabled by default.** | |
| 298 | ||
| 299 | {% highlight js %}$('#element').popover('enable'){% endhighlight %} | |
| 300 | ||
| 301 | #### `.popover('disable')` | |
| 302 | ||
| 303 | Removes the ability for an element's popover to be shown. The popover will only be able to be shown if it is re-enabled. | |
| 304 | ||
| 305 | {% highlight js %}$('#element').popover('disable'){% endhighlight %} | |
| 306 | ||
| 307 | #### `.popover('toggleEnabled')` | |
| 308 | ||
| 309 | Toggles the ability for an element's popover to be shown or hidden. | |
| 310 | ||
| 311 | {% highlight js %}$('#element').popover('toggleEnabled'){% endhighlight %} | |
| 312 | ||
| 313 | #### `.popover('update')` | |
| 314 | ||
| 315 | Updates the position of an element's popover. | |
| 316 | ||
| 317 | {% highlight js %}$('#element').popover('update'){% endhighlight %} | |
| 318 | ||
| 319 | ### Events | |
| 320 | ||
| 321 | <table class="table table-bordered table-striped"> | |
| 322 | <thead> | |
| 323 | <tr> | |
| 324 | <th style="width: 150px;">Event Type</th> | |
| 325 | <th>Description</th> | |
| 326 | </tr> | |
| 327 | </thead> | |
| 328 | <tbody> | |
| 329 | <tr> | |
| 330 | <td>show.bs.popover</td> | |
| 331 | <td>This event fires immediately when the <code>show</code> instance method is called.</td> | |
| 332 | </tr> | |
| 333 | <tr> | |
| 334 | <td>shown.bs.popover</td> | |
| 335 | <td>This event is fired when the popover has been made visible to the user (will wait for CSS transitions to complete).</td> | |
| 336 | </tr> | |
| 337 | <tr> | |
| 338 | <td>hide.bs.popover</td> | |
| 339 | <td>This event is fired immediately when the <code>hide</code> instance method has been called.</td> | |
| 340 | </tr> | |
| 341 | <tr> | |
| 342 | <td>hidden.bs.popover</td> | |
| 343 | <td>This event is fired when the popover has finished being hidden from the user (will wait for CSS transitions to complete).</td> | |
| 344 | </tr> | |
| 345 | <tr> | |
| 346 | <td>inserted.bs.popover</td> | |
| 347 | <td>This event is fired after the <code>show.bs.popover</code> event when the popover template has been added to the DOM.</td> | |
| 348 | </tr> | |
| 349 | </tbody> | |
| 350 | </table> | |
| 351 | ||
| 352 | {% highlight js %} | |
| 353 | $('#myPopover').on('hidden.bs.popover', function () { | |
| 354 | // do something… | |
| 355 | }) | |
| 356 | {% endhighlight %} | |