HTML div 레이아웃 나누기 - HTML div leiaus nanugi

이전 글에서 완성한 <header>, <footer>에 이어서

<main> 영역을 만들어보겠습니다.

이 글에서는 <main> 영역의 내부를 세부적으로 카피하지는 않고

두가지 방식으로 큰 틀만 나누어 볼게요.

※스압에 주의하세요

HTML div 레이아웃 나누기 - HTML div leiaus nanugi

1. 큰 단위 -> 작은 단위 순서대로

이전 글에서 <body> 전체를 <header>, <main>, <footer> 영역으로 나눴듯이

<main> 영역을 각 구역(div)으로 나눈 뒤

각 구역을 다시 세부적으로 나누는 방법입니다.

우선 저는 <main> 영역을 크게 아래와 같이 나눠보겠습니다.

HTML div 레이아웃 나누기 - HTML div leiaus nanugi

구역을 나눴으니 이제 위의 레이아웃을 구현하기 위한 방법을 선택해야합니다.

1. width, height, position 설정

2. flex 박스

3. grid 시스템

이전 글에서도 말씀드렸지만

세가지 중 어느 한가지 기술이 반드시 필요한 경우는 없어요.

자신이 가장 잘 활용할 수 있는 기술을 사용하면 됩니다.

(grid 시스템이 가장 선호되긴합니다.)

저는 사진 속 8구역을 나누는 작업은 grid 시스템을,

각 구역 내부에서의 작업은 flex 박스를 사용해볼게요.

index.html - main

<main>
  <div class="main-container">
    <div class="temp-box">1</div>
    <div class="temp-box">2</div>
    <div class="temp-box">3</div>
    <div class="temp-box">4</div>
    <div class="temp-box">5</div>
    <div class="temp-box">6</div>
    <div class="temp-box">7</div>
    <div class="temp-box">8</div>
  </div>
</main>

main.css

main {
  background: #f2f4f7;
  min-height: 700px;
}
.main-container {
  width: 1080px;
  margin: auto;
  display: grid;
  grid-template-columns: 740px 330px; /* 각 행(세로줄)의 길이 */
  grid-template-rows: 120px 310px 890px 130px; /* 각 열(가로줄)의 길이 */
  gap: 10px; /* 자식요소간의 간격 */
}
.temp-box {
  background: yellow;
  width: 100%;
  height: 100%;
  font-size: 40px;
  border: 1px solid #dee3eb;
  text-align: center;
}
HTML div 레이아웃 나누기 - HTML div leiaus nanugi
8개 구역으로 나누기

다음으로

위쪽의 네이버 사이트를 자세히 보면

3번구역과 4번구역이 각각 두 부분으로 나뉘어져 있어요.

이 영역들을 각각 3-1, 3-2 / 4-1, 4-2로

flex 박스를 사용해서 나눠보겠습니다.

index.html - main

<main>
  <div class="main-container">
    <div class="temp-box">1</div>
    <div class="temp-box">2</div>
    <div class="temp-box box-three">
      <div class="border-dee3eb">3-1</div>
      <div class="gap-box"></div> <!-- 3-1과 3-2 사이 -->
      <div class="border-dee3eb">3-2</div>
    </div>
    <div class="temp-box box-four">
      <div class="border-dee3eb">4-1</div>
      <div class="gap-box"></div>
      <div class="border-dee3eb">4-2</div>
    </div>
    <div class="temp-box">5</div>
    <div class="temp-box">6</div>
    <div class="temp-box">7</div>
    <div class="temp-box">8</div>
  </div>
</main>

main.css

main {
  background: #f2f4f7;
  min-height: 700px;
}
.main-container {
  width: 1080px;
  margin: auto;
  display: grid;
  grid-template-columns: 740px 330px;
  grid-template-rows: 120px 310px 890px 130px;
  gap: 10px; /* 구역간의 간격 */
}
.temp-box {
  background: yellow;
  width: 100%;
  height: 100%;
  font-size: 40px;
  border: 1px solid #dee3eb;
  text-align: center;
}
.box-three {
  display: flex;
  flex-direction: column; /* 세로 정렬 */
  border: none; /* border를 지우고 3-1과 3-2에 각각 border를 적용해줍니다. */
}
.box-three > div:first-child {
  width: 100%;
  flex: 1; /* 공간차지비율 */
}
.box-three > div:last-child {
  width: 100%;
  flex: 8; /* 공간차지비율 */
}
.box-four {
  display: flex;
  flex-direction: column;
  border: none;
}
.box-four > div:first-child {
  flex: 1;
}
.box-four > div:last-child {
  flex: 1;
}

