PositionCalculator

The slim highly flexible jQuery plugin to calculate element's position and overflow.

by Tobias Lindig
View on GitHub * Download minified version * Download uncompressed version

Overview

PositionCalculator calculate the position of an element relative to another element or event. It has also functionality to handle collision within the viewport of a given container.

This plugin will not manipulate any CSS settings or DOM-trees, it only calculate values. To be more exact, it calculates the difference of current position to target position and the overflow over boundary. Thus you are all paths open to implement the positioning according to your requirements. You can apply the new position by using top and left or using the css3 transform function or by setting margin. It is up to you.

It is also possible to use the result of PositionCalculator as input for additional calculation.

With PositionCalculator it is absolute easy to implements an "inView" functionality. Take a look to the "Examples" section below.

PositionCalculator takes away the complicated calculation taking account of preferred orientation, reference points and boundary.

With PositionCalculator it is more easy to implement components like tooltip, popover, popup, sticky navigation, dynamic placed toolbars and so on. You don't need waste your time with implementing calculation for positioning a item near by a target element and for collision handling. Just use the PositionCalculator.

Live Demo

Try out all the options and see the result instantly. All options are described in a table in section below.

Below you can see a yellow square. That is the item that will be positioned.

To see the collision handling live (flip and stick) you can check the checkbox in the green rectangle and move it with the mouse. The colored triangle shows the initial chosen reference point from item and target (itemAt, targetAt).

Configuration

Elements

idem: yellow box (100x100)
target:
boundary:

Placement

Initial placement of reference point.
The colored triangle shows your decision.

itemAt (-> red):
itemOffset (px|%):
targetAt (-> blue):
targetOffset (px|%):

Behavior

Collision handling strategy.

Prevent overflow of boundary. Select the edge where item shall stick on.

stick:

Flip reference point from target, from item or from both.

flip:

Showcase

Container

item
being positioned
target, drag me!
item follow me
(option 'target' -> "green box")

Live Results

Return value of .calculate():


            

Properties, read from DOM:

item top:
target top:
difference y:
item left:
target left:
difference x:

Options

Name type default description
item selector | jQuery | DOM node null

Required. Given value will be called with jQuery(item) and should match a element.

item reference the element being positioned.

target selector | jQuery | DOM node | null null

target reference the element align the positioned item against.

"selector" means a string with a CSS selector. The value can also be a DOM element or a jQuery wrapped DOM element.

If no element match or null is given, option "flip", "itemAt" and "targetAt" will be ignored. But option "stick" still work and overflow will be calculated for a given "boundary".

boundary selector | jQuery | DOM node | null window

boundary reference the element that constraints the position of item. It is used to detect overflow. See option "flip" and "stick".

"selector" means a string with a CSS selector. The value can also be a DOM element or a jQuery wrapped DOM element.

If no element match, overflow will not calculated.

itemAt string "top left"

Placement of reference point on the item

Space separated combination of top | middle | bottom and left | center | right.

targetAt string "top left"

Placement of reference point on the target

Space separated combination of top | middle | bottom and left | center | right.

itemOffset Object { y:0, x:0, mirror:true }

Additional offset for position of specified reference point from item.

Properties:
y: string or number with vertical offset in pixel or percent. Can be negative.
x: string or number with horizontal offset in pixel or percent. Can be negative.
mirror: boolean specify, if the x and y values shall be negated in case of flipping.

targetOffset Object { y:0, x:0, mirror:true }

Additional offset for position of specified reference point from target.

Properties:
y: string or number with vertical offset in pixel or percent. Can be negative.
x: string or number with horizontal offset in pixel or percent. Can be negative.
mirror: boolean specify, if the x and y values shall be negated in case of flipping.

flip string | boolean 'both'

Specify the strategy to prevent that item overflows the boundary.

Allowed as value is:
"item" - Only change the itemAt
"target" - Only change the targetAt
"both"|true - Change both the itemAt and targetAt at the same time (to 'flip' the item to the other side of the target).
"none"|false - Don't flip

stick string | boolean 'all'

Will keep the item within it's boundary by sticking it to the edges that normally would overflow.

Specify sides you'd like to control (space separated top, bottom, left and right) or "none"|false or "all"|true.

API

PositionCalculator is a JavaScript class added to the jQuery object. It can be instantiated by calling the constructor.

Constructor

PositionCalculator(options)

Create and initializes a new instance of PositionCalculator. Options are described in section "Options".

var myCalculator = new jQuery.PositionCalculator({ item: '#idItem', target:'#idTarget' });

Methods

All methods of PositionCalculator return the instance itself to allow chaining, except the method shall explicit return special value.

.calculate()

Calculate the distance between reference point of item and reference point of target and handle overflow in the specified matter.

Current position of elements (item, target, boundary) will be read from DOM.

Return a CalculationResult object.

var result = myCalculator.calculate();

.calcVariant(item_at, target_at)

Exported helper method. Calculate the resulting position only for the given placement. That will not handle flip and fit. Current position of elements (item, target, boundary) will be read from DOM.

Arguments item_at and target_at have to be an object with string property x and y. Allowed values for x are "left", "center" or "right". Allowed values for y are "top", "middle" or "bottom".

Return a CalculationResult object.

var result = myCalculator.calcVariant();

.resize()

Update intern stored values depending on size and position of elements (item, target, boundary). Should be called if dimensions of an element changed.

Return this instance itself to allow chaining.

myCalculator.resize();

Result Object: CalculationResult

Name type example description
moveBy Object { y:10, x:-20 }

Calculated distance between resulting reference points of target and item as pixel values.

Properties:
y: number with vertical distance. Can be negative.
x: number with horizontal distance. Can be negative.

itemAt string "top left"

Resulting placement of reference point on the item

Space separated combination of top | middle | bottom and left | center | right.

targetAt string "top left"

Resulting placement of reference point on the target

Space separated combination of top | middle | bottom and left | center | right.

distance {null|Object}
{
  top:51,
  left:22,
  bottom:171,
  right:375,
  overflow: ["top", "left"]
}

Calculated distance of item to the viewport of boundary.

Properties:
top: number pixel value with distance to top edge of boundary. Overflow is positive value.
left: number pixel value with distance to left edge of boundary. Overflow is positive value.
bottom: number pixel value with distance to bottom edge of boundary. Overflow is negative value.
right: number pixel value with distance to right edge of boundary. Overflow is negative value.
overflow: string Array with edges that has overflow (top, bottom, left and right) or null for no collision.

Events

PositionCalculator do not trigger events.

Examples

Tooltip, popup, popover

All this components want show an additional element (item) at a special target position. And may be you want also ensure that the new item is shown without clipping by the viewport.

The new position will be given to you by the PositionCalculator, you have only to set the css properties.

Example: Simple tooltip

Example: Simple tooltip with PositionCalculator

Example: Dynamic popup

Example: Dynamic popup with PositionCalculator

inView

In this example, PositionCalculator is used to figure out if an element is shown in viewport. If so, a special class will be added.

Example: inView

Example: inView with PositionCalculator

Bootstrap Dropdown with auto position

In this example, PositionCalculator is used to add auto position feature to the dropdown menu from Bootstrap.

The first dropdown, has the default behavior of dropdown from bootstrap, but the second, got the add a auto flipping feature.

Example: Bootstrap dropdown

Example: Bootstrap dropdown with PositionCalculator