docs: function positionElements(hostElem, targetElem, placement, appendToBody) {
  
  	// need to read from prop to support tests.
  	const targetWidth = isDefined(targetElem.offsetWidth) ? targetElem.offsetWidth : targetElem.prop('offsetWidth');
  	const targetHeight = isDefined(targetElem.offsetHeight) ? targetElem.offsetHeight : targetElem.prop('offsetHeight');
  
  	placement = parsePlacement(placement);
  
  	const hostElemPos = appendToBody ? offset(hostElem) : position(hostElem);
  	const targetElemPos = {top: 0, left: 0, placement: ''};
  
  	if (placement[2]) {
  		const viewportOffset = getViewportOffset(hostElem, appendToBody);
  
  		const targetElemStyle = window.getComputedStyle(targetElem);
  		const adjustedSize = {
  			width: targetWidth + Math.round(Math.abs(parseStyle(targetElemStyle.marginLeft) + parseStyle(targetElemStyle.marginRight))),
  			height: targetHeight + Math.round(Math.abs(parseStyle(targetElemStyle.marginTop) + parseStyle(targetElemStyle.marginBottom)))
  		};
  
  		placement[1] = placement[1] === 'top' && adjustedSize.height - hostElemPos.height > viewportOffset.bottom && adjustedSize.height - hostElemPos.height <= viewportOffset.top
  			? 'bottom' : placement[1] === 'bottom' && adjustedSize.height - hostElemPos.height > viewportOffset.top && adjustedSize.height - hostElemPos.height <= viewportOffset.bottom
  			? 'top' : placement[1] === 'left' && adjustedSize.width - hostElemPos.width > viewportOffset.right && adjustedSize.width - hostElemPos.width <= viewportOffset.left
  			? 'right' : placement[1] === 'right' && adjustedSize.width - hostElemPos.width > viewportOffset.left && adjustedSize.width - hostElemPos.width <= viewportOffset.right
  			? 'left' : placement[1];
  
  		placement[0] = placement[0] === 'top' && adjustedSize.height > viewportOffset.top && adjustedSize.height <= viewportOffset.bottom
  			? 'bottom' : placement[0] === 'bottom' && adjustedSize.height > viewportOffset.bottom && adjustedSize.height <= viewportOffset.top
  			? 'top' : placement[0] === 'left' && adjustedSize.width > viewportOffset.left && adjustedSize.width <= viewportOffset.right
  			? 'right' : placement[0] === 'right' && adjustedSize.width > viewportOffset.right && adjustedSize.width <= viewportOffset.left
  			? 'left' : placement[0];
  
  		if (placement[1] === 'center') {
  			if (PLACEMENT_REGEX.vertical.test(placement[0])) {
  				const xOverflow = hostElemPos.width / 2 - targetWidth / 2;
  				if (viewportOffset.left + xOverflow < 0 && adjustedSize.width - hostElemPos.width <= viewportOffset.right) {
  					placement[1] = 'left';
  				} else if (viewportOffset.right + xOverflow < 0 && adjustedSize.width - hostElemPos.width <= viewportOffset.left) {
  					placement[1] = 'right';
  				}
  			} else {
  				const yOverflow = hostElemPos.height / 2 - adjustedSize.height / 2;
  				if (viewportOffset.top + yOverflow < 0 && adjustedSize.height - hostElemPos.height <= viewportOffset.bottom) {
  					placement[1] = 'top';
  				} else if (viewportOffset.bottom + yOverflow < 0 && adjustedSize.height - hostElemPos.height <= viewportOffset.top) {
  					placement[1] = 'bottom';
  				}
  			}
  		}
  	}
  
  	switch (placement[0]) {
  		case 'top':
  			targetElemPos.top = hostElemPos.top - targetHeight;
  			break;
  		case 'bottom':
  			targetElemPos.top = hostElemPos.top + hostElemPos.height;
  			break;
  		case 'left':
  			targetElemPos.left = hostElemPos.left - targetWidth;
  			break;
  		case 'right':
  			targetElemPos.left = hostElemPos.left + hostElemPos.width;
  			break;
  	}
  
  	switch (placement[1]) {
  		case 'top':
  			targetElemPos.top = hostElemPos.top;
  			break;
  		case 'bottom':
  			targetElemPos.top = hostElemPos.top + hostElemPos.height - targetHeight;
  			break;
  		case 'left':
  			targetElemPos.left = hostElemPos.left;
  			break;
  		case 'right':
  			targetElemPos.left = hostElemPos.left + hostElemPos.width - targetWidth;
  			break;
  		case 'center':
  			if (PLACEMENT_REGEX.vertical.test(placement[0])) {
  				targetElemPos.left = hostElemPos.left + hostElemPos.width / 2 - targetWidth / 2;
  			} else {
  				targetElemPos.top = hostElemPos.top + hostElemPos.height / 2 - targetHeight / 2;
  			}
  			break;
  	}
  
  	targetElemPos.top = Math.round(targetElemPos.top);
  	targetElemPos.left = Math.round(targetElemPos.left);
  	targetElemPos.placement = placement[1] === 'center' ? placement[0] : placement[0] + '-' + placement[1];
  
  	return targetElemPos;
  }