An illustration with the text: Such a flex Such a flex

Flex Reverse


When I started learning CSS, I stumbled across the property flex-direction: row-reverse and wondered when would you ever use that. Some argue that you can use it for languages that are read from right to left. I think that is not necessarily a good approach, as browsers can handle that for you with the dir attribute.

So when would you want to reverse the rendered order of your flex items, but not the order in the source code?

The Problem

Imagine you have a multistep form with next and previous buttons:

Is the ocean blue?(2 / 4)

Multi-Step-Form simplified code
function MultiStepForm() {
	
  return (
    <form onSubmit={/*...*/}>
      <p>Is the ocean blue?</p>
      
      <input
        type="radio"
        name="question2"
        value="Yes"
      />
      <label>Yes</label>
      
      <input
        type="radio"
        name="question2"
        value="No"
      />
      <label>No</label>
      
      <div className="flex justify-between">
        <button type="button">Previous</button>
        
        <button type="submit">Next</button>
      </div>
    </form>
  );
}

If you are using the Tab key (or a screen-reader) to navigate through the form, you will notice that you’ll focus the Previous button before the Next button, because they are defined in that order in the source code.

Form with buttons displayed with the flex-direction: row property

Form with flex-direction: row buttons

However, while it makes sense from a continuity flow to have the previous button on the left and the next button on the right, it doesn’t make sense for keyboard navigation. When you Tab after you choose an option, you most likely want to go to the next step, not the previous one:

Form with buttons displayed with the flex-direction: row property

Form with improved keyboard navigation

The Solution

This is where flex-direction: row-reverse comes into play. By defining the buttons in the order:

  1. next
  2. previous

and then reversing the order with said property, we’ll keep the continuity flow but also allow the next button to be focused first after choosing an option. Et voilà:

Is the ocean blue?(2 / 4)

Multi-Step-Form simplified code
function MultiStepForm() {
	
  return (
    <form onSubmit={/*...*/}>
      <p>Is the ocean blue?</p>
      
      <input
        type="radio"
        name="question2"
        value="Yes"
      />
      <label>Yes</label>
      
      <input
        type="radio"
        name="question2"
        value="No"
      />
      <label>No</label>
      
      <div className="flex justify-between flex-row-reverse">
        <button type="submit">Next</button>
        
        <button type="button">Previous</button>
      </div>
    </form>
  );
}

Form with flex-direction: row-reverse buttons