안녕하세요! 프론트엔드 개발 강사입니다. 이번에 가져오신 문서는 Flexbox(플렉스박스)의 아주 강력하면서도 주의해서 다뤄야 할 기능, 바로 플렉스 아이템의 순서 지정(Ordering flex items)에 대한 내용이네요!
HTML 마크업 순서를 건드리지 않고도 화면에 보이는 순서를 마음대로 섞거나 뒤집을 수 있다니, 정말 매력적이죠? 하지만 이 마법 같은 기능 뒤에는 접근성(Accessibility)이라는 아주 중요한 함정이 숨어있습니다. 실무와 면접에서 단골로 등장하는 이 주제를, 제가 이해하기 쉬운 구어체와 실무 팁을 곁들여 완벽하게 번역 및 해설해 드릴게요. 같이 살펴볼까요? 😊
Flexbox와 Grid 같은 최신 레이아웃 방식들은 콘텐츠의 순서를 제어할 수 있는 기능을 제공합니다. 이 문서에서는 Flexbox를 사용할 때 콘텐츠의 '시각적인 순서(visual order)'를 변경하는 다양한 방법들을 살펴볼 것입니다. 또한, 아이템의 순서를 재배치하는 것이 접근성(accessibility)에 어떤 영향을 미치는지도 함께 고민해 보겠습니다.
flex-direction 속성은 다음 네 가지 값 중 하나를 가질 수 있습니다:
row (가로 방향)column (세로 방향)row-reverse (가로 역방향)column-reverse (세로 역방향)처음 두 값(row, column)은 아이템들을 HTML 문서의 소스 코드에 적힌 순서 그대로 유지하며, 시작선(start line)에서부터 차례대로 표시합니다.


나머지 두 값(row-reverse, column-reverse)은 시작선(start line)과 끝선(end line)의 위치를 서로 맞바꿈으로써 아이템들의 순서를 완전히 뒤집어 버립니다.


여기서 시작선(start line)은 현재 사용 중인 쓰기 모드(writing modes)와 직결된다는 점을 기억하세요. 위에 있는 row 관련 예제들은 영어나 한국어처럼 왼쪽에서 오른쪽으로(LTR) 글을 쓰는 언어에서 row와 row-reverse가 어떻게 작동하는지 보여줍니다. 만약 여러분이 아랍어처럼 오른쪽에서 왼쪽으로(RTL) 읽는 언어로 작업하고 있다면, row는 오른쪽에서 시작하고 row-reverse는 왼쪽에서 시작하게 될 것입니다.

