Bring interactivity to your site with a selection of jQuery widgets (plugins) all built with accessibility and usability in mind.
Popover popover.js
A more robust version of a tooltip, that allows for larger pieces of content or interactive functionality.
Widget Dependencies
Popover requires the following:
- Tooltip widget for the base functionality.
- Drag widget for drag functionality.
Overview
Important notes about using the popover widget:
- Specify
container: 'body'
to avoid rendering problems in more complex components (like our input groups, button groups, etc). - Triggering popovers on hidden elements will not work.
- Popovers for
.disabled
ordisabled
elements must be triggered on a wrapper element. - When triggered from anchors that wrap across multiple lines, popovers will be centered between the anchors' overall width. Use
white-space: nowrap;
on your<a>
s to avoid this behavior.
Examples
Static Popover
Four options are available: top, forward( right), bottom, and reverse (left) aligned.
Heads up! When using the right-to-left, rtl
, variant of Figuration all horizontal directions will be reversed. Meaning left becomes right, and vice-versa.
Popover top
Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.
Forward popover
Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.
Popover bottom
Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.
Reverse popover
Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.
Four Directions
<button type="button" class="btn" data-cfw="popover" data-cfw-popover-container="body" data-cfw-popover-placement="top" data-cfw-popover-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">
Popover on top
</button>
<button type="button" class="btn" data-cfw="popover" data-cfw-popover-container="body" data-cfw-popover-placement="forward" data-cfw-popover-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">
Forward popover
</button>
<button type="button" class="btn" data-cfw="popover" data-cfw-popover-container="body" data-cfw-popover-placement="bottom" data-cfw-popover-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">
Popover on bottom
</button>
<button type="button" class="btn" data-cfw="popover" data-cfw-popover-container="body" data-cfw-popover-placement="reverse" data-cfw-popover-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">
Reverse popover
</button>
Default Toggle Example
<button type="button" class="btn btn-info" data-cfw="popover" title="Click Popover Example" data-cfw-popover-content="Click the trigger or close button to close me." data-cfw-popover-placement="forward">Click to toggle popover</button>
Hover Example
<button type="button" class="btn btn-info" id="cf-example-hover-popover" data-cfw="popover" title="Hover Popover Example" data-cfw-popover-content="Stop hovering over the trigger or the popover to auto-close." data-cfw-popover-placement="forward" data-cfw-popover-trigger="hover focus">Hover/focus to show popover</button>
Draggable Example
Allow users to move popovers around the screen by enabling the drag
option. Drag support mouse, keyboard (with arrow keys), and touch movement.
<button type="button" class="btn btn-info" data-cfw="popover" title="Draggable Popover Example" data-cfw-popover-content="Click the trigger or close link to close me." data-cfw-popover-placement="forward" data-cfw-popover-drag="true">Draggable popover</button>
Popover with HTML
<button type="button" class="btn btn-info" data-cfw="popover" data-cfw-popover-html="true" data-cfw-popover-placement="forward" data-cfw-popover-content="<em>Popover</em> <u>with</u> <b>HTML</b>" title="<em>Popover</em> <u>with</u> <b>HTML</b>">Popover with HTML</button>
If using more complex HTML, using a data attribute might not be optimal. A better option would be to use the Javascript options, or with a pre-generated popover, as shown in the following example.
<button type="button" class="btn btn-info" id="html-popover">Popover with HTML</button>
<script>
$('#html-popover').CFW_Popover({
html: true,
title: '<em>Popover</em> <u>with</u> <b>HTML</b>',
content: '<span aria-hidden="true">·</span> <em>Popover</em> <u>with</u> <b>HTML</b>'
});
</script>
Pre-generated Popover
Have a complex content that you would like to show in a popover, or one that is updated dynamically? Create the popover and then link to it with the target
option.
Popover title
Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.

