Reordering DOM Elements on Mobile with CSS order
TLDR: Three elements (center header, sheet tab bar, table body) share a flex column container. On desktop they are in DOM order. On mobile, CSS order: 1/2/3 reorders them visually so the tab bar sits between the header and the table, making it reachable above the fold.
Repo: tools/table-formatter
The Problem
The TAFNE layout has three stacked sections: a center header, a sheet tab bar, and the table content area. On desktop, the tab bar sits below the header and above the table. That is also the DOM order.
On mobile, the table content area pushes the tab bar below the fold. Users had to scroll down past the table to reach the sheet tabs. Switching sheets required a two-finger scroll past potentially 50+ rows of table data.
Why Not Change the DOM Order
The simplest fix would be reordering the HTML so the tab bar comes before the table in the DOM. That creates two problems:
First, JavaScript that traverses the DOM to find "the element after the header" breaks. There were three places in the codebase that expected DOM order to match visual order.
Second, the desktop layout then requires CSS to push the tab bar below the header, which is where it already sits in DOM order. This is circular.
Changing DOM order to fix mobile means adding compensating CSS for desktop. CSS order does this cleanly without touching the DOM.
The Fix
The three elements live inside a flex column container. On mobile, assign explicit order values:
@media (max-width: 767px) {
.tafne-center-header { order: 1; }
.tafne-sheet-tab-bar { order: 2; }
.tafne-table-body { order: 3; }
}
On desktop, no order values are set. Elements render in DOM order. On mobile, the tab bar (order 2) renders between the header (order 1) and the table (order 3), regardless of its actual position in the HTML.
The DOM order stays:
<div class="tafne-main flex-col">
<div class="tafne-center-header">...</div>
<div class="tafne-table-body">...</div> <!-- DOM second -->
<div class="tafne-sheet-tab-bar">...</div> <!-- DOM third -->
</div>
JavaScript that depends on DOM order still finds the table body at its original position. Only the visual rendering changes.
What CSS order Does
CSS order is a flex or grid property. It affects the visual rendering order of flex/grid children without affecting:
- DOM traversal order (
nextSibling,children[N]) - Tab key focus order (follows DOM order, not visual order)
- Screen reader reading order (follows DOM order)
- JavaScript
querySelectorresults
If tab order and screen reader order also need to change, use the tabindex attribute alongside order. TAFNE's sheet tabs are mouse/touch-primary, so DOM-order tab focus is acceptable.
Tradeoffs
Tab focus order still follows DOM order. A keyboard user tabbing through the interface will reach the table body before the sheet tab bar, even though the sheet tab bar appears above the table visually. This is a known tradeoff for using order without adjusting tabindex.
order only works inside flex or grid containers. The parent must have display: flex or display: grid. Adding order to a child of a block container has no effect.
Three elements, three order values. If a fourth element is inserted later, its order value must be set explicitly or it defaults to 0, which sorts it before everything else. Always check the full sibling set when adding order to a flex container.