CSS / 고정형 레이아웃 만들기
고정형 레이아웃은 화면 크기가 달라져도 페이지의 기준 너비를 일정하게 유지하는 배치입니다. 바깥 상자에 width를 지정하고 margin-inline: auto로 가운데에 놓은 뒤, CSS Grid로 본문과 사이드바를 나누면 만들 수 있습니다. 다만 화면보다 페이지가 넓으면 가로 스크롤이 생기므로 모바일까지 대응할 때는 반응형 배치를 별도로 설계해야 합니다.
고정형 레이아웃의 기준 정하기
이 글에서는 바깥 테두리를 포함한 페이지 너비를 960px로 고정합니다. 그 안에 머리말, 본문과 사이드바, 꼬리말을 배치합니다. 브라우저 창을 넓혀도 페이지 너비는 960px이며, 남는 공간은 좌우 바깥 여백이 됩니다. CSS의 px는 CSS 픽셀로, 화면의 물리적인 픽셀 수와 항상 같지는 않습니다.
고정형이라는 말은 스크롤해도 화면에 붙어 있는 position: fixed와 다른 뜻입니다. 여기서 고정하는 것은 페이지의 너비입니다. 페이지 영역을 표로 만들 필요도 없습니다. 표는 행과 열의 데이터에 사용하고, 페이지 배치는 Grid처럼 레이아웃을 위한 기능으로 작성할 수 있습니다.
| 설정 | 이 예제의 역할 |
|---|---|
width: 960px |
페이지의 기준 너비를 정합니다. |
box-sizing: border-box |
지정한 너비에 안쪽 여백과 테두리를 포함합니다. |
margin-inline: auto |
가로 공간이 남을 때 페이지를 가운데에 놓습니다. |
grid-template-columns |
본문과 사이드바의 열 너비를 정합니다. |
gap |
열 사이의 간격을 정합니다. |
전체 예제: 본문과 사이드바가 있는 2단 배치
텍스트 편집기에 다음 코드를 입력하고 fixed-layout.html로 저장한 뒤 브라우저에서 엽니다. 별도 라이브러리나 설치 과정은 없습니다. 실습할 때는 브라우저 창의 너비를 1,100px 이상으로 넓혀 페이지 양쪽의 여백도 함께 확인하세요.
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>고정형 2단 레이아웃</title>
<style>
*, *::before, *::after { box-sizing: border-box; }
body {
margin: 0;
color: #243449;
background: #eef2f6;
font-family: "Noto Sans KR", sans-serif;
line-height: 1.7;
}
.page {
width: 960px;
margin: 32px auto;
padding: 20px;
border: 1px solid #b8c6d4;
background: white;
}
.panel {
min-width: 0;
padding: 20px;
border: 1px solid #b8c6d4;
overflow-wrap: anywhere;
}
header, footer { background: #e8f0f9; }
h1, h2 { margin-top: 0; }
.layout {
display: grid;
grid-template-columns: minmax(0, 1fr) 220px;
grid-template-areas: "main side";
gap: 20px;
margin-block: 20px;
}
.content { grid-area: main; }
.sidebar { grid-area: side; background: #fff4d9; }
</style>
</head>
<body>
<div class="page">
<header class="panel">
<h1>고정형 레이아웃 실습</h1>
<p>페이지의 바깥 너비는 960px입니다.</p>
</header>
<div class="layout">
<main class="panel content">
<h2>본문</h2>
<p>본문과 사이드바는 서로 다른 열에 배치됩니다.</p>
<p>창을 넓혀도 페이지와 사이드바의 너비는 유지됩니다.
본문이 길어지면 가운데 행의 높이가 늘어나고 꼬리말은 그 아래에 놓입니다.</p>
</main>
<aside class="panel sidebar">
<h2>사이드바</h2>
<ul><li>공지 사항</li><li>분류 목록</li><li>문의 안내</li></ul>
</aside>
</div>
<footer class="panel">꼬리말은 두 열의 아래에 배치됩니다.</footer>
</div>
</body>
</html>
결과는 위아래로 넓은 머리말과 꼬리말, 가운데의 넓은 본문과 오른쪽 사이드바입니다. 이 예제는 Grid의 기본 늘이기 정렬을 사용하므로 두 패널의 바깥 높이도 같아집니다. 본문 문단을 더 추가해 가운데 행과 꼬리말이 함께 아래로 이동하는지 확인해 보세요.
너비가 계산되는 방식
페이지 바깥 너비 960px에는 좌우 안쪽 여백 20px씩과 테두리 1px씩이 들어 있습니다. 따라서 Grid가 사용할 수 있는 안쪽 너비는 960 - 40 - 2 = 918px입니다. 그중 사이드바가 220px, 열 간격이 20px이므로 본문 열은 678px을 사용합니다. 패널에도 border-box가 적용되어 있어 본문과 사이드바의 안쪽 여백이 열 너비 밖으로 더해지지 않습니다.
minmax(0, 1fr)는 남는 공간을 본문 열에 배분하면서 열의 최소 너비를 0으로 둡니다. 1fr만 썼을 때 긴 내용이 열을 예상보다 넓게 만드는 문제를 줄이는 데 유용합니다. 예제에서는 min-width: 0과 overflow-wrap: anywhere도 함께 사용해 긴 문자열이 패널 밖으로 튀어나오는 상황을 다룹니다. 이미지가 있다면 별도로 max-width: 100%; height: auto;도 검토해야 합니다.
개발자 도구의 요소 검사에서 .page의 박스 모델 너비와 .layout의 열 크기를 확인할 수 있습니다. MDN의 box-sizing 설명은 내용 영역과 테두리를 포함한 크기의 차이를, grid-template-columns 문서는 열 크기를 지정하는 방식을 설명합니다.
사이드바를 왼쪽으로 바꾸기
전체 예제의 .layout 규칙에서 다음 두 선언만 바꿉니다. 첫 번째 열을 사이드바 너비로 바꾸고, 영역의 순서도 함께 바꿔야 합니다. 나머지 HTML과 스타일은 그대로 둡니다.
grid-template-columns: 220px minmax(0, 1fr);
grid-template-areas: "side main";
새로 고침하면 사이드바는 왼쪽, 본문은 오른쪽에 표시됩니다. 다시 원래 두 선언으로 되돌리면 오른쪽 사이드바 배치로 복구됩니다. 이 변경은 화면의 위치만 바꾸며 HTML의 읽기 순서는 바꾸지 않습니다. 링크나 입력 요소가 있는 실제 페이지에서는 키보드 이동 순서가 시각적인 순서와 어긋나지 않도록 문서 구조도 함께 검토하세요.
3단 레이아웃으로 확장하기
양쪽 사이드바가 필요하면 전체 예제의 <div class="layout">부터 대응하는 닫는 태그까지를 다음 코드로 교체합니다. 머리말과 꼬리말은 그대로 둡니다.
<div class="layout">
<aside class="panel sidebar-left">
<h2>분류</h2><p>왼쪽 사이드바입니다.</p>
</aside>
<main class="panel content">
<h2>본문</h2><p>가운데 열이 남는 너비를 사용합니다.</p>
</main>
<aside class="panel sidebar">
<h2>안내</h2><p>오른쪽 사이드바입니다.</p>
</aside>
</div>
이어서 기존 .layout, .content, .sidebar 규칙을 다음 스타일로 교체합니다. .page와 .panel 등의 공통 규칙은 유지합니다.
.layout {
display: grid;
grid-template-columns: 160px minmax(0, 1fr) 200px;
grid-template-areas: "left main right";
gap: 20px;
margin-block: 20px;
}
.sidebar-left { grid-area: left; background: #fff4d9; }
.content { grid-area: main; }
.sidebar { grid-area: right; background: #fff4d9; }
왼쪽 160px, 가운데 518px, 오른쪽 200px의 세 열이 만들어집니다. 열 사이에 20px 간격이 두 번 들어가므로 160 + 518 + 200 + 40 = 918px입니다. 두 사이드바의 값을 늘리면 가운데 본문이 좁아진다는 점을 직접 관찰할 수 있습니다. 2단 예제로 돌아가려면 교체했던 HTML과 스타일을 원래 코드로 되돌립니다.
좁은 화면과 기존 float 코드에서 주의할 점
브라우저 창을 960px보다 좁게 하면 페이지가 창에 맞춰 줄어들지 않습니다. 이 예제의 가로 스크롤은 고정형 배치의 결과입니다. 모바일에서 가로 스크롤을 없애려면 바깥 너비만 줄이는 것으로 끝내지 말고 열 너비와 열 개수도 함께 바꿔야 합니다. 단순히 overflow-x: hidden으로 넘친 영역을 가리면 사이드바나 조작 요소에 접근할 수 없게 됩니다.
기존 문서에서 float와 clear로 같은 구조를 만든 코드를 볼 수 있습니다. float 기반 배치는 떠 있는 요소가 일반 흐름에서 빠지는 특성까지 고려해야 합니다. 이 글의 Grid 예제에서는 열이 Grid의 행을 구성하므로 float 해제를 위한 clear: both가 필요하지 않습니다. Grid로 전환하면서 이전의 float와 고정 폭 계산 코드를 일부만 남기면 의도하지 않은 결과가 생길 수 있으므로, 배치 규칙을 한 방식으로 정리해 확인하세요.





