Grid layout/Grid layout and accessibility

김동현·2026년 3월 21일

mdn 학습 번역 - CSS

목록 보기
109/190

안녕하세요! 프론트엔드 개발자 양성 과정 강사입니다. CSS Grid 레이아웃을 공부하면서 접근성(Accessibility, a11y)까지 챙기시려는 모습이 정말 훌륭합니다! 현업에서 시니어 개발자로 성장하기 위해 반드시 갖춰야 할 시각이 바로 이 '접근성'이거든요.

요청하신 대로 MDN 공식 문서의 내용을 하나도 빠짐없이, 이해하기 쉬운 구어체로 꼼꼼하게 번역해 드릴게요. 중간중간 실무 경험을 곁들인 보충 설명과 팁도 팍팍 넣어두었으니 천천히 따라와 주세요!


그리드 레이아웃과 접근성 (Grid layout and accessibility)

HTML은 웹사이트의 콘텐츠 계층(content layer)으로, 의미론적(semantic)이고 구조가 잘 짜여진 문서를 만드는 역할을 합니다. 반면 CSS는 표현 계층(presentation layer)이죠. 우리는 CSS를 적용하여 우리가 원하는 형태로 콘텐츠의 레이아웃을 만들어냅니다. 특히 2차원의 그리드(격자) 구조는 CSS 그리드 레이아웃(CSS grid layout)을 사용하여 정의할 수 있습니다.

현대의 HTML과 CSS는 처음부터 의미론적이고 접근성이 뛰어난 콘텐츠와 디자인을 만들 수 있도록 설계되어 있습니다. 하지만, 아이러니하게도 그리드를 사용하면서 오히려 접근성 문제를 만들어내는 경우도 발생할 수 있습니다. 이 문서에서는 그리드를 사용할 때 발생할 수 있는 잠재적인 문제점들을 살펴보고, 이를 어떻게 피할 수 있는지 알아볼 것입니다.

💡 강사의 팁:
여기서 '접근성(Accessibility)'이란, 시각 장애를 가진 분들이 사용하는 스크린 리더(Screen Reader) 프로그램이나, 마우스 대신 키보드(Tab 키 등)만으로 웹사이트를 탐색하는 사용자들을 모두 배려하여 웹을 만드는 것을 의미합니다. 화면에 보이는 것이 다가 아니라는 점을 항상 기억해야 해요!

CSS 그리드 레이아웃에서 콘텐츠 재배치하기 (Re-ordering content in CSS grid layout)

이전 가이드들을 통해 우리는 CSS 그리드 레이아웃이 화면의 콘텐츠 순서를 아주 쉽게 재배치할 수 있는 강력한 기능을 제공한다는 것을 배웠습니다. 그리드 템플릿 영역의 라인 기반 배치를 사용하면, HTML 소스 코드 상의 요소 위치를 전혀 고려하지 않고도 아이템들을 원하는 곳에 자유롭게 배치할 수 있죠.

또한, 아이템들의 자동 배치 순서를 바꿀 수 있는 order 속성도 있고, DOM(HTML 문서) 순서와 상관없이 시각적으로 빈 공간을 빽빽하게 채워주는 grid-auto-flow 속성의 dense 값도 있습니다.

하지만 CSS 그리드 레이아웃 공식 명세서(Specification)에는 재배치와 접근성(Reordering and Accessibility)이라는 섹션이 별도로 존재합니다. 이 섹션의 도입부에서는 그리드 레이아웃을 사용해 시각적으로 순서를 재배치했을 때 브라우저가 어떻게 동작해야 하는지 아주 상세히 설명하고 있습니다. 명세서의 내용을 살펴볼까요?

"그리드 레이아웃은 작성자(개발자)에게 문서를 재배치할 수 있는 엄청난 능력을 부여합니다. 하지만, 이것이 문서 소스(HTML)의 올바른 순서를 대체할 수는 없습니다. order 속성과 그리드 배치는 음성(스크린 리더 등)과 같은 비시각적 미디어의 읽기 순서에는 아무런 영향을 주지 않습니다. 마찬가지로, 시각적으로 그리드 아이템을 재배치한다고 해서 순차적인 내비게이션 모드(예: tabindex를 통한 링크 이동 등)의 기본 이동 순서가 바뀌지는 않습니다."