<button type="button" class="btn btn-info" data-cfw="popover" data-cfw-popover-target="#popoverExample0" data-cfw-popover-placement="forward">Show Popover</button>
<div class="popover" id="popoverExample0">
<h3 class="popover-header">Popover title</h3>
<div class="popover-body">
<p>Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.</p>
<figure class="figure">
<img src="/assets/3.0/img/test.gif" class="figure-img img-fluid" alt="Sample image">
<figcaption class="figure-caption">Sample image caption.</figcaption>
</figure>
</div>
<div class="popover-arrow"></div>
</div>
Custom Placement
Locate a popover anywhere you need with the placement
option.
<button type="button" class="btn btn-info" id="cf-example-placed-popover" title="Custom placed popover" data-cfw-popover-content="Look, I am way over here!">Custom Placement Popover</button>
<script>
$('#cf-example-placed-popover').CFW_Popover({
placement : function(tip, trigger) {
var $trigger = $(trigger);
var loc = {};
var pos = $trigger.offset();
loc.top = pos.top;
loc.left = pos.left + $trigger.parent().width() - $trigger.outerWidth();
return loc;
}
});
</script>
Viewport Constrainment
Keep popovers in their place with the viewport
option.
<div class="container-viewport" id="viewport-popover">
<p class="viewport-text">Viewport constraints for popovers.</p>
<button type="button" class="btn btn-info popover-viewport-bottom" title="This should be shifted to the right">Shift Right</button>
<button type="button" class="btn btn-info popover-viewport-right" title="This should be shifted down">Shift Down</button>
<button type="button" class="btn btn-info float-end popover-viewport-bottom" title="This should be shifted to the left">Shift Left</button>
<button type="button" class="btn btn-info popover-viewport-right btn-bottom" title="This should be shifted up">Shift Up</button>
<button type="button" class="btn btn-info popover-viewport-drag btn-drag" title="This should be confined to the viewport box">Drag Test (click)</button>
</div>
<script>
$('.popover-viewport-right').CFW_Popover({
placement: 'forward',
viewport: '#viewport-popover',
padding: 2
});
$('.popover-viewport-bottom').CFW_Popover({
placement: 'bottom',
viewport: '#viewport-popover',
padding: 2
});
$('.popover-viewport-drag').CFW_Popover({
drag: true,
viewport: '#viewport-popover',
padding: 2
});
</script>
Disabled Elements
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.
For disabled popover triggers, you may also prefer data-cfw-popover-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.
<span class="d-inline-block" data-cfw="popover" data-cfw-popover-content="Popover for disabled item">
<button class="btn btn-primary" style="pointer-events: none;" type="button" disabled>Disabled button</button>
</span>
Usage
The popover widget, by default, generates content and markup on demand, and by default places popovers after their trigger element.
Via Data Attributes
The required markup for a popover is only a data-cfw="popover"
attribute and title
or a data-cfw-popover-content=""
on the HTML element you wish to have a popover. The generated markup of a popover is rather simple, though it does require a position (by default, set to top by the widget).
If the popover item is already created, you can link to it using data-cfw-popover-target="#somePopover"
, or href="#somePopover"
. The proper role
and aria-
attributes will be automatically created to link the trigger and target elements.
Via JavaScript
Enable manually with:
$('#myPopover').CFW_Popover();
Close Triggers
Any element with a data attribute of data-cfw-dismiss="popover"
within the popover element will act as a close trigger for the popover. There can be multiple close triggers, such as a header/titlebar close and a cancel button in the footer.
Draggable Popovers
The added functionality from the Drag widget allows for touch and mouse dragging to be available.
The drag event handlers will auto-enable when a data-cfw-drag="popover"
trigger item is found within the popover item. The drag
option will insert a drag trigger into the popover element, resulting in invoking the drag handlers.
Draggable popovers will force the following settings:
container: 'body'
trigger: 'click'
Options
Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-cfw-popover
, as in data-cfw-popover-placement="forward"
.
Name | Type | Default | Description |
---|---|---|---|
target | string | null |
The selector (jQuery style) of the target popover. |
animate | boolean | true |
If popover items should fade in and out. |
placement | string | object | function | 'top' |
string:
object:
function: function myPopoverAlign(tip, trigger) { // this - popover data-api // tip -> popover target // trigger -> popover trigger } |
trigger | string | 'hover focus' |
How popover is triggered - click | hover | focus | manual. You may pass multiple triggers; separate them with a space. manual cannot be combined with any other trigger. |
delay | number| object | show:0, hide:250 |
Delay showing and hiding the popover (ms) - does not apply to manual trigger type. If a number is supplied, delay is applied to both hide/show. Object structure is:delay: { show: 500, hide: 100 }
|
container | string | false | false |
Appends the popover to a specific element. Example: container: 'body' |
viewport | string | function | 'body' |
Keeps the popover within the bounds of this element. Example: If a function is given, it is called with the triggering element DOM node as its only argument. The |
padding | integer | 0 |
Spacing, in pixels, to keep the popover away from the viewport edge. |
html | boolean | false |
Insert HTML into the popover. If false, jQuery's text method will be used to insert content into the DOM. Use text if you're worried about XSS attacks. |
closetext | string | '<span aria-hidden="true" >×</span>' |
Visible text for close links when using option trigger: 'click' |
closesrtext | string | 'Close' |
Screen reader only text alternative for close links when using option trigger: 'click' |
title | string | function | '' |
Default title value if title attribute isn't present. |
content | string | function | '' |
Default title value if data-cfw-popover-content attribute isn't present. |
unlink | boolean | false |
If the unlink method should be called when the popover is hidden. This leaves the popover behind in the DOM. |
dispose | boolean | false |
If the dispose method should be called when the popover is hidden. This will remove the popover from the DOM. |
drag | boolean | false |
If the popover should have a drag handle inserted. |
dragtext | string | '<span aria-hidden="true" >+</span>' |
Visible text for the auto-inserted drag handle. |
dragsrtext | string | 'Drag' |
Screen reader only text alternative for the auto-inserted drag handle. |
dragstep | integer | 10 |
Pixel increment to move the popover when using arrow keys on a drag handle. |
show | boolean | false |
Show the popover automatically at the end of initialization. This will force the trigger option to a setting of 'click' . |
Methods
.CFW_Popover(options)
Activates a popover on a given element. Accepts an optional options object
.
$('#myPopover').CFW_Popover({
placement: 'forward'
});
.CFW_Popover('toggle')
Toggles a popover item to be shown or hidden.
.CFW_Popover('show')
Shows an element's popover.
.CFW_Popover('hide')
Hides an element's popover.
.CFW_Popover('unlink')
Hides the popover, removes events and attributes from both trigger and popover.
.CFW_Popover('dispose')
Calls the unlink
method, and then removes the popover from the DOM.
Events
Event callbacks happen on the toggle/trigger element.
Event Type | Description |
---|---|
init.cfw.popover | This event fires after the popover item is initialized. |
beforeShow.cfw.popover | This event is fired immediately when the show method is called. If the popover container is not present, it is created just after this event is called. |
afterShow.cfw.popover | This event is fired when a popover has been made visible to the user (will wait for CSS transitions to complete). |
beforeHide.cfw.popover | This event is fired immediately when the hide method is called. |
afterHide.cfw.popover | This event is fired when a popover has been hidden from the user (will wait for CSS transitions to complete). |
inserted.cfw.popover | This event is fired after the beforeShow.cfw.popover event when the popover has been added to the DOM. |
dragStart.cfw.popover | This event is fired at the start of the drag action. |
dragEnd.cfw.popover | This event is fired at the end of the drag action. |
beforeUnlink.cfw.popover | This event is fired immediately when the unlink method is called. This event can occur after the beforeHide event if set to automatically unlink, or before if called via method. |
afterUnlink.cfw.popover | This event is fired when a popover item has been unlinked from its trigger item and the data-api removed. This event can occur after the afterHide event when invoked from the unlink method, or before if set to automatically unlink. |
dispose.cfw.popover | This event is fired immediately before the popover item is removed from the DOM. |
$('#myPopover').on('afterHide.cfw.popover', function () {
// do something...
});
Server-side Apps
Popovers are designed to hopefully work with server side applications, such as Apache Wicket, and other instances where the server-side application might need to create or update the popover content after the initial page load.
A quick example:
- An item with an event handler that makes a callback to create a new popover is interacted with.
-
Call as needed:
$('#myPopover').CFW_Popover('hide');
- or
$('#myPopover').CFW_Popover('unlink');
- or
$('#myPopover').CFW_Popover('dispose');
- Update/create the popover object and insert into DOM.
- Initialize the popover:
$('#myPopover').CFW_Popover(options);
with desired options. - Show popover:
$('#myPopover').CFW_Popover('show');
Accessibility
Key Commands
The following key commands are handled when focus is inside the popover:
- Esc - Close the popover
Focus Handling
Popovers have additional focus handling when using keyboard navigation.
If navigating from above the popover's trigger (typically with the tab
key), the trigger becomes focused, the next forward focus will move from the trigger to the first focusable item inside the popover.
If navigating from below the popover's trigger (typically with the shift
-tab
key combination), when the trigger is focused, focus will be moved from the trigger to the last focusable item inside the popover.
When navigating forward, out the bottom of the popover, the focus will be moved to the next focusable item in the document relative to the trigger. This is done so that if the container
option is used, the focus will move to next logical item. Otherwise, when using container: body
, the focus will potentially drop off the end of the HTML document, leaving a keyboard user in an akward situation.
When navigating backward, out the top of the popover, the focus will be moved to the trigger.
This will not necessarily work with some assistive technologies reading modes.