이 기능은 무언가를 역순으로 표시하고 싶을 때 정말 쉽고 편한 방법처럼 보입니다. 하지만 여러분은 이 아이템들이 오직 '시각적으로만(visually)' 역순으로 표시된다는 사실을 절대 잊어선 안 됩니다.
⚠️ 강사의 중요 팁! "시각적 순서 vs 논리적 순서"
화면에 보이는 순서가 바뀌었다고 해서 실제 HTML 뼈대의 순서가 바뀐 것은 아닙니다! 사용자가 키보드의Tab키를 눌러 이동하거나(Tabbing order), 스크린 리더(시각장애인용 화면 낭독기)가 문서를 읽어주는 순서(Speech order)는 여전히 원본 HTML 소스 코드의 순서를 곧이곧대로 따릅니다.
즉, 시각적인 표현만 바뀔 뿐 소스 순서는 그대로 유지되므로, CSS를 해석하지 않는 기기(Siri나 Alexa 같은 음성 비서)나 보조 기술(assistive technology)을 사용하는 사람들에게는 일반 사용자와 완전히 다른 사용자 경험을 제공하게 됩니다. 만약 여러분이 내비게이션 바의 순서를 이 기능으로 뒤집어 놓는다면, 시각적 순서와 키보드 탭 이동 순서가 서로 엇갈리게 되어 키보드 사용자에게 엄청난 인지적 혼란(cognitive confusion)을 줄 수 있습니다.
따라서 reverse 값을 사용하거나 다른 방식으로 아이템을 재배치할 때는, "내가 정말로 HTML 소스의 논리적인 순서 자체를 바꿔야 하는 건 아닌지" 먼저 고민해 보아야 합니다.
플렉스박스 사양서에서도 순서 변경 기능을 HTML 소스의 문제를 덮기 위한 땜빵용으로 쓰지 말라고 강력히 경고하고 있습니다:
"작성자(개발자)는 올바른 소스 순서를 작성하는 것을 귀찮아하여 그 대신
order속성이나flex-flow/flex-direction의*-reverse값들을 대용품으로 사용해서는 절대 안 됩니다(must not). 이는 문서의 접근성을 완전히 망쳐버릴 수 있습니다."
아래의 라이브 예제에서 링크들을 키보드 Tab 키로 차례대로 이동해 보세요. 포커스 된 스타일이 하이라이트되면서, flex-direction으로 플렉스 아이템의 시각적 순서를 바꾸었음에도 불구하고 탭 이동 순서는 여전히 소스 코드의 순서(1 -> 2 -> 3)를 고집스럽게 따라가는 것을 확인할 수 있습니다.
(MDN Playground에서 실행해보기)
<div class="box">
<div><a href="#">One</a></div>
<div><a href="#">Two</a></div>
<div><a href="#">Three</a></div>
</div>
.box > * {
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
padding: 10px;
}
.box > * a:focus {
background-color: yellow;
color: black;
}
.box {
border: 2px dotted rgb(96 139 168);
display: flex;
flex-direction: row-reverse; /* 시각적으로는 Three - Two - One 순으로 보입니다 */
}
flex-direction을 바꾸는 것이 탭 순서를 바꾸지 못하는 것과 마찬가지로, 이 값은 브라우저가 요소를 그리는 순서(paint order) 또한 바꾸지 않습니다. 오직 시각적인 배치만 뒤집을 뿐입니다.
방향을 통째로 뒤집는 것 외에도, order 속성을 사용하면 특정 개별 아이템을 콕 집어서 시각적인 배치 순서를 내 마음대로 바꿀 수 있습니다.
order 속성은 아이템들을 서수 그룹(ordinal groups)으로 나누어 배치하도록 설계되었습니다. 쉽게 말해, 각 아이템에 그들이 속할 그룹 번호(정수)를 꼬리표처럼 붙여주는 겁니다. 그런 다음, 아이템들은 그 정수 값이 가장 작은 것부터 먼저(가장 앞이나 위쪽에) 시각적으로 배치됩니다. 만약 여러 아이템이 똑같은 order 값을 가지고 있다면, 그 그룹 안에서는 원래 HTML 소스에 적힌 순서대로 배치됩니다.
예를 들어, 5개의 플렉스 아이템에 다음과 같이 order 값을 주었다고 가정해 봅시다:
order: 2order: 3order: 1order: 3order: 1이 아이템들은 화면에서 다음과 같은 순서로 그려집니다:
order: 1 (가장 낮음, 소스에서 먼저 옴)order: 1 (가장 낮음, 소스에서 나중에 옴)order: 2order: 3 (동률, 소스에서 먼저 옴)order: 3 (동률, 소스에서 나중에 옴)
👨🏫 강사의 실무 팁! "order의 기본값은 0입니다"
따로order를 주지 않은 모든 플렉스 아이템은 기본적으로order: 0을 가집니다. 따라서 특정 아이템 하나만 맨 끝으로 보내고 싶다면 그 아이템에order: 1을 주면 되고, 특정 아이템 하나만 맨 앞으로 보내고 싶다면order: -1을 주면 아주 간단하게 해결됩니다!
아래 라이브 예제에서 값들을 직접 가지고 놀아보며 순서가 어떻게 변하는지 확인해 보세요. 또한, flex-direction을 row-reverse로 바꿔보면 어떤 일이 일어나는지도 확인해 보세요. (시작선이 반대쪽으로 바뀌기 때문에, 정렬 순서도 반대편에서부터 시작하게 됩니다.)
(MDN Playground에서 실행해보기 (Play))
<div class="box">
<div><a href="#">1</a></div>
<div><a href="#">2</a></div>
<div><a href="#">3</a></div>
<div><a href="#">4</a></div>
<div><a href="#">5</a></div>
</div>
.box > * {
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
padding: 10px;
}
.box {
border: 2px dotted rgb(96 139 168);
display: flex;
flex-direction: row;
}
.box :nth-child(1) {
order: 2;
}
.box :nth-child(2) {
order: 3;
}
.box :nth-child(3) {
order: 1;
}
.box :nth-child(4) {
order: 3;
}
.box :nth-child(5) {
order: 1;
}
플렉스 아이템의 기본 order 값은 0입니다. 따라서 0보다 큰 정수 값을 부여받은 아이템은, order 값이 명시적으로 지정되지 않은(즉, 0인) 아이템들보다 항상 뒤쪽에 표시됩니다.
order 속성에는 음수(negative values)도 사용할 수 있는데, 이게 꽤나 유용합니다. 만약 다른 아이템들의 순서는 그대로 둔 채 딱 하나의 아이템만 맨 앞으로 빼오고 싶다면, 그 아이템에 order: -1을 주면 됩니다. 이 값은 기본값인 0보다 작기 때문에 해당 아이템은 무조건 가장 먼저 표시됩니다.
아래 코드 예제에서는 플렉스박스로 아이템들이 배치되어 있습니다. HTML에서 어느 아이템에 active 클래스를 주느냐에 따라 그 아이템이 가장 먼저(맨 위에) 표시되고, 컨테이너의 전체 너비를 꽉 채우게(flex: 1 0 100%) 되며 나머지 아이템들은 그 아래에 배치되도록 만들었습니다.
(MDN Playground에서 실행해보기 (Play))
<div class="box">
<div><a href="#">1</a></div>
<div><a href="#">2</a></div>
<div class="active"><a href="#">3</a></div> <div><a href="#">4</a></div>
<div><a href="#">5</a></div>
</div>
* {
box-sizing: border-box;
}
.box > * {
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
padding: 10px;
}
.box {
width: 500px;
border: 2px dotted rgb(96 139 168);
display: flex;
flex-wrap: wrap;
flex-direction: row;
}
.active {
order: -1; /* 무조건 1등으로 만듭니다 */
flex: 1 0 100%; /* 혼자 한 줄을 다 차지하게 만듭니다 */
}
아이템들은 '순서가 수정된 문서 순서(order-modified document order)'로 렌더링 됩니다. 즉, 아이템이 화면에 그려지기 직전에 order 속성의 값을 먼저 계산한다는 뜻이죠.
또한 order 속성은 아이템이 화면에 그려지는 순서(paint order) 자체를 바꿉니다. order 값이 낮은 아이템이 가장 먼저 그려지고, order 값이 높은 아이템이 나중에 그 위에 덧그려지게 됩니다. (이는 Z-index처럼 겹침이 발생할 때 영향을 줄 수 있습니다.)
order 속성을 사용하는 것은 앞서 살펴본 flex-direction을 변경하는 것과 똑같은 접근성(accessibility) 문제를 발생시킵니다. order를 사용하면 아이템이 그려지는 순서와 시각적으로 보이는 순서는 바뀌지만, 키보드를 이용한 순차적인 탐색 순서(Tab 키 이동 순서)는 전혀 바뀌지 않습니다. 따라서 사용자가 키보드의 Tab 키를 이용해 페이지를 탐색할 경우, 포커스가 화면 여기저기를 예측 불가능하게 점프하면서 이동하게 되어 극심한 혼란을 겪을 수 있습니다.
이 페이지에 있는 라이브 예제들 위에서 Tab 키를 직접 눌러보시면, 마우스와 같은 포인팅 장치를 쓰지 않는 사용자에게 order 속성이 얼마나 이상하고 혼란스러운 경험을 만들어내는지 체감하실 수 있을 겁니다. 시각적 순서와 논리적 순서의 이러한 단절, 그리고 이것이 접근성에 미치는 잠재적 문제들에 대해 더 깊이 알고 싶다면 아래의 자료들을 읽어보시길 권장합니다.
접근성 이슈가 무시무시하긴 하지만, 논리적 순서(읽는 순서)와 시각적 순서를 분리하는 것이 오히려 크게 도움이 되는 특정한 활용 사례(Use cases)들이 분명히 존재합니다. 주의 깊게 잘 사용하기만 한다면 order 속성은 몇 가지 아주 유용한 디자인 패턴을 정말 쉽게 구현할 수 있게 해줍니다.
예를 들어, 뉴스 기사를 보여주는 '카드(Card)' UI를 디자인한다고 해봅시다. 뉴스 기사에서 가장 중요한, 강조되어야 할 요소는 단연 제목(heading)입니다. 스크린 리더 사용자나 키보드 사용자가 제목들 사이를 탭(tab)하며 자신이 읽고 싶은 기사를 찾을 때 가장 먼저 접근해야 하는 요소이기도 하죠. 하지만 카드 디자인에는 날짜(date)도 포함되어야 합니다. 우리가 만들고자 하는 완성된 디자인은 시각적으로 아래와 같은 모습입니다.