global.css

/* 생략 */

.gap-box {
  background: #f2f4f7;
  height: 10px;
}
.border-dee3eb {
  border: 1px solid #dee3eb;
}
HTML div 레이아웃 나누기 - HTML div leiaus nanugi

완성되었습니다.

여기까지 큰 단위부터 하나씩 나눠가는 방법이었는데요,

눈에 보이는대로 하나씩 나눠가는 방법이기 때문에 비교적 쉽게 레이아웃을 정의할 수 있습니다.


2. grid cell

화면을 grid cell이라는 최소단위의 균일한 블록으로 나눈 뒤

cell들을 각 영역에 할당해주는 방식입니다.

개념이 생소하니 그림으로 볼게요.

HTML div 레이아웃 나누기 - HTML div leiaus nanugi

위에서 첫번째 방법으로 나눴던 최종 레이아웃입니다.

위 레이아웃을 만들기 위해 <main> 영역전체를 X * Y 의 균일한 cell들로 나눠줍니다.

(각 영역의 최대공약수 뭐시기로 나눠주시면 됩니다)

HTML div 레이아웃 나누기 - HTML div leiaus nanugi

가로 3개 * 세로 24개 = 총 72개의 cell들로 나뉘어졌습니다.

계산이 끝났으니

grid 시스템으로 적용해줍니다.

index.html - main

<main>
  <div class="main-container">
  </div>
</main>

main.css

main {
  background: #f2f4f7;
  min-height: 700px;
}
.main-container {
  width: 1080px;
  margin: auto;
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* 균일한 크기로 3등분 */
  grid-template-rows: repeat(24, 40px); /* 40px로 24등분 -> <main> 영역의 전체 height가 계산된다면 height 지정 후 1fr로 사용하셔도 좋습니다.*/
}

개발자콘솔(F12)을 열어서 <div class="main-container> 요소를 확인해봅니다.

HTML div 레이아웃 나누기 - HTML div leiaus nanugi
개발자콘솔(F12) - main-container

해당요소의 코드에 마우스를 올리면 grid system에 의해 나뉘어진 구역을 확인할 수 있습니다.

다음으로

1번부터 8번구역까지 다음 순서대로 각 cell을 할당해주면 됩니다.

- <div>를 생성합니다.

index.html - main

<main>
  <div class="main-container">
    <div class="temp-box box-one">1</div>
  </div>
</main>

- box-one 클래스에 grid-column과 grid-row 속성으로 cell을 할당해줍니다.

main.css

main {
  background: #f2f4f7;
}
.main-container {
  width: 1080px;
  margin: auto;
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* 균일한 크기로 3등분 */
  grid-template-rows: repeat(24, 40px); /* 40px로 24등분 -> <main> 영역의 전체 height가 계산된다면 height 지정 후 1fr로 사용하셔도 좋습니다.*/
  gap: 10px;
}
.temp-box {
  background: skyblue;
  text-align: center;
  font-size: 30px;
  border: 1px solid #dee3eb;
}
.box-one {
  grid-column: 1 / 3; /* 시작column번호 / 끝column번호 */
  grid-row: 1 / 3; /* 시작row번호 / 끝row번호 */
}

아래 그림의 column번호와 row번호를 참고하시면서

얼만큼의 cell을 할당할지 설정해주면됩니다.

HTML div 레이아웃 나누기 - HTML div leiaus nanugi
column, row 번호
HTML div 레이아웃 나누기 - HTML div leiaus nanugi
box-one

같은 방식으로 2번째 구역부터 8번째 구역까지 cell을 할당합니다.

index.html - main

<main>
  <div class="main-container">
    <div class="temp-box box-one">1</div>
    <div class="temp-box box-two">2</div>
    <div class="temp-box box-three-1">3-1</div>
    <div class="temp-box box-three-2">3-2</div>  
    <div class="temp-box box-four-1">4-1</div>
    <div class="temp-box box-four-2">4-2</div>
    <div class="temp-box box-five">5</div>
    <div class="temp-box box-six">6</div>
    <div class="temp-box box-seven">7</div>
    <div class="temp-box box-eight">8</div>
  </div>
