OOUI/Concepts

Certain core ideas or similar configuration options are shared by various elements/widgets that are not directly related. This page documents some of them.

Overlays

edit

Elements of certain widgets are positioned outside of normal flow, "on top of" everything else on the page, their dimensions constrained only by the browser viewport – for example, PopupButtonWidget's popup, or DropdownWidget's menu.

 

 

However, limitations of CSS occasionally prevent this. For example:

  • If the widget is placed inside a stacking context (other than the root one), created e.g. by using the z-index property, it is not possible to display the popup "on top of" content outside of that stacking context.
  • If the widget is placed inside a scrollable area, created by using the overflow property, it is not possible for the popup to extend outside of its dimensions.
    • Special case: if the widget is placed inside an OOUI dialog.

To avoid this, you can specify an "overlay" (using the $overlay configuration option), inside of which the popup will be placed (instead of being inside of the widget). The overlay is a DOM element that should be outside of the affected area, allowing its contents to be positioned in the desired way.

In most cases, the overlay should be an element that is a direct child of the ‎<body>. (Using the body itself is also supported, but not recommended as it makes it harder to keep track of what inserted the popups there.) You can pass true to automatically create such an element via OO.ui.getDefaultOverlay(). For elements inside dialogs, you should use the dialog's this.$overlay property.

Widgets and other elements supporting the $overlay configuration option include:

  • PopupButtonWidget
  • LookupElement
  • CapsuleMultiselectWidget
  • ComboBoxInputWidget
  • DropdownWidget
  • FieldLayout
  • FieldsetLayout

Example

edit

In this example, two nearly identical popup buttons are placed inside a dialog. The only difference is specifying an overlay or not. (Refer to OOUI/Windows/Dialogs and OOUI/Widgets/Buttons and Switches#Popup buttons for more details about the boilerplate code.)

 

function MyDialog( config ) {
	MyDialog.super.call( this, config );
}

OO.inheritClass( MyDialog, OO.ui.Dialog );
MyDialog.static.name = 'myDialog';
MyDialog.static.title = 'Simple dialog';

MyDialog.prototype.initialize = function () {
	MyDialog.super.prototype.initialize.call( this );

	var popupButton1 = new OO.ui.PopupButtonWidget( {
			label: 'Popup button (without $overlay)',
			popup: {
				$content: $( '<p>Popup contents.</p><p>Popup contents.</p><p>Popup contents.</p>' ),
				padded: true
			}
		} ),
		popupButton2 = new OO.ui.PopupButtonWidget( {
			$overlay: this.$overlay,
			label: 'Popup button (with $overlay)',
			popup: {
				$content: $( '<p>Popup contents.</p><p>Popup contents.</p><p>Popup contents.</p>' ),
				padded: true
			}
		} ),

		panel = new OO.ui.PanelLayout( {
			padded: true,
			expanded: false
		} );

	panel.$element.append( popupButton1.$element, popupButton2.$element );
	this.$body.append( panel.$element );
};

MyDialog.prototype.getBodyHeight = function () {
	return 100;
};

var windowManager = new OO.ui.WindowManager();
$( document.body ).append( windowManager.$element );
windowManager.addWindows( [ new MyDialog() ] );
windowManager.openWindow( 'myDialog' );

The first button's popup can't extend outside of the dialog's dimensions, only a small part of it is displayed and it requires scrolling to see the entire contents. The second button's popup can, and is displayed fully.