눈으로 보기에는(시각적으로는) 날짜가 제목 위쪽에 나타납니다. 하지만 만약 화면 낭독기(Screen Reader)가 이 카드를 읽어준다면, 날짜보다는 제목이 먼저 음성으로 출력되고 그다음 출판일이 읽히는 것이 이치에 맞을 것입니다. 우리는 order 속성을 활용해 이 두 마리 토끼를 모두 잡을 수 있습니다!
카드를 플렉스 컨테이너(display: flex)로 만들고 flex-direction을 column(세로 방향)으로 설정합니다. 그리고 소스 코드상으로는 제목 뒤에 있는 날짜 요소에 order: -1을 주어, 시각적으로만 제목 위로 끌어올리는 것입니다.
(MDN Playground에서 실행해보기 (Play))
<div class="wrapper">
<div class="card">
<h3>News item title</h3> <div class="date">1 Nov 2017</div>
<p>This is the content of my news item. Very newsworthy.</p>
</div>
<div class="card">
<h3>Another title</h3>
<div class="date">6 Nov 2017</div>
<p>This is the content of my news item. Very newsworthy.</p>
</div>
</div>
body {
font-family: sans-serif;
}
.wrapper {
display: flex;
flex: 1 1 200px;
gap: 1em;
}
.card {
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
padding: 1em;
display: flex;
flex-direction: column;
}
.date {
order: -1; /* 시각적으로만 날짜를 맨 위로 올립니다! */
text-align: right;
}
이처럼 작고 디테일한 시각적 조정이 바로 order 속성이 진가를 발휘하는 완벽한 사례입니다. 문서의 읽기 순서 및 탭 이동 순서와 동일하게 논리적 구조(HTML)를 유지하여 가장 접근성 좋고 탄탄한 구조를 만드세요. 그런 다음, 오로지 시각적인 디자인 조정을 위해서만 order를 양념처럼 활용하세요. 단, 키보드 포커스를 받는 상호작용 요소(링크나 버튼 등)의 순서는 절대로 재배치하지 마세요.
마지막으로 당부드리고 싶은 것은, 마우스나 터치스크린이 아닌 오직 키보드만을 사용해서 여러분이 만든 콘텐츠를 테스트해보는 습관을 들이라는 것입니다. 탭 키를 연타하며 화면을 누벼보세요. 이 테스트를 통해 여러분의 개발 방식이 키보드 사용자의 내비게이션 경험을 지나치게 복잡하고 어렵게 만들고 있는 건 아닌지 금방 알아차릴 수 있을 것입니다.
이 페이지가 도움이 되셨나요? [네 (Yes)] / [아니요 (No)]
기여하는 방법 알아보기 (Learn how to contribute)
이 페이지는 2025년 11월 7일에 MDN 기여자들 (MDN contributors)에 의해 마지막으로 수정되었습니다.