피그마에서 무언가를 담는 상자가 프레임이라면, 화면 코드에서 그 상자는 대개 하나의 박스입니다. 프레임을 만들 때 우리가 정하는 크기와 여백과 정렬은 CSS의 박스 모델과 그대로 짝이 맞습니다. 프레임을 코드 박스로 옮기는 과정을 값 하나씩 짚어 보겠습니다.
62.1 프레임은 결국 박스
프레임 안에는 콘텐츠가 있고, 그 둘레로 안쪽 여백과 테두리와 바깥 여백이 겹겹이 감쌉니다. CSS 박스 모델이 말하는 네 겹이 바로 그것입니다.
.frame {
width: 320px;
padding: 16px;
border: 1px solid #e5e7eb;
margin: 24px;
}
안쪽 여백 padding 은 콘텐츠와 테두리 사이를 벌리고, 바깥 여백 margin 은 이 박스와 옆 박스 사이를 벌립니다. 피그마에서 프레임 안 여백과 프레임 사이 간격을 따로 잡는 것과 똑같은 구분입니다.
62.2 크기 계산을 헷갈리지 않게
기본 상태의 박스는 width 가 콘텐츠 폭만 가리키고, 여백과 테두리는 그 바깥에 따로 더해집니다. 그래서 320으로 잡은 박스가 실제로는 더 넓어지는 함정이 생깁니다.
/* 실제 폭 = 320 + 16*2 + 1*2 = 354px */
.frame {
width: 320px;
padding: 16px;
border: 1px solid #e5e7eb;
}
피그마에서 프레임을 320으로 잡으면 그 320 안에 여백이 포함되는데, 코드 기본값은 반대로 동작하니 어긋나는 것이지요. 이 어긋남은 한 줄로 맞춥니다.
*, *::before, *::after {
box-sizing: border-box;
}
.frame {
width: 320px;
padding: 16px;
border: 1px solid #e5e7eb;
}
이제 width 가 테두리까지 포함한 바깥 폭을 뜻하게 되어, 여백을 아무리 넣어도 320을 지킵니다. 피그마의 프레임 크기와 코드의 크기가 같은 뜻이 되는 순간입니다.
62.3 프레임 크기와 제약
피그마의 크기 제약은 화면이 넓어지거나 좁아질 때 프레임이 어떻게 버틸지를 정합니다. 이것은 CSS의 최대 폭, 최소 높이, 가운데 정렬로 옮겨집니다.
.container {
width: 100%;
max-width: 960px;
min-height: 200px;
margin: 0 auto;
}
여기서 width: 100% 는 좁은 화면에서 꽉 차게 늘어나라는 뜻이고, max-width 는 넓은 화면에서 960을 넘지 말라는 상한입니다. 좌우 margin 을 auto 로 두면 남는 공간이 양옆에 똑같이 나뉘어 박스가 가운데로 옵니다.
피그마에서 프레임을 좌우 고정으로 붙이는 제약은 이렇게 표현됩니다.
.panel {
margin-left: 24px;
margin-right: 24px;
}
양쪽을 같은 값으로 붙여 두면 화면이 넓어질 때 가운데 콘텐츠 폭만 늘어납니다. 제약을 크기 규칙으로 번역해 두면, 창을 줄이거나 늘여도 레이아웃이 흐트러지지 않습니다.
62.4 레이아웃 그리드
피그마의 컬럼 그리드는 화면을 여러 세로줄로 나눠 요소를 그 줄에 맞춰 놓는 장치입니다. CSS에서는 그리드 레이아웃이 이 일을 그대로 맡습니다.
.grid {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 24px;
}
repeat(12, 1fr) 은 폭이 같은 열 열두 개를 만들라는 뜻이고, 1fr 은 남는 공간을 똑같이 나눠 가지는 한 몫을 가리킵니다. gap 은 열과 행 사이의 간격이라, 피그마 그리드의 거터와 같은 자리입니다.
어떤 카드는 열두 열 중 몇 칸을 차지할지 지정할 수 있습니다. 피그마에서 요소를 여러 컬럼에 걸치는 것과 같습니다.
.card-main {
grid-column: span 8;
}
.card-side {
grid-column: span 4;
}
본문이 여덟 칸, 옆 영역이 네 칸을 차지해 합이 열두 칸으로 딱 맞습니다. 열두 개라는 숫자는 2, 3, 4, 6으로 고르게 나뉘어 반씩, 삼분의 일씩 나누기가 쉬워 오래 사랑받는 값입니다.
62.5 중첩 프레임
피그마에서 프레임 안에 프레임을 넣듯, 코드에서도 박스 안에 박스를 넣어 구조를 만듭니다. 바깥 박스는 큰 틀을 잡고, 안쪽 박스는 제 몫의 여백과 정렬을 따로 가집니다.
<div class="card">
<div class="card-body">
<h3>제목</h3>
<p>설명</p>
</div>
</div>
이 중첩에 각자의 여백을 줍니다.
.card {
max-width: 360px;
border: 1px solid #e5e7eb;
border-radius: 8px;
}
.card-body {
padding: 20px;
}
바깥 card 는 폭과 테두리라는 큰 틀만 맡고, 안쪽 card-body 가 콘텐츠 둘레 여백을 책임집니다. 역할을 이렇게 나눠 두면, 나중에 카드 안에 이미지 한 줄을 더 얹어도 바깥 틀은 건드리지 않고 안쪽만 손보면 됩니다.
62.6 좁은 화면에서 열 수 줄이기
피그마에서는 데스크톱과 모바일 프레임을 따로 그리지만, 코드에서는 화면 폭에 따라 그리드가 스스로 열 수를 바꾸게 만들 수 있습니다. 고정된 열두 열은 좁은 화면에서 답답합니다.
.gallery {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 16px;
}
이 값을 폭에 반응하도록 바꾸면, 카드가 최소 폭 아래로 눌리지 않고 알아서 줄을 바꿉니다.
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 16px;
}
minmax(200px, 1fr) 은 한 열이 적어도 200은 되고 남으면 더 늘어나라는 뜻이고, auto-fill 은 그 규칙으로 들어갈 수 있는 만큼 열을 채우라는 지시입니다. 넓은 화면에서는 다섯 열, 좁은 화면에서는 두 열로 카드가 스스로 접힙니다. 프레임을 폭마다 새로 그리는 대신, 규칙 하나로 여러 폭을 감당하는 셈이지요.
특정 폭에서 크게 바꾸고 싶을 때는 미디어 쿼리로 딱 잘라 지정할 수도 있습니다.
@media (max-width: 600px) {
.card-main,
.card-side {
grid-column: span 12;
}
}
모바일에서는 본문과 옆 영역이 나란히 서는 대신 위아래로 쌓여 각자 열두 칸을 다 씁니다. 데스크톱 프레임과 모바일 프레임의 차이가 코드에서는 이 한 블록으로 표현됩니다.
62.7 정리
프레임을 박스로, 제약을 크기 규칙으로, 컬럼 그리드를 그리드 레이아웃으로 옮기면 디자인과 코드가 같은 골격을 공유하게 됩니다. 지금까지 나온 조각을 한 틀에 모아 봅니다.
.layout {
width: 100%;
max-width: 960px;
margin: 0 auto;
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 24px;
}
가운데로 모인 폭 안에서 열두 열이 콘텐츠를 나눠 받습니다. 프레임은 화면 위의 상자이고, 박스 모델은 그 상자를 코드로 옮긴 설계도입니다. 상자를 어떻게 그렸는지 기억해 두면, 코드로 옮길 길은 이미 절반쯤 놓여 있습니다.