</main>

main.css

main {
  background: #f2f4f7;
}
.main-container {
  width: 1080px;
  margin: auto;
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* 균일한 크기로 3등분 */
  grid-template-rows: repeat(24, 40px); /* 40px로 24등분 -> <main> 영역의 전체 height가 계산된다면 height 지정 후 1fr로 사용하셔도 좋습니다.*/
  gap: 10px;
}
.temp-box {
  background: skyblue;
  text-align: center;
  font-size: 30px;
  border: 1px solid #dee3eb;
}
.box-one {
  grid-column: 1 / 3;
  grid-row: 1 / 3;
}
.box-two {
  grid-column: 3 / 4;
  grid-row: 1 / 3;
}
.box-three-1 {
  grid-column: 1 / 3;
  grid-row: 3 / 4;
}

.box-three-2 {
  grid-column: 1 / 3;
  grid-row: 4 / 7;
}
.box-four-1 {
  grid-column: 3 / 4;
  grid-row: 3 / 5;
}
.box-four-2 {
  grid-column: 3 / 4;
  grid-row: 5 / 7;
}
.box-five {
  grid-column: 1 / 3;
  grid-row: 7 / 23;
}
.box-six {
  grid-column: 3 / 4;
  grid-row: 7 / 23;
}
.box-seven {
  grid-column: 1 / 3;
  grid-row: 23 / 25;
}
.box-eight {
  grid-column: 3 / 4;
  grid-row: 23 / 25;
}

grid system에는 더 편하게 작업할 수 있는

shorthand property들이 많으니 문서를 확인하면서 만드시길 권장합니다.

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout

실행화면입니다.

HTML div 레이아웃 나누기 - HTML div leiaus nanugi
grid system 최종

이렇게 두번째 방법처럼 cell로 나눈 후 구역에 할당하는 경우에는

cell의 할당량에 따라 레이아웃이 자유롭게 변화될 수 있기 때문에

반응형 디자인이나 확장 및 수정이 용이한 코드가 완성됩니다.

-끝-


최종코드 입니다.(두번째 방법 적용 후)

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>레이아웃 잡기</title>
    <link rel="stylesheet" type="text/css" href="/css/header.css">
    <link rel="stylesheet" type="text/css" href="/css/main.css">
    <link rel="stylesheet" type="text/css" href="/css/footer.css">
    <link rel="stylesheet" type="text/css" href="/css/global.css">
  </head>
  <body>
    <header>
      <div class="links">
        <a href="/" class="link_text">네이버를 시작페이지로</a>
        <a href="/" class="link_text">쥬니어네이버</a>
        <a href="/" class="link_text">해피빈</a>
      </div>
      <a href="/"><img src="images/naver_logo.png" class="img_logo"/></a>
      <form>
        <!-- 웹접근성 향상을 위해 fieldset과 legend를 사용해주는 것이 좋습니다. 
              두 요소의 기본 디자인을 숨기는 방법은 CSS(.visually-hidden)를 참고해주세요-->
        <fieldset>
          <legend class="visually-hidden">검색</legend>
          <div class="search_box">
            <input type="text" maxlength="225" tabindex="1" />
            <button type="submit" tabindex="2">
              검색
            </button>
          </div>
        </fieldset>
      </form>
      <nav>
        <div class="nav_items">
          <ul>
            <li><a href="/">메일</a></li>
            <li><a href="/">카페</a></li>
            <li><a href="/">블로그</a></li>
            <li><a href="/">지식iN</a></li>
            <li><a href="/">쇼핑</a></li>
            <li><a href="/">Pay</a></li>
            <li><a href="/">TV</a></li>
            <li><a href="/">사전</a></li>
            <li><a href="/">뉴스</a></li>
            <li><a href="/">증권</a></li>
            <li><a href="/">부동산</a></li>
            <li><a href="/">지도</a></li>
            <li><a href="/">영화</a></li>
            <li><a href="/">뮤직</a></li>
            <li><a href="/">책</a></li>
            <li><a href="/">웹툰</a></li>
            <li><a href="/">더보기</a></li>
          </ul>
          <div class="keyword">
            <span class="color_naver">1</span>
            <span>Eoldam spark</span></span>
          </div>
        </div>
      </nav>
    </header>
<main>
  <div class="main-container">
    <div class="temp-box box-one">1</div>
    <div class="temp-box box-two">2</div>
    <div class="temp-box box-three-1">3-1</div>
    <div class="temp-box box-three-2">3-2</div>  
    <div class="temp-box box-four-1">4-1</div>
    <div class="temp-box box-four-2">4-2</div>
    <div class="temp-box box-five">5</div>
    <div class="temp-box box-six">6</div>
    <div class="temp-box box-seven">7</div>
    <div class="temp-box box-eight">8</div>
  </div>
</main>
    <footer>
      <div class="notice_box">
        <a href="/">공지사항</a>
        <a href="/">서비스 전체보기></a>
      </div>
      <div class="aside_box">
        <div class="area_user">
          <div class="area_user_row">
            <span class="text_bold-13">Creators</span>
            <ul>
              <li><a href="/">크리에이터</a></li>
              <li><a href="/">스몰비즈니스</a></li>
            </ul>
          </div>
          <div class="area_user_row">
            <span class="text_bold-13">Partners</span>
            <ul>
              <li><a href="/">비즈니스 광고</a></li>
              <li><a href="/">스토어 개설</a></li>
              <li><a href="/">지역업체 등록</a></li>
            </ul>
          </div>
          <div class="area_user_row">
            <span class="text_bold-13">Developers</span>
            <ul>
              <li><a href="/">네이버 개발자센터</a></li>
              <li><a href="/">오픈API</a></li>
              <li><a href="/">오픈소스</a></li>
              <li><a href="/">네이버 D2</a></li>
              <li><a href="/">네이버 D2SF</a></li>
              <li><a href="/">네이버 랩스</a></li>
            </ul>
          </div>
        </div>
        <div class="area_col">
          <div class="ac_content">
            <div class="text_bold-13">웨일 브라우저</div>
            <div class="ac_link"><a href="/">다운받기</a></div>
          </div>
          <a href="/"><img src="images/icon_whale.png" class="ac_img"/></a>
        </div>
        <div class="area_col">
          <div class="ac_content">
            <div class="text_bold-13">프로젝트 꽃</div>
            <div class="ac_link"><a href="/">바로가기</a></div>
          </div>
          <a href="/"><img src="images/icon_flower.png" class="ac_img"/></a>
        </div>
      </div>
      <div class="bottom_box">
        <ul>
          <li><a href="/">회사소개</a></li>
          <li><a href="/">인재채용</a></li>
          <li><a href="/">제휴제안</a></li>
          <li><a href="/">이용약관</a></li>
          <li><a href="/">개인정보처리방침</a></li>
          <li><a href="/">청소년보호정책</a></li>
          <li><a href="/">네이버 정책</a></li>
          <li><a href="/">고객센터</a></li>
          <li><a href="/">&copy; NAVER Corp.</a></li>
        </ul>
      </div>
    </footer>
  </body>
</html>

header.css

header {
  margin: auto; /* header의 양쪽 여백(margin)을 동등하게 맞춤 -> 수평가운데정렬 */
  width: 1080px;
  height: 215px;
  display: flex;
  align-items: center; /* 하위 요소들 수직 가운데정렬 */
  position: relative;
}
fieldset {
  border: none; /* 기본 border 없애기(이 코드를 지우고 기본 border를 확인해보세요) */
}
.visually-hidden {
  position: absolute !important;
  height: 1px;
  width: 1px;
  overflow: hidden;
  clip: rect(1px 1px 1px 1px);
  clip: rect(1px, 1px, 1px, 1px);
  white-space: nowrap;
}
.links {
  /* 링크들을 상단 우측에 위치시킵니다. */
  position: absolute;
  top: 0;
  right: 0;
}
.links .link_text {
  font-size: 12px;
  margin-left: 5px;
}
.img_logo {
  margin-bottom: 12px;
  width: 220px;
  height: 65px;
}
.search_box {
  width: 520px;
  height: 50px;
  border: 2px solid #03cf5d;
  display: flex;
  align-items: center;
}
.search_box input {
  flex: 9; /* search-box내부에서 9만큼의 크기를 차지(비율) */
  height: 46px;
  padding-left: 12px;
  padding-right: 12px;
  border: none;
  outline: none;
  font-size: 18px;
}
.search_box button {
  flex: 1; /* search-box내부에서 1만큼의 크기를 차지(비율) */
  height: 46px;
  margin: 0;
  padding: 0;
  border: none;
  outline: none;
  background: #03cf5d;
  color: #ffffff;
}
/* nav */
header > nav {
  width: 100%;
  height: 45px;
  position: absolute;
  bottom: 0;
}
.nav_items {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 15px;
  font-weight: bold;
  border-top: 1px solid #f1f3f6;
}
.keyword {
  width: 200px;
}
.nav_items ul > li {
  display: inline-block;
  margin-left: 8px;
}
.nav_items ul > li:nth-child(-n + 7) > a {
  /* <ul>하위 7번째 <li>까지 각각 내부의 <a> 태그 접근 */
  color: #03cf5d;
}
.nav_items ul > li > a {
  text-decoration: none;
  cursor: pointer;
}

main.css

main {
  background: #f2f4f7;
  min-height: 700px;
}
.main-container {
  width: 1080px;
  margin: auto;
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* 균일한 크기로 3등분 */
  grid-template-rows: repeat(24, 40px); /* 40px로 24등분 -> <main> 영역의 전체 height가 계산된다면 height 지정 후 1fr로 사용하셔도 좋습니다.*/
  gap: 10px;
}
.temp-box {
  background: skyblue;
  text-align: center;
  font-size: 30px;
  border: 1px solid #dee3eb;
}
.box-one {
  grid-column: 1 / 3;
  grid-row: 1 / 3;
}
.box-two {
  grid-column: 3 / 4;
  grid-row: 1 / 3;
}
.box-three-1 {
  grid-column: 1 / 3;
  grid-row: 3 / 4;
}

.box-three-2 {
  grid-column: 1 / 3;
  grid-row: 4 / 7;
}
.box-four-1 {
  grid-column: 3 / 4;
  grid-row: 3 / 5;
}
.box-four-2 {
  grid-column: 3 / 4;
  grid-row: 5 / 7;
}
.box-five {
  grid-column: 1 / 3;
  grid-row: 7 / 23;
}
.box-six {
  grid-column: 3 / 4;
  grid-row: 7 / 23;
}
.box-seven {
  grid-column: 1 / 3;
  grid-row: 23 / 25;
}
.box-eight {
  grid-column: 3 / 4;
  grid-row: 23 / 25;
}

footer.css

footer {
  width: 1080px;
  height: 310px;
  margin: auto;
  padding: 0 8px 0 8px; /* 각각 위 오른쪽 아래 왼쪽 */
  display: flex;
  flex-direction: column; /* 요소들을 수평정렬 */
  font-size: 12px;
}
.notice_box {
  flex: 1;
  display: flex;
  justify-content: space-between; /* 양끝 정렬 */
  align-items: center;
  border-bottom: 1px solid #f1f3f6;
}
.notice_box a {
  font-weight: bold;
  color: black;
}
.aside_box {
  flex: 2;
  display: flex;
  align-items: center;
  border-bottom: 1px solid #f1f3f6;
}
.area_user {
  flex: 4;
  line-height: 2em; /* 줄간격 */
}
.area_user_row {
  display: flex;
}
.area_user_row span {
  flex: 1;
}
.area_user_row ul {
  flex: 6;
}
.aur_title {
  font-size: 13px;
  font-weight: bold;
}
.area_user_row ul > li {
  display: inline-block; /* li 수평정렬하는 방법 */
  margin-left: 8px;
}
.area_col {
  flex: 1;
  display: flex;
}
.area_col .ac_content {
  line-height: 20px;
}
.area_col .ac_img {
  width: 60px;
  height: 60px;
}
.bottom_box {
  flex: 3;
  padding-top: 20px;
  font-size: 14px;
}
.bottom_box ul > li {
  display: inline-block; /* 수평정렬 */
  margin-left: 8px;
}
.bottom_box ul > li:last-child {
  /* 마지막 li요소 (Naver Corp.) 굵게 */
  font-weight: bold;
}

global.css

body {
  margin: 0;
  font-family: sans-serif;
}
a {
  text-decoration: none;
  color: #888;
}
a:hover {
  text-decoration: underline;
}
ul {
  margin: 0;
  padding: 0;
}
* {
  box-sizing: border-box; /* 길이 계산을 편하게 하기위함. box-sizing에 관한 설명은 아래 링크를 참고해주세요 */
}
/* 재사용 클래스 */
.color_naver {
  color: #03cf5d;
}
.text_bold-13 {
  font-weight: bold;
  font-size: 13px;
}