이 말은 즉, 여러분이 그리드 레이아웃을 사용해 화면에 보이는 순서를 마음대로 바꾼다고 하더라도, 스크린 리더나 텍스트를 음성으로 변환해 주는 기기가 콘텐츠를 읽는 순서는 절대 바뀌지 않는다는 것을 의미합니다.

게다가, 키보드의 탭(Tab) 키를 이용한 이동 순서(Tab order)도 바뀌지 않습니다. 키보드로 웹사이트를 탐색하는 사용자가 탭 키를 누르며 링크를 이동하다가, 화면상으로는 아래에 있던 요소로 가야 할 타이밍에 갑자기 문서 맨 위쪽이나 전혀 엉뚱한 곳으로 훅 점프해버리는 황당한 상황을 겪을 수 있다는 뜻입니다. HTML 소스 순서와 화면의 순서가 꼬여버렸기 때문이죠.

그래서 명세서에서는 개발자(CSSWG 용어로는 작성자)들에게 이런 식의 재배치를 하지 말라고 강력하게 경고하고 있습니다.

"작성자는 order 속성과 그리드 배치 속성들을 콘텐츠의 논리적 재배치가 아닌, 오직 시각적인 재배치를 위해서만 사용해야 합니다. 논리적인 순서를 바꾸기 위해 이런 기능들을 사용하는 스타일시트는 규격을 준수하지 않은 것입니다."

그렇다면, 이 경고가 실제 실무에서 그리드 레이아웃을 디자인할 때 어떤 의미를 가질까요?

💡 강사의 팁:
정말 중요한 포인트입니다! 개발을 하다 보면 기획이나 디자인 요구사항 때문에 요소의 순서를 화면상에서 뒤집어야 할 때가 있어요. 이때 CSS의 ordergrid-column으로 화면만 바꾸고 "끝났다!"라고 생각하시면 안 됩니다. 마우스 없이 키보드 Tab 키만 눌러서 여러분의 웹사이트를 돌아다녀 보세요. 포커스가 화면을 이리저리 미친 듯이 널뛰기한다면, 그건 잘못된(접근성이 훼손된) 마크업입니다.

논리적인 재배치가 아닌 시각적인 재배치 (Visual not logical re-ordering)

여러분이 그리드 레이아웃이나 플렉스박스(flexbox)를 사용해 무언가의 순서를 바꿀 때는 오직 시각적인 재배치(visual reordering)만 수행된다는 것을 명심하세요. 텍스트를 음성으로 읽어주거나 문서의 탭(Tab) 순서를 제어하는 것은 전적으로 그 바탕이 되는 HTML 소스 코드의 몫입니다. 예제를 통해 이게 어떻게 작동하는지 확실히 보여드릴게요.

아래 예제에서는 5개의 아이템을 가진 그리드가 있고, 각 아이템 안에는 링크(<a>)가 들어있습니다. 아이템들은 라인 기반 배치 속성으로 위치가 정해져 있어요. 여기서 우리는 첫 번째 박스(box 1)를 그리드의 두 번째 행으로 위치시켜서, 시각적으로는 마치 목록의 네 번째 아이템인 것처럼 보이게 만들었습니다.

하지만 사용자가 탭(Tab) 키를 눌러 링크들을 차례대로 탐색해보면, 가장 먼저 포커스(Focus)가 가는 곳은 여전히 'box 1'입니다. 왜냐하면 HTML 소스 코드 상에서는 box 1이 여전히 가장 첫 번째에 위치하고 있기 때문이죠.

* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 100px;
}

.box1 {
  grid-column: 1;
  grid-row: 2; /* 시각적으로는 2번째 줄로 내려버렸습니다! */
}
<div class="wrapper">
  <div class="box box1"><a href="">One</a></div>
  <div class="box box2"><a href="">Two</a></div>
  <div class="box box3"><a href="">Three</a></div>
  <div class="box box4"><a href="">Four</a></div>
  <div class="box box5"><a href="">Five</a></div>
</div>

