이 글은 3부작 중 첫 번째로, 최신 브라우저뿐만 아니라 IE에서도 작동하는 CSS 그리드 시스템 사용법에 관한 글입니다. 폴백 레이아웃을 작성하지 않고도 CSS 그리드 코드를 작성한다고 상상해보세요. 많은 사람이 이런 건 몇 년 후 미래에나 가능할 것이라고 생각합니다. 현실적으로 IE11만이 남아 있는 걸림돌이라고 생각했다면 운이 좋은 편입니다. 이 시리즈를 다 읽고 나면 IE11(canius.com에서 확인)에서도 그리드를 쓸 수 있게 될 것입니다.
1부 – IE에서의 CSS 그리드 사용하기: 일반적인 IE 그리드 오해를 파헤치다(현재 글)
2부 – IE에서 CSS 그리드 사용하기: CSS 그리드와 Autoprefixer
3부 – IE에서 CSS 그리드 사용하기: 간격으로 자동 배치 그리드 만들기
4부 – IE에서 CSS 그리드 사용하기: 중복된 그리드 영역명도 지원하기
시작하기 전에, 1부에서는 IE11의 기본 그리드 구현에 대한 오해를 다룰 것입니다.
2부에서는 IE11에서 CSS 그리드를 사용하는 것이 매우 어렵다는 선입견을 없애 보겠습니다. IE11 에는 더 이상 구질구질한 폴백 레이아웃이 필요 없습니다. 그리고 3부에서는 자동 배치 그리드를 만들 때 함께 쓸 수 있는 플렉스박스 기술에 대해 알려드리겠습니다. 자동 배치 그리드를 흉내 낸 것인데 실제로 CSS 그리드 레이아웃을 사용해서 만든 그리드와 완전히 똑같아 보입니다. 미디어쿼리에서 width 값 하나만 바꾸면 화면 폭에 따라 완전히 반응형으로 칼럼 수를 조절할 수 있고, 심지어 IE11에서도 완벽하게 작동합니다. 서론은 이쯤 하고, 이런 오해들에 대해 이야기하러 넘어가보죠.
IE는 ‘암시적 그리드’를 가지고 있다
CSS 그리드에서 ‘명시적 그리드’는 grid-template-*
속성으로 수동으로 정의하는 것을 이야기합니다. 반면 ‘암시적 그리드’는 ‘명시적 그리드’ 외부의 셀을 브라우저가 알아서 배열하는 방법입니다.
최신 브라우저에서 CSS그리드를 사용할 때 ‘암시적 그리드’는 셀을 수동으로 정의하지 않아도 알아서 새 열에 생성하므로 알아차리기 쉬운 편입니다. IE는 자동 배치가 되지 않아 암시적 그리드를 지원하지 않는다고 오해하기 쉽지만 우리가 실제로 쓸 때는 좀 더 명확히 알아야 합니다.
IE의 암시적 그리드를 사용하는 가장 흔한 케이스는 행을 생성할 때입니다. 만약 그리드 내부 행들의 높이가 내용물 높이에 의해 알아서 조절되도록 하려면 굳이 -ms-grid-rows
(grid-template-rows
의 IE 버전)를 정의할 필요가 없습니다. 그리드 셀을 배치하면 행이 자동으로 세팅됩니다.
중요한 것은 최신 브라우저에서는 grid-auto-rows/grid-auto-columns
속성을 사용할 수 있다는 점입니다. 이 속성들을 사용하면 브라우저가 암시적 그리드에서 행과 열의 크기를 처리하는 방법을 지정할 수 있습니다. 반면 IE에는 이런 속성에 대한 개념이 없습니다. IE의 암시적 그리드는 ‘auto
’만 지원합니다.
IE는 반복 기능을 가지고 있다
걱정하지 마세요. 12열 그리드를 만들 때 1fr 20px
를 12번이나 쓸 필요는 없습니다(IE는 grid-gap
을 지원하지 않습니다). IE에는 repeat()
함수가 기본으로 내장되어 있습니다. 그저 다른 구문 뒤에 가려져 있을 뿐이죠.
열과 행의 값을 반복시키는 최신 문법은 repeat(12, 1fr 20px)
입니다. 1fr 20px
패턴을 12번 반복하라는 뜻이죠. IE 버전은 (1fr 20px)[12]
입니다. IE 버전은 기능은 같지만 문법이 좀 다릅니다.
최신 브라우저와 IE가 repeat()
함수를 돌리는 방식에는 문법 외에도 또 다른 점이 하나 더 있습니다. 최신 브라우저들은 auto-fit/auto-fill
키워드 기능을 지원합니다. IE는 이런 것을 지원하지 않으므로 IE에서는 사용하지 마세요.
IE는 minmax()를 기본적으로 지원한다
minmax()
는 CSS 그리드 전용의(현재까지는) 크기 조절 함수입니다. 함수 파라미터로 최솟값과 최댓값을 주면 열이나 행이 그 사잇값으로 알아서 줄어들고 늘어납니다. 아래 codepen에서 어떻게 돌아가는지 확인해보세요.
See the Pen <a href=’https://codepen.io/iwuegqfx/pen/MWYRqVr’>MWYRqVr</a> by 만해당 (<a href=’https://codepen.io/iwuegqfx’>@iwuegqfx</a>) on <a href=’https://codepen.io’>CodePen</a>.
IE에는 이런 멋진 기능이 내장되어 있지만 사람들은 종종 없다고 오해합니다. 그 이유는 아마 다음 두 가지 중 하나일 것 같네요.
1. IE는 쓰레기이기 때문에 이런 멋진 기능을 가질 리 없다.
2. grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
같은 멋진 코드가 IE에서 돌아가지 않는 것을 보고 화가 났다(만약 이 코드를 처음 본다면, 이 짧은 동영상을 잠깐 보고 놀랄 준비를 하시죠).
저 코드가 IE에서 동작하지 않기 때문에 사람들은 나머지에 대해서도 기대를 접어버립니다. 사실은 IE가 auto-fit
과 auto-placement를 지원하지 않기 때문에 작동하지 않는 것입니다.
min-content/max-content는 IE에서 100% 잘 작동한다
IE는 min-content
와 max-content
를 완벽하게 지원합니다.
min-content
를 이용해 열과 행을 줄일 수 있는 최솟값을 지정할 수 있습니다. 이것을 열에 적용하면 보통 가장 긴 단어의 너비가 열의 너비가 됩니다.
See the Pen <a href=’https://codepen.io/iwuegqfx/pen/MWYRqVr’>MWYRqVr</a> by 만해당 (<a href=’https://codepen.io/iwuegqfx’>@iwuegqfx</a>) on <a href=’https://codepen.io’>CodePen</a>.
반면 max-content
를 이용해 늘릴 수 있는 최댓값을 지정할 수 있습니다. white-space: nowrap
을 본 적이 있죠? 그것과 비슷하게 작동합니다.
See the Pen <a href=’https://codepen.io/iwuegqfx/pen/MWYRqVr’>MWYRqVr</a> by 만해당 (<a href=’https://codepen.io/iwuegqfx’>@iwuegqfx</a>) on <a href=’https://codepen.io’>CodePen</a>.
저는 앞서 minmax()
코드의 이유로 IE가 이런 것들을 제대로 지원하지 않을 것이라고 예상했는데, 조사해보니 제가 틀렸다는 것을 알고 오히려 기뻤습니다. minmax()
와 마찬가지로 IE가 지원하지 못하는 그리드 문법은 많지 않습니다(auto-placement를 안 쓴다면).
IE는 fit-content( )를 지원하지 않지만…
IE는 fit-content()
를 지원하지 않습니다. ?
하지만 다행스럽게도 fit-content()
는 일종의 단축 문법이라 긴 문법으로 쓸 경우 IE에서 지원합니다.?
길게 쓰는 방법은 열이나 행에 auto(혹은 좀 더 자세히 말해 minmax(min-content, max-content)
) 적용, 그리고 자식 요소에 max-width: [value]
를 지정하는 것입니다.
아래 예제는 모던 브라우저에서 fit-content()
를 사용하는 방식입니다.
위의 fit-content()
가 의미하는 바는 이렇습니다. “강제로 값을 지정하지 않는 한 가운데 열을 내용물의 가로 최대 사이즈(예: max-content
값)에 맞게 300px 이내에서 늘려라.”
See the Pen <a href=’https://codepen.io/iwuegqfx/pen/MWYRqVr’>MWYRqVr</a> by 만해당 (<a href=’https://codepen.io/iwuegqfx’>@iwuegqfx</a>) on <a href=’https://codepen.io’>CodePen</a>.
모바일로 이 글을 보고 있다면 화면을 가로로 눕혀서 Codepen 데모를 봐주세요.
IE가 같은 방식으로 동작하게 만들려면 코드를 아래와 같이 작성해야 합니다.
See the Pen <a href=’https://codepen.io/daniel-tonon/pen/pKZLBY’>fit-content IE hack</a> by Daniel Tonon (<a href=’https://codepen.io/daniel-tonon’>@daniel-tonon</a>) on <a href=’https://codepen.io’>CodePen</a>.
이것이 IE에서 fit-content()
를 완벽하게 재현할 수 있는 요술 방망이는 아닙니다. 만약 어떤 그리드 셀이 다른 셀의 max-width
값보다 폭을 넓게 쓸 경우, 그리드 열은 더 큰 셀 크기에 맞게 늘어납니다. fit-content()
를 쓸 때처럼 300px에 제한되지 않습니다.
See the Pen <a href=’https://codepen.io/iwuegqfx/pen/MWYRqVr’>MWYRqVr</a> by 만해당 (<a href=’https://codepen.io/iwuegqfx’>@iwuegqfx</a>) on <a href=’https://codepen.io’>CodePen</a>.
전체 열에 영향을 미치는 최신 fit-content()
함수와 비교해보세요.
See the Pen <a href=’https://codepen.io/iwuegqfx/pen/MWYRqVr’>MWYRqVr</a> by 만해당 (<a href=’https://codepen.io/iwuegqfx’>@iwuegqfx</a>) on <a href=’https://codepen.io’>CodePen</a>.
이 글의 주제대로 fit-content()
함수에 대한 오해를 풀어야 합니다. fit-content()
를 지정한 행이나 열은 입력한 값을 넘어가지 않는다는 것이 바로 오해입니다. 위의 경우에는 해당되지 않습니다. 만약 어떤 그리드 열이 가로 사이즈 fit-content(300px)
로 세팅되어 있고, 그 안의 그리드 셀이 가로 400px로 지정되어 있다면 그리드 열은 우리가 예상한 300px 대신 400px이 됩니다.
See the Pen <a href=’https://codepen.io/iwuegqfx/pen/MWYRqVr’>MWYRqVr</a> by 만해당 (<a href=’https://codepen.io/iwuegqfx’>@iwuegqfx</a>) on <a href=’https://codepen.io’>CodePen</a>.
IE의 auto != 최신 브라우저의 auto
IE의 auto
값은 최신 브라우저들의 auto
와는 조금 다르게 작동합니다. IE에서의 auto
는 minmax(min-content, max-content)
와 완전히 동일합니다. 열이나 행을 auto
로 세팅할 경우, IE에서는 절대 min-content
보다 작아질 수 없습니다. 또한 max-content
보다 커질 수도 없습니다.
최신 브라우저들의 auto
값은 조금 다르게 작동합니다. 대개 auto
는 IE와 마찬가지로 minmax(min-content, max-content)
와 동일하게 작동합니다. 하지만 결정적 차이가 있습니다. 최신 브라우저의 auto
는 align-content
와 justify-content
속성에 따라 늘어날 수 있습니다.
최신 브라우저에서 auto
를 이용해 그리드 열의 사이즈를 조절할 때, auto
는 열을 가득 채울 내용물이 없으면 1fr
와 비슷하게 작동합니다. 하지만 IE는 그렇지 않죠. IE는 언제나 max-content
사이즈에 맞게 그리드 열의 사이즈를 줄입니다.
자, 아래와 같은 코드가 있을 때:
최신 브라우저에서는 이렇게 동작합니다:
그리고 IE에서는 이렇습니다:
최신 브라우저에서는 1fr
를 쓸 때와 비슷하게 동작합니다. 그렇다면 minmax(min-content, 1fr)
를 써서 IE에 대응할 수 있을까요? 이렇게 하면 최신 브라우저처럼 가로로 늘어나지 않을까요?
네, 하지만 아래와 같은 문제가 있습니다:
최신 브라우저:
IE:
참고로 minmax(min-content, 1fr)
의 1fr
는 그냥 1fr
이지 auto
가 아닙니다. minmax(min-content, 100%)
로도 실험해봤지만, IE는 그저 1fr
를 썼을 때와 같은 결과를 보여주었습니다. 제가 아는 한 IE에서 최신 브라우저의 auto
기능을 흉내 낼 방법은 없습니다.
auto
값에 대해 또 다른 중요한 차이점이 있습니다. IE 버전의 auto
는 minmax(min-content, max-content)
와 동일하기 때문에, minmax()
함수 안에 auto
를 사용할 수 없습니다. minmax()
는 또 다른 minmax()
함수 안에서 사용할 수 없습니다. 따라서 auto
는 사용하기 까다롭습니다.
최신 브라우저들은 좀 복잡미묘합니다. auto
는 상황에 따라 다르게 해석됩니다. 그냥 사용할 경우 본질적으로 minmax(min-content, max-content)
와 동일합니다. 하지만 늘어날 수 있는 기능이 추가되죠. max 값과 함께 사용할 경우 auto
는 max-content
와 동일합니다. min 값과 함께 사용하면 min-content
와 동일합니다.
만약 지금 그리드 템플릿에서 auto
를 쓰지 말아야겠다고 겁을 먹었다면, 다시 생각해보셔야 합니다. IE에서 auto
가 다르게 동작하는 상황은 오직 세 경우뿐입니다.
1. auto
가 grid-template-columns
에서 fr
단위 없이 사용될 경우
2. auto가 grid-template-rows
에서 fr
단위 없이, 그리고 그리드의 높이가 내부 그리드 셀보다 높을 경우
3. auto
가 minmax()
함수 안에서 사용될 경우
IE에서 auto
가 다르게 동작하는 경우는 이 세 경우가 전부입니다. auto
는 minmax(min-content, max-content)
보다 쓰기 편합니다. 쉽게 피할 수 있는 몇 가지 오작동 때문에 이것을 포기할 필요는 없습니다.
(내용 추가) IE 그리드는 display: inline
요소에서 작동하지 않는다
그리드 안에서 <span>
이나 <a>
요소를 그리드 셀로 사용할 경우, IE에서 돌려보면 다 깨지는 것을 볼 수 있습니다. 그리드는 블록 레벨 요소들(예: <p>
, <div>
, <ul>
)에서만 잘 작동하고 인라인 요소들(예: <span>
, <a>
, <label>
)에서는 다 깨집니다.
아쉽게도 IE에서는 display: inline
요소를 그리드에 넣을 수 없습니다. 브라우저들은 <span>
과 <a>
요소를 기본적으로 display: inline
으로 봅니다. 하지만 이것은 그냥 display: block
으로 따로 지정해 쉽게 피해갈 수 있습니다.
See the Pen <a href=’https://codepen.io/iwuegqfx/pen/MWYRqVr’>MWYRqVr</a> by 만해당 (<a href=’https://codepen.io/iwuegqfx’>@iwuegqfx</a>) on <a href=’https://codepen.io’>CodePen</a>.
브라우저들은 <main>
<header>
<footer>
등의 HTML5 요소들을 display: block
으로 다룹니다. 하지만 이 요소들은 IE11 이후에 등장했기 때문에 IE11은 이들을 모릅니다. 인식할 수 없는 요소들은 <span>
과 동일하게 취급합니다. 다시 말해 이것들을 그리드 아이템으로 쓰면 IE에서 다 깨질 것이란 말이지요.