When CSS Layout Order Stops Matching the HTML

Grid and Flexbox can move an element to almost any visual position. They do not necessarily move it in the DOM, keyboard focus order, or screen reader reading order.

That difference becomes a problem when the screen suggests one sequence while the HTML provides another:

Visible: Name → Email → Message → Send
HTML:    Message → Name → Send → Email

The layout looks repaired with CSS. Anyone moving through it in source order gets a different interface.

Make the HTML sensible before layout

A form should begin in its logical interaction order:

<form>
  <label>
    Name
    <input name="name">
  </label>

  <label>
    Email
    <input name="email">
  </label>

  <label>
    Message
    <textarea name="message"></textarea>
  </label>

  <button>Send</button>
</form>

If the stylesheet fails, this still makes sense from top to bottom. That is a useful test of the structure.

Flexbox order moves only the visual box

form {
  display: flex;
  flex-direction: column;
}

button {
  order: -1;
}

The button may now appear first, while keyboard focus still reaches it after the fields. Grid areas can create the same mismatch.

Visual reordering is not always wrong. Rearranging broad, non-sequential layout regions can be harmless. It becomes risky when position communicates reading or interaction order.

Do not use layout to repair bad source order

This card starts with the action before giving it any context:

<article>
  <a href="#">Read more</a>
  <h2>Article title</h2>
  <p>Description.</p>
</article>

CSS can move the link to the bottom, but assistive technology still encounters it first. Put the meaning in order in the HTML:

<article>
  <h2>Article title</h2>
  <p>Description.</p>
  <a href="#">Read more</a>
</article>

The same principle applies across breakpoints. This layout can change from two columns to one without changing its reading sequence:

Desktop:
Image | Text

Mobile:
Image
Text

when the source is already:

<img>
<div class="text">...</div>

If a stylesheet contains a set of repairs like this, revisit the markup:

.a { order: 4; }
.b { order: 1; }
.c { order: 3; }
.d { order: 2; }

Positive tabindex adds another fragile order

Do not try to synchronise the mismatch manually:

<button tabindex="3">...</button>
<input tabindex="1">
<a tabindex="2">...</a>

Positive tabindex values create a separate focus order that becomes difficult to maintain as controls are added or moved. Natural DOM order is much more dependable.

Load the finished page and press Tab. If focus jumps around the screen instead of following what your eyes expect, compare the visual arrangement with the source.

CSS should decide how a sensible document is laid out, not disguise a document whose order is wrong. When visual and HTML order agree, mouse, keyboard, and screen reader users all get the same story.