명세서에 따르면, 만약 이런 상황에서 box 1이 논리적으로도 정말 4번째 위치에 있는 것이 맞다면, 우리는 그리드 레이아웃을 써서 순서를 꼼수로 바꿀 것이 아니라 직접 HTML 소스 코드로 돌아가서 마크업 순서 자체를 수정해야 합니다. 이것이 바로 '시각적 재배치'와 '논리적 재배치'의 차이입니다. 논리적인 순서는 우리 문서의 의미와 구조를 전달하는 데 있어 너무나도 중요하기 때문에, 우리는 항상 이 근본적인 구조가 훼손되지 않도록 지켜내야 합니다.


그리드 레이아웃의 접근성에 어떻게 접근해야 할까요? (How should we approach accessibility for grid layout?)

명세서를 통해 우리는 문서가 콘텐츠의 논리적인 순서를 올바르게 유지해야 한다는 것을 배웠습니다. 그렇다면 다양한 사용자와 그들이 웹페이지와 상호작용하는 여러 방식들을 위해 접근성을 유지하려면, 실제 개발 과정에서 어떻게 접근해야 할까요?

구조화되고 접근하기 쉬운 문서에서 출발하세요 (Start with a structured and accessible document)

그리드 레이아웃을 사용한다는 것은, 우리가 원하는 레이아웃을 얻기 위해 HTML 문서의 소스를 억지로 뜯어고칠 필요가 없다는 것을 의미해야 합니다. 따라서 웹페이지를 만들 때 가장 먼저 할 일은 탄탄한 구조와 접근성을 갖춘 원본 HTML 문서를 작성하는 것입니다. 흥미롭게도 이렇게 잘 짜여진 구조는 대개 여러분의 가장 작은 화면의 기기(모바일)를 위한 훌륭한 구조가 되기도 합니다. 사용자가 모바일에서 긴 문서를 스크롤해서 내릴 때 중요하게 봐야 하는 콘텐츠의 우선순위는, HTML 소스 코드 상에서의 우선순위와 완벽하게 일치하는 경우가 많기 때문입니다.

💡 강사의 팁:
"모바일 퍼스트(Mobile First)" 전략을 떠올려보세요! 화면이 좁은 모바일에서는 콘텐츠가 위에서 아래로(1차원) 흐르게 되죠? 이때 HTML 태그를 의미에 맞게 순서대로 잘 짜두면, 모바일에서는 CSS 레이아웃 없이도 내용이 자연스럽게 읽힙니다. 이렇게 튼튼하게 기초 공사를 한 뒤에, 데스크탑용 넓은 화면이 되었을 때 Grid를 써서 화려하게 옆으로 넓히고 재배치하는 것이 정석입니다.

반응형이면서, 동시에 책임감 있는 그리드를 만드세요 (Create a responsive, and responsible grid)

HTML에 탄탄한 문서 구조를 잡아두었다면, 이제 CSS를 사용하여 그 위에 레이아웃을 입힐 차례입니다. 아마도 여러분은 다양한 화면 크기나 기기에 대응하기 위해 미디어 쿼리(media queries)를 사용할 것이고, 넓은 화면에서는 여러 개의 열(column)을 추가하게 될 것입니다. 그리드는 이 단계에서 엄청나게 유용합니다. 예를 들어, 모바일 소스 코드에서는 중요도가 낮아 맨 아래에 배치되었던 요소들을, 데스크탑 레이아웃에서는 화면 우측의 사이드바로 쏙 끌어올릴 수 있으니까요. 여기서 핵심은 계속해서 테스트하는 것입니다. 가장 좋은 테스트 방법은 탭(Tab) 키를 눌러 문서 전체를 돌아다녀 보는 것입니다. 이동 순서가 여전히 말이 되나요? 탭을 누를 때마다 화면 맨 위에서 맨 아래로 기괴하게 널뛰고 있지 않은지 꼭 확인하세요. 만약 그렇다면, 레이아웃 방식에 무언가 조치가 필요하다는 강력한 신호입니다.

소스로 다시 돌아가기 (Returning to the source)

