CSS Global Order

CSS Global Order is a JavaScript library that implements support for visual reordering of HTML elements with the standard order CSS-property without need for turning-on Flexbox mechanism (display: flex / display: inline-flex) for their parent element.

The library works in all Flexbox-capable browsers (including older browsers that support its draft versions with prefixes) and Internet Explorer 7+.

API

The library is available as the CSSGlobalOrder object that has two methods:

processChildren(parent)
Reorders direct child elements of the specified element.
process([scope])
Reorders elements inside the specified element.

Both methods take an element, an array of elements, or a selector as argument. If the argument is an array or a selector, then the call is equivalent to consequent calls of the same method for all items contained in the array or elements that match the selector respectively.

For the process() method, the argument is optional: if the argument is not specified, then all elements of the HTML document are processed.

Selector as argument is only supported in browsers that support the querySelectorAll() method (all modern browsers and IE8+).

Examples

When calling methods, those elements are processed which are available at the moment of calling. It’s recommended to call methods on the DOMContentLoaded event:

document.addEventListener('DOMContentLoaded', function() {
    CSSGlobalOrder.processChildren('.foo, .bar');
}, false);

or, for example, in the similarly-working ready handler for the document with jQuery:

$(document).ready(function() {
    CSSGlobalOrder.processChildren('.foo, .bar');
});

Examples of calling methods with arguments of all supported types:

CSSGlobalOrder.processChildren('.foo, .bar') /* selector */;
CSSGlobalOrder.processChildren(document.getElementById('demo')); /* element */
CSSGlobalOrder.processChildren([a, b, c]); /* array of elements */

CSSGlobalOrder.process('#lorem > .ipsum'); /* selector */
CSSGlobalOrder.process(document.getElementsByTagName('main')[0]); /* element */
CSSGlobalOrder.process([a, b, c]); /* array of elements */
CSSGlobalOrder.process(); /* no argument: all elements are processed */

Text nodes

Besides elements that are subject to be reordered, text nodes are allowed, value of their order CSS-property is assumed equal to zero (consistently with the default value for elements).

Flex containers

Child elements of Flex containers are not affected by reordering since their reordering is supported on pure-CSS level, so emulation is unneeded in such cases. An element is considered Flex container if it has the display CSS-property with one of the following values:

  • flex,
  • inline-flex,
  • -webkit-flex,
  • -webkit-inline-flex,
  • -ms-flexbox,
  • -ms-inline-flexbox,
  • -moz-box,
  • -moz-inline-box,
  • -webkit-box,
  • -webkit-inline-box.

Old versions of Firefox and WebKit

When it’s needed to support old versions of Firefox (19 and older) and browsers based on WebKit engine of old versions (Safari 8 and older), besides the standard order CSS-property, prefixed nonstandard properties -moz-box-ordinal-group, -webkit-box-ordinal-group and -webkit-order should additionally be specified, all having the same value:

.example {
       -moz-box-ordinal-group: 3;
    -webkit-box-ordinal-group: 3;
    -webkit-order: 3;
            order: 3;
}

Caution: in the original version of Flexbox speficication of 2009, the box-ordinal-group property did not allow negative values. So when needed to support corresponding old browser versions, only zero and positive values of the order property and its prefixed variants should be used.

Performance

In general, in terms of performance, precedence of ways to use the library is following (in order of decreasing performance):

  1. processChildren(parent);
  2. process(scope);
  3. process().

This is because selecting elements that have the order CSS-property is done by traversing all elements and checking value of the order property for each of them since at the time of writing the library, there is no a standard way to quickly select elements by value ofa CSS property (like querySelectorAll() for selecting by selector).

Accordingly, in the first case, only child nodes of the specified element are traversed; in the second case, it’s all descendants of the specified element; in the third case, it’s all elements of the document.