Layout

divedeepp·2022년 2월 18일
0

CSS3

목록 보기
18/21
post-thumbnail

Layout?

과거에는 table을 사용하여 layout을 만들었지만, HTML과 CSS의 역할의 완전한 분리와 모바일이나 데스크탑 등 화면의 크기에 따라 적절히 화면 구성을 변화시키는 반응형 웹 디자인 또한 모던 웹 사이트의 필수 사항이 되었다.

현재의 웹 페이지는 CSS를 사용하여 style과 layout을 구성하는 것이 일반적이다.

layout이란 웹사이트를 구성하는 element들을 배치할 공간을 분할하고 정렬하는 것이다. 공간을 분할할 때는 먼저 행을 구분한 후, 행 내부 element를 분리하는 것이 일반적이다.

layout의 핵심은 block level element들을 원하는 위치에 배열하는 것이다.

CSS를 사용하여 layout을 구성할 때, 자주 사용되는 핵심 기술은 float 이다.

아래의 코드는 2 column layout의 일반적인 구조이다.

<!DOCTYPE html>
<html>
<body>
  <div id="wrap">
    <header>
      <nav>
        <ul>
          <li>...</li>
          <li>...</li>
        </ul>
      </nav>
    </header>
    <div id="content-wrap">
      <aside>
        <ul>
          <li>...</li>
          <li>...</li>
        </ul>
      </aside>
      <section>
        <article>...</article>
        <article>...</article>
      </section>
    </div>
    <footer></footer>
  </div>
</body>
</html>

위 구조를 바탕으로 레이아웃을 구성하는 한 파트씩 살펴보자.


Header & Navigation Bar

Navigation bar는 웹사이트의 필수 구성 요소라 할 수 있다.

Navigation bar는 기본적으로 링크들의 리스트이다. 따라서, <ul>, <li> tag를 이용하여 작성하는 것이 일반적이다.

천천히 Navigation bar를 구현해보자.

  1. 최소한의 Reset CSS를 추가한 링크들의 리스트를 만들자. 직관적인 box model을 위해 box-sizing: border-box; 을 지정했다. 실제 웹사이트를 구축할 시에 Reset CSS를 좀 더 정교하게 초기화해야 한다.
<!DOCTYPE html>
<html>
<head>
  <style>
    /* Simple Reset CSS */
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    body {
      font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
      color: #58666e;
      background-color: #f0f3f4;
    }
    li {
      list-style: none;
    }
    a {
      text-decoration: none;
    }
  </style>
</head>
<body>
  <div id="wrap">
    <header>
      <a class="logo" href="#home">
        <img src="https://poiemaweb.com/img/logo.png" height="36px">
      </a>
      <nav>
        <ul class="nav-items">
          <li><a href="#home">Home</a></li>
          <li><a href="#news">News</a></li>
          <li><a href="#contact">Contact</a></li>
          <li><a href="#about">About</a></li>
        </ul>
      </nav>
    </header>
  </div>
</body>
</html>

  1. <header> element에 화면폭 만큼의 width와 고정 height를 지정한다. background-colorbox-shadow 효과도 추가한다. 그리고, float property를 이용해 navigation bar를 우측 정렬한다.
header {
  width: 100%;
  height: 60px;
  z-index: 2000;
  background-color: #fff;
  box-shadow: 0 2px 2px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(0, 0, 0, 0.05);
}
nav {
  float: right;
}

  1. 다음은 logo 이미지를 수직으로 중앙 정렬한다. logo 이미지를 포함하는 <a> tag의 height를 logo 이미지와 같은 height인 36px로 지정하고 상하 margin을 12px 씩 부여하면 높이는 60px이 되고, <header> element의 height와 같아져 이미지는 수직 중앙 정렬된다. <a> tag는 inline level element이므로, margin을 정의하기 위해 display: inline-block; 을 설정한다. 또한, <img> tag에 부여한 height attribute를 CSS로 옮긴다.
.logo {
  display: inline-block;
  height: 36px;
  margin: 12px 0 12px 25px;
}
.logo > img { height: 36px; }

  1. 수직 정렬되어 있는 navigation bar를 수평 정렬한다. block level element인 <li> element에 display: inline-block; 을 설정하여 inline level element처럼 가로로 정렬시킨다.
.nav-items > li {
  display: inline-block;
}

  1. 수평 정렬된 navigation bar를 수직 중앙 정렬한다. line-height: 60px;를 설정해서 텍스트의 높이를 <header> element의 height와 동일하게 60px로 고정시킨다. 그리고, 텍스트 간의 적당한 간격 유지를 위해 padding을 정의한다.
.nav-items > li > a {
  line-height: 60px;
  padding: 0 30px;
  color: rgba(0, 0, 0, 0.4);
}

  1. 마우스가 navigation bar 위에 올라오면 navigation item의 색상이 변경되도록 :hover를 설정한다.
.nav-items > li > a:hover {
  color: rgba(0, 0, 0, 0.8);
}

아래는 완성된 navigation bar의 예제 코드이다.

<!DOCTYPE html>
<html>
<head>
  <style>
    /* Simple Reset CSS */
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    body {
      font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
      color: #58666e;
      background-color: #f0f3f4;
    }
    li {
      list-style: none;
    }
    a {
      text-decoration: none;
    }
    header {
      width: 100%;
      height: 60px;
      z-index: 2000;
      background-color: #fff;
      box-shadow: 0 2px 2px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(0, 0, 0, 0.05);
    }
    nav {
      float: right;
    }
    .logo {
      display: inline-block;
      height: 36px;
      margin: 12px 0 12px 25px;
    }
    .logo > img { height: 36px; }
    .nav-items > li {
      display: inline-block;
    }
    .nav-items > li > a {
      line-height: 60px;
      padding: 0 30px;
      color: rgba(0,0,0,0.4);
    }
    .nav-items > li > a:hover {
      color: rgba(0,0,0,0.8);
    }
  </style>
</head>
<body>
  <div id="wrap">
    <header>
      <a class="logo" href="#home">
        <img src="https://poiemaweb.com/img/logo.png">
      </a>
      <nav>
        <ul class="nav-items">
          <li><a href="#home">Home</a></li>
          <li><a href="#news">News</a></li>
          <li><a href="#contact">Contact</a></li>
          <li><a href="#about">About</a></li>
        </ul>
      </nav>
    </header>
  </div>
</body>
</html>

Section & Aside

컨텐츠의 영역을 section, 컨텐츠에 대한 navigation item이나 부가 정보 영역을 aside라 한다. section 영역은 다시 article 영역으로 구분할 수 있다.

위 두 개의 영역은 float property를 사용해서 수평 정렬하는 것이 일반적이다.

  1. <header> element 뒤에 <aside>, <section>, <article>을 포함하는 <div> element를 정의한다. id는 content-wrap으로 명시한다.
<div id="content-wrap">
  <aside>
    <h1>Aside</h1>
    <ul>
      <li><a href="#" class="active">London</a></li>
      <li><a href="#">Paris</a></li>
      <li><a href="#">Tokyo</a></li>
      <li><a href="#">Newyork</a></li>
    </ul>
  </aside>
  <section>
    <article id="london">
      <h1>London</h1>
      <p>...</p>
    </article>
    <article id="paris">
      <h1>Paris</h1>
      <p>...</p>
    </article>
    <article id="tokyo">
      <h1>Tokyo</h1>
      <p>...</p>
    </article>
    <article id="newyork">
      <h1>Newyork</h1>
      <p>...</p>
    </article>
  </section>
<!-- end of content-wrap   -->
</div>

  1. aside을 좌측 정렬, section을 우측 정렬한다. 이 때 float property를 가진 <aside>, <section> element를 감싸는 content-wrap id를 가진 <div> element에 clearfix를 부여하여 float property가 선언된 두 개의 자식 element를 포함하는 부모 element의 높이가 정상적인 값을 가지지 못하는 문제를 해결해야 한다.
/* clearfix */
#content-wrap:after {
  content: "";
  display: block;
  clear: both;
}
aside {
  float: left;
  width: 20%;
}
section {
  float: right;
  width: 80%;
}

두 개의 block 영역이 수평 정렬되었고, content-wrap element도 정상적인 높이를 가지게 되었다. 그런데 아래 그림처럼 화면을 아래로 스크롤하면 header 영역도 따라 올라가버려 navigation bar가 사라지는 현상이 발생한다.

  1. navigation bar를 화면 상단에 고정시키자. fixed property를 사용해서 <header> element를 상단에 고정시킨다. fixed property는 부모 element와 관계없이 브라우저의 viewport를 기준으로 좌표 property(top, bottom, left, right)을 사용해서 위치를 이동시킨다. 스크롤이 되더라도 화면에서 사라지지 않고 항상 같은 곳에 위치한다.
header {
  /* for sticky header */
  position: fixed;
  top: 0;
  ...
}

content 영역 상단이 header 영역과 겹치므로 content 영역을 header의 height 만큼 아래로 내린다.

#content-wrap {
  /* margin-top = header height */
  margin-top: 60px;
}

  1. 이제 header 영역은 고정되었다. 그런데 화면이 스크롤될 때 좌측 aside의 navigation이 사라지는 것은 마찬가지로 불편할 수 있따. aside 영역도 고정시키자. float: left; 를 삭제하고, header와 같이 position: fixed; 를 추가한다. %로 지정했던 width도 고정폭으로 변경한다. 이 때, section 영역의 % width도 삭제하여 aside 영역만큼 우측으로 밀어서 나머지 영역을 모두 차지하도록 한다.
aside {
  /* for fixed side bar */
  position: fixed;
  top: 60px;
  bottom: 0;

  width: 200px;
}
section {
  float: right;
  margin-left: 200px;
}

  1. 다음은 aside navigation의 스타일을 정의한다. active 상태의 item을 컬러로 구분할 수 있게하고, hover 상태일 때도 컬러로 구분할 수 있게 한다. 또, 텍스트의 스타일도 정의한다.
aside {
  /* for fixed side bar */
  position: fixed;
  top: 60px;
  bottom: 0;

  width: 200px;
  padding-top: 25px;
  background-color: #333;
}
/* aside navigation */
aside > ul {
  width: 200px;
}
aside > ul > li > a {
  display: block;
  color: #fff;
  padding: 10px 0 10px 20px;
}
aside > ul > li > a.active {
  background-color: #4CAF50;
}
aside > ul > li > a:hover:not(.active) {
  background-color: #555;
}
aside > h1 {
  padding: 20px 0 20px 20px;
  color: #fff;
}
/* Section */
section {
  float: right;
  /* aside width */
  margin-left: 200px;
}
article {
  margin: 10px;
  padding: 25px;
  background-color: white;
}

heading tag(h1)의 크기가 위치한 영역에 따라 다를 수 있다. 즉, <header> 내의 <h1><section> 내의 <h1> 보다 크다. 이것을 방지하기 위해 Reset CSS에 다음의 코드를 추가한다. 크기는 적당히 조절하고, 다른 텍스트 태그의 스타일도 정의한다.

h1 { font-size: 1.8em; }
h1, h2, h3, h4, h5, h6, p {
  margin: 10px 5px;
}


Footer

id가 content-wrap으로 설정된 <div> element 다음에 <footer> element를 배치한다.

<footer>© Copyright 2016 ungmo2</footer>

footer도 고정되어 있을 필요가 있지만, 본문을 가리면 안된다. 따라서, position property에 fixed를 설정하지 않는다. 대신 absolute를 설정한다. absolute를 설정하면 다른 element가 먼저 위치를 점유하고 있어도 뒤로 밀리지 않고 덮어쓰게 된다.

footer {
  /* footer를 aside위에 올리기 위해 사용(부유객체) */
  position: absolute;
  height: 60px;
  width: 100%;
  padding: 0 25px;
  line-height: 60px;
  color: #8a8c8f;
  border-top: 1px solid #dee5e7;
  background-color: #f2f2f2;
}


완성된 웹페이지 레이아웃

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <style>
    /* Simple Reset CSS */
    * {
      margin: 0; padding: 0;
      box-sizing: border-box;
    }
    body {
      font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
      color: #58666e;
      background-color: #f0f3f4;
      -webkit-font-smoothing: antialiased;
      -webkit-text-size-adjus: 100%;  /* iphone font size 변경 방지 */
    }
    li { list-style: none; }
    a { text-decoration: none; }
    h1, h2, h3, h4, h5, h6, p {
      margin: 10px 5px;
    }
    h1 { font-size: 1.8em; }

    #wrap {
      width: 100%;
      /* margin-top = header height */
      margin-top: 60px;
    }

    /* Navigation bar */
    header {
      /* for sticky header */
      position: fixed;
      top: 0;

      width: 100%;
      height: 60px;
      z-index: 2000;
      background-color: #fff;
      box-shadow: 0 2px 2px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(0, 0, 0, 0.05);
    }
    .logo {
      display: inline-block;
      height: 36px;
      margin: 12px 0 12px 25px;
    }
    .logo > img { height: 36px; }
    nav {
      float: right;
    }
    .nav-items {
      margin-right: 20px;
    }
    .nav-items > li {
      display: inline-block;  /* 가로정렬 */
    }
    .nav-items > li > a {
      /* for Vertical Centering */
      line-height: 60px;
      padding: 0 30px;
      color: rgba(0, 0, 0, 0.4);
    }
    .nav-items > li > a:hover {
      color: rgba(0, 0, 0, 0.8);
    }

    /* contents */
    /* clearfix */
    #content-wrap:after {
      content: "";
      display: block;
      clear: both;
    }
    aside {
      /* for fixed side bar */
      position: fixed;
      top: 60px;
      bottom: 0;
      width: 200px;  /* 너비 고정 */
      padding-top: 25px;
      background-color: #333;
    }
    /* aside navigation */
    aside > ul {
      width: 200px;
    }
    aside > ul > li > a {
      display: block;
      color: #fff;
      padding: 10px 0 10px 20px;
    }
    aside > ul > li > a.active {
      background-color: #4CAF50;
    }
    aside > ul > li > a:hover:not(.active) {
      background-color: #555;
    }
    aside > h1 {
      padding: 20px 0 20px 20px;
      color: #fff;
    }
    /* Section */
    section {
      float: right;
      /* aside width */
      margin-left: 200px;
    }
    article {
      margin: 10px;
      padding: 25px;
      background-color: white;
    }
    /* footer */
    footer {
      /* footer를 aside위에 올리기 위해 사용(부유객체) */
      position: absolute;
      height: 60px;
      width: 100%;
      padding: 0 25px;
      line-height: 60px;
      color: #8a8c8f;
      border-top: 1px solid #dee5e7;
      background-color: #f2f2f2;
    }
  </style>
</head>
<body>
  <div id="wrap">
    <header>
      <a class="logo" href="#home"><img src="https://poiemaweb.com/img/logo.png"></a>
      <nav>
        <ul class="nav-items">
          <li><a href="#home">Home</a></li>
          <li><a href="#news">News</a></li>
          <li><a href="#contact">Contact</a></li>
          <li><a href="#about">About</a></li>
        </ul>
      </nav>
    </header>

    <div id="content-wrap">
      <aside>
        <h1>Aside</h1>
        <ul>
          <li><a href="#" class="active">London</a></li>
          <li><a href="#">Paris</a></li>
          <li><a href="#">Tokyo</a></li>
          <li><a href="#">Newyork</a></li>
        </ul>
      </aside>
      <section>
        <article id="london">
          <h1>London</h1>
          <p>London is the capital city of England. It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants.</p>
          <p>Standing on the River Thames, London has been a major settlement for two millennia,its history going back to its founding by the Romans, who named it Londinium.</p>
          <p>London, also referred to as Greater London, is one of 9 regions of England and the top-level subdivision covering most of the city's metropolis. The small ancient City of London at its core once comprised the whole settlement, but as its urban area grew, the Corporation of London resisted attempts to amalgamate the city with its suburbs, causing "London" to be defined in a number ways for different purposes.</p>
        </article>
        <article id="paris">
          <h1>Paris</h1>
          <p>London is the capital city of England. It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants.</p>
          <p>Standing on the River Thames, London has been a major settlement for two millennia,its history going back to its founding by the Romans, who named it Londinium.</p>
          <p>London, also referred to as Greater London, is one of 9 regions of England and the top-level subdivision covering most of the city's metropolis. The small ancient City of London at its core once comprised the whole settlement, but as its urban area grew, the Corporation of London resisted attempts to amalgamate the city with its suburbs, causing "London" to be defined in a number ways for different purposes.</p>
        </article>
        <article id="tokyo">
          <h1>Tokyo</h1>
          <p>London is the capital city of England. It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants.</p>
          <p>Standing on the River Thames, London has been a major settlement for two millennia,its history going back to its founding by the Romans, who named it Londinium.</p>
          <p>London, also referred to as Greater London, is one of 9 regions of England and the top-level subdivision covering most of the city's metropolis. The small ancient City of London at its core once comprised the whole settlement, but as its urban area grew, the Corporation of London resisted attempts to amalgamate the city with its suburbs, causing "London" to be defined in a number ways for different purposes.</p>
        </article>
        <article id="newyork">
          <h1>Newyork</h1>
          <p>London is the capital city of England. It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants.</p>
          <p>Standing on the River Thames, London has been a major settlement for two millennia,its history going back to its founding by the Romans, who named it Londinium.</p>
          <p>London, also referred to as Greater London, is one of 9 regions of England and the top-level subdivision covering most of the city's metropolis. The small ancient City of London at its core once comprised the whole settlement, but as its urban area grew, the Corporation of London resisted attempts to amalgamate the city with its suburbs, causing "London" to be defined in a number ways for different purposes.</p>
        </article>
      </section>
      <!-- end of content-wrap -->
    </div>
    <footer>© Copyright 2016 ungmo2</footer>
  <!-- end of wrap   -->
  </div>
</body>
</html>

레이아웃을 구성해 하나의 웹페이지를 완성했지만, 몇 가지 문제가 남아있다. 이는 반응형 웹으로 해결할 수 있다.


참고문헌

https://poiemaweb.com/css3-layout

profile
더깊이

0개의 댓글