디자인 과정 중 언제라도 그리드를 사용해 특정 요소의 위치를 눈에 띄게 옮기고 있는 자신을 발견한다면, "잠깐, 내가 이 요소의 논리적인 순서(HTML 구조)도 바꿔야 하는 건 아닐까?" 하고 스스로 고민해 보세요. CSS 그리드 레이아웃의 멋진 점은, 레이아웃 코드를 크게 망가뜨리지 않고도 요소의 논리적 순서를 맞추기 위해 HTML 소스 위치를 쉽게 옮길 수 있다는 것입니다. 문서의 논리적 순서를 유지하기 위해 소스 코드로 돌아가 그것을 업데이트하는 것은 오롯이 우리 개발자들의 몫이자 책임입니다.


그리드와 마크업 평면화의 위험성 (Grid and the danger of markup flattening)

CSS 그리드 레이아웃(그리고 조금 덜하지만 CSS 플렉스박스에서도)을 사용할 때 주의해야 할 또 다른 문제는 바로 마크업을 '평면화(flattening)'하려는 유혹에 빠지기 쉽다는 점입니다.

지금까지 배워서 아시겠지만, 어떤 요소가 '그리드 아이템(grid item)'이 되어 그리드의 마법 같은 배치를 받으려면, 반드시 그리드 컨테이너의 '직계 자식(direct child)'이어야만 합니다.

예를 들어, 그리드 컨테이너 안에 <ul> 요소(리스트)가 들어있다면, 그 <ul> 태그 자체가 그리드 아이템이 되는 것이지, 그 안에 들어있는 진짜 알맹이인 자식 <li> 요소들은 그리드 아이템이 되지 않습니다.

이때 많은 개발자들이 <li>들을 그리드에 예쁘게 배치하고 싶어서, 의미론적으로 꼭 필요한 <ul> 태그를 삭제해 버리고 <li> 대신 단순히 <div>들을 쫙 깔아버리는 실수를 하곤 합니다. 이게 바로 마크업을 평면화하는 행위입니다.

다행히 grid-template-columnsgrid-template-rows에 사용할 수 있는 subgrid 값이 이 문제를 우아하게 해결해 줍니다. 서브그리드를 사용하면 부모의 그리드 설정이 자식 그리드 아이템에게 상속되어, HTML 트리 깊숙이 전달될 수 있습니다.

또 다른 대안으로는 그리드 아이템(이 경우 <ul> 태그)에 display: contents를 설정하는 방법이 있습니다. 이렇게 하면 해당 요소의 자식들(<li>들)이 마치 부모를 뚫고 올라온 것처럼 그리드 아이템으로 승격됩니다. display: contents를 설정하면 원래 생성되어야 할 부모 박스는 화면에서 완전히 투명해져 사라지고, 그 안에 있던 자식 요소들의 박스가 한 단계 위로 올라온 것처럼 렌더링 됩니다.

결론적으로, 처음부터 제대로 구조화된 HTML 문서를 작성하는 것이 접근성 문제를 미연에 방지하는 가장 훌륭하고 확실한 방법입니다.

💡 강사의 팁:
"디자인을 맞추기 위해 HTML 태그의 의미(Semantic)를 파괴하지 말자!"
이 원칙만 가슴에 새기셔도 훌륭합니다. <ul><li>는 목록을 스크린 리더에게 전달하는 아주 중요한 태그입니다. 이걸 억지로 <div>로 바꾸지 마시고, 최신 CSS 기능인 subgriddisplay: contents를 활용해 디자인과 접근성 두 마리 토끼를 모두 잡으세요!


더 보기 (See also)

접근성과 그리드/플렉스박스에 대해 더 깊이 공부하고 싶으시다면 아래의 귀중한 자료들을 꼭 읽어보세요!


이 문서는 2025년 11월 7일에 MDN 기여자들(MDN contributors)에 의해 마지막으로 수정되었습니다.
GitHub에서 이 페이지 보기 | 문제점 신고하기


강사의 입장에서 실무적인 팁들을 더해 번역을 진행해 보았습니다. 접근성은 조금 어렵게 느껴질 수도 있지만, 습관이 되면 여러분을 대체 불가능한 에이스 개발자로 만들어줄 것입니다! 추가로 궁금한 점이 있으시다면 언제든 질문 남겨주세요.

profile
프론트에_가까운_풀스택_개발자

0개의 댓글