이 번역은 완료되지 않았습니다. 이 문서를 번역해 주세요.

이 문서에서는 이전 모듈에서 이미 접했던 CSS 레이아웃 기능 — display 값의 차이와 같은 — 을 간략하게 설명하고, 이 모듈에서 다루는 개념을 소개합니다.

선수과목: HTML의 기초 (HTML 소개),
CSS 작동 방식에 대한 아이디어 (CSS 소개)
목표: CSS 페이지 레이아웃 기법에 대한 개요를 제공합니다.
각각의 기술은 다음 튜토리얼에서 보다 자세하게 학습할 수 있습니다.

CSS 페이지 레이아웃 기법을 통해 웹 페이지에 포함 된 요소를 가져올 수 있습니다. 그리고 그것들은 일반적인 레이아웃 플로우, 주변의 다른 요소, 상위 컨테이너, 메인 뷰포트/창(window)에서 배치되는 position을 제어합니다.  이 모듈에서 다루는 페이지 레이아웃 기법은 다음과 같습니다.

  • Normal flow
  • The display property
  • Flexbox
  • Grid
  • Floats
  • Positioning
  • Table layout
  • Multiple-column layout

각 기법에는 용도와 장단점이 있으며, 독립적으로 사용하도록 설계되진 않았습니다. 각 메서드가 무엇을 위해 설계되었는지 이해하면, 각 작업에 가장 적합한 레이아웃 도구를 이해하는 데 도움이됩니다.

Normal flow

Normal flow는 페이지 레이아웃을 제어하는 어떠한 것도 하지 않으면, 브라우저가 기본적으로 HTML을 레이아웃하는 방법입니다. 간단한 HTML예제를 살펴보겠습니다.

<p>I love my cat.</p>
    
<ul>
  <li>Buy cat food</li>
  <li>Exercise</li>
  <li>Cheer up friend</li>
</ul>
    
<p>The end!</p>

기본적으로 브라우저는이 코드를 다음과 같이 표시합니다.

HTML이 소스 코드에 나타나는 정확한 순서대로 어떻게 표시되는지, 요소가 서로 겹쳐서 표시되는지 확인해보세요 — 첫 번째 단락(<p>), 순서가 없는 목록(<ul>), 두 번째 단락(<p>) 순입니다.

한 단락의 개별 단어와 같이 다른 단어 옆에 하나씩 나타나는 인라인 요소와 대조적으로, 하나 아래에 나타나는 요소는 블록 요소로 설명됩니다.

노트: 블록 요소 컨텐츠가 배치되는 방향은 블록 방향으로 설명됩니다. 블록 방향은 영어와 같이 가로 쓰기 모드이면, 세로 방향으로 실행됩니다. 일본어와 같이 세로 쓰기 모드가 있으면, 가로 방향으로 실행됩니다. 해당 인라인 방향은 인라인 컨텐츠가(문장과 같은)이 실행되는 방향입니다.

CSS를 사용하여 레이아웃을 만들 때, 여러분이 수행하는 작업은 요소를 normal flow에서 멀리 옮기는 것입니다. 그러나 페이지의 많은 요소에서 이 normal flow는 필요한 레이아웃을 정확하게 만듭니다. 이것이 잘 구조화 된 HTML 문서로 시작하는 것이 중요한 이유입니다. 그 다음에는 기본적으로 설정된 방식으로 작업할 수 있습니다.

CSS에서 요소가 배치되는 방식을 변경할 수있는 메서드는 다음과 같습니다.

  • The display propertyblockinlineinline-block 과 같은 표준 값들은 요소가 normal flow에서 작동하는 방식을 변경할 수 있습니다. (자세한 것은 Types of CSS boxes 참조). CSS GridFlexbox와 같은 display 값에 따라 전환되는 전체 레이아웃 메서드를 갖습니다.
  • Floats — float 에 left 와 같은 값을 적용하면, 블록 레벨의 요소가 해당 요소의 한 면과 나란히 감쌀(wrap) 수 있습니다. 잡지 레이아웃에서 때때로 이미지가 텍스트 주위에 떠 있는 방식과 같습니다.
  • The position property — 다른 상자들 안에서 상자 배치를 정확하게 제어할 수 있습니다. normal flow에서 기본값은 static 이지만, 다른 값을 사용하여 요소를 다르게 배치할 수 있습니다. 예를들어, fixed를 사용하면 항상 브라우저 viewport의 좌측 상단에 고정됩니다.
  • Table layout — HTML 테이블을 스타일 지정하기 위한 기능입니다. display: table , 그리고 이와 연관된 속성(property)을 사용하여 테이블이 아닌 요소에 사용할 수 있습니다. 
  • Multi-column layoutMulti-column layout 속성을 사용하면, 신문에서 볼 수 있는 것과 같은 블록 내용을 열(columns) 레이아웃으로 만들 수 있습니다.

The display property

CSS에서 페이지 레이아웃을 달성하는 주요 방법은, 전부 display 속성의 값을 변경하는 것입니다. 이 속성을 사용하면 무언가가 표시되는 기본 방법을 변경할 수 있습니다. normal flow의 모든 것은 display 값을 가지며, 설정 한 요소의 기본 방법으로 사용됩니다. 예를 들어, 영어의 단락이 다른 단락 아래에 표시된다는 사실은 display: block 으로 스타일이 지정 되었기 때문입니다. 단락(p) 안에 일부 텍스트 주위에 링크를 만들면, 해당 링크는 텍스트의 나머지 부분과 함께 인라인 상태로 유지되고, 줄바꿈을 하지 않습니다. <a> 요소의 기본값이 display: inline 이기 때문입니다.

우리는 display 동작의 기본값을 변경할 수 있습니다. 예를들면 <li> 요소의 기본값은 display: block 입니다. 이것은 목록(list) 항목이 영어 문서에서 다른 항목 아래에 하나씩 표시된다는 의미입니다. display값을 inline 으로 변경하면, 문장 속 단어들 처럼 옆으로 나열됩니다. 모든 요소의 display 값을 변경할 수 있다는 사실은, 의미를 나타내는 HTML 요소를 어떻게 보일지 염려하지 않고 선택할 수 있음을 의미합니다. 그들이 보는 방식을 바꿀 수 있습니다.

항목을 block 에서 inline 으로 또는 그 반대로 전환하여 기본 표현을 변경할 수있을뿐만 아니라, display 값으로 시작하는 몇 가지 더 큰 레이아웃 방법이 있습니다. 그러나 이들을 사용할 때 일반적으로 추가 속성을 호출해야합니다. 레이아웃을 논의 할 때 우리의 목적에 가장 중요한 두 가지 값은 display: flexdisplay: grid입니다. 

Flexbox

Flexbox는 Flexible Box Layout Module의 약자로, 행이나 열로 한 차원에 쉽게 배치 할 수 있도록 설계되었습니다. flexbox를 사용하려면 display: flex를 레이아웃하려는 요소의 부모 요소에 적용합니다. 모든 직계 자식 요소들은 플렉스 아이템이 됩니다. 우리는 이것을 간단한 예시로 볼 수 있습니다.

아래의 HTML 마크 업은 wrapper 클래스를 갖고 있는 요소가 있고, 그 안에 <div> 요소가 세 개 있습니다. 기본적으로 이 요소들은 display: block 속성을 가지며, 우리가 아는 영어 문서들처럼 한 요소마다 줄바꿈을 하게 됩니다.

그러나 display: flex를 부모 요소에 추가하면, 세 항목이 열로(한 줄 내에서 단어처럼) 정렬됩니다. 이것은 flex item이 되어 flexbox가 제공하는 초기값을 사용하기 때문입니다.  flex-direction 의 초기 값은 row 이기 때문에, 행으로 표현됩니다. 그것들은 모두 align-items의 초기값이  stretch 이기 때문에, 가장 큰 아이템의 높이까지 늘어나는 것처럼 보입니다. 즉, 아이템이 플렉스 컨테이너의 높이까지 늘어나고, 가장 큰 아이템에 의해 정의된다는 것을 뜻합니다. 아이템은 모두 컨테이너의 시작 부분에 정렬되어, 행 끝에 여분의 공백이 남습니다.

.wrapper {
  display: flex;
}
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three</div>
</div>

플렉스 컨테이너에 적용할 수 있는 위의 속성(properties) 외에도, 플렉스 아이템에 적용할 수 있는 속성이 있습니다. 이러한 속성은 다른 것들과 마찬가지로 아이템이 유연해지는 방식을 바꿀 수 있습니다. 따라서 사용 가능한 공간에 맞게 확장 및 축소할 수 있습니다.

이것의 간단한 예로, flex 속성을 모든 자식 요소에 추가할 수 있습니다. 값은 1 을 넣겠습니다. 이렇게하면 끝 부분에 공간을 남기지 않고, 모든 요소들이 커져서 컨테이너를 가득 채웁니다. 공간이 많으면(컨테이너의 크기가 커지면) 항목이 넓어지고, 공간이 적으면(컨테이너의 크기가 작아지면) 요소가 작아집니다. 게다가 마크업에 다른 아이템(요소)을 추가하면, 아이템의 크기가 작아져서 공간이 확보됩니다. 그리고 요소들의 크기가 조정되어 동일한 공간을 차지합니다.

.wrapper {
    display: flex;
}

.wrapper > div {
    flex: 1;
}
<div class="wrapper">
    <div class="box1">One</div>
    <div class="box2">Two</div>
    <div class="box3">Three</div>
</div>

노트: 이것은 Flexbox에서 가능한 것들 중 아주 짧은 소개였습니다. 자세한 내용은 Flexbox문서를 참조하세요.

Grid Layout

While flexbox is designed for one-dimensional layout, Grid Layout is designed for two dimensions — lining things up in rows and columns.

Once again, you can switch on Grid Layout with a specific value of display — display: grid. The below example uses similar markup to the flex example, with a container and some child elements. In addition to using display: grid, we are also defining some row and column tracks on the parent using the grid-template-rows and grid-template-columns properties respectively. We've defined three columns each of 1fr and two rows of 100px. I don’t need to put any rules on the child elements; they are automatically placed into the cells our grid has created.

.wrapper {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: 100px 100px;
    grid-gap: 10px;
}
<div class="wrapper">
    <div class="box1">One</div>
    <div class="box2">Two</div>
    <div class="box3">Three</div>
    <div class="box4">Four</div>
    <div class="box5">Five</div>
    <div class="box6">Six</div>
</div>

Once you have a grid, you can explicitly place your items on it, rather than relying on the auto-placement behavior seen above. In the second example below we have defined the same grid, but this time with three child items. We've set the start and end line of each item using the grid-column and grid-row properties. This causes the items to span multiple tracks.

.wrapper {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: 100px 100px;
    grid-gap: 10px;
}

.box1 {
    grid-column: 2 / 4;
    grid-row: 1;
}

.box2 {
    grid-column: 1;
    grid-row: 1 / 3;
}

.box3 {
    grid-row: 2;
    grid-column: 3;
}
<div class="wrapper">
    <div class="box1">One</div>
    <div class="box2">Two</div>
    <div class="box3">Three</div>
</div>

Note: These two examples are just a small part of the power of Grid layout; to find out more see our Grid Layout article.

The rest of this guide covers other layout methods, which are less important for the main layout structures of your page but can still help you achieve specific tasks. By understanding the nature of each layout task, you will soon find that when you look at a particular component of your design the type of layout best suited to it will often be clear.

Floats

Floating an element changes the behavior of that element and the block level elements that follow it in normal flow. The element is moved to the left or right and removed from normal flow, and the surrounding content floats around the floated item.

The float property has four possible values:

  • left — Floats the element to the left.
  • right — Floats the element to the right.
  • none — Specifies no floating at all. This is the default value.
  • inherit — Specifies that the value of the float property should be inherited from the element's parent element.

In the example below we float a <div> left, and give it a margin on the right to push the text away from the element. This gives us the effect of text wrapped around that box, and is most of what you need to know about floats as used in modern web design.

<h1>Simple float example</h1>
    
<div class="box">Float</div>
    
<p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci vel, viverra egestas ligula. Curabitur vehicula tellus neque, ac ornare ex malesuada et. In vitae convallis lacus. Aliquam erat volutpat. Suspendisse ac imperdiet turpis. Aenean finibus sollicitudin eros pharetra congue. Duis ornare egestas augue ut luctus. Proin blandit quam nec lacus varius commodo et a urna. Ut id ornare felis, eget fermentum sapien.</p>

    
.box {
    float: left;
    width: 150px;
    height: 150px;
    margin-right: 30px;
}

Note: Floats are fully explained in our lesson on the float and clear properties. Prior to techniques such as Flexbox and Grid Layout floats were used as a method of creating column layouts. You may still come across these methods on the web; we will cover these in the lesson on legacy layout methods.

Positioning techniques

Positioning allows you to move an element from where it would be placed when in normal flow to another location. Positioning isn’t a method for creating your main page layouts, it is more about managing and fine-tuning the position of specific items on the page.

There are however useful techniques for certain layout patterns that rely on the position property. Understanding positioning also helps in understanding normal flow, and what it is to move an item out of normal flow.

There are five types of positioning you should know about:

  • Static positioning is the default that every element gets — it just means "put the element into its normal position in the document layout flow — nothing special to see here".
  • Relative positioning allows you to modify an element's position on the page, moving it relative to its position in normal flow — including making it overlap other elements on the page.
  • Absolute positioning moves an element completely out of the page's normal layout flow, like it is sitting on its own separate layer. From there, you can fix it in a position relative to the edges of the page's <html> element (or its nearest positioned ancestor element). This is useful for creating complex layout effects such as tabbed boxes where different content panels sit on top of one another and are shown and hidden as desired, or information panels that sit off screen by default, but can be made to slide on screen using a control button.
  • Fixed positioning is very similar to absolute positioning, except that it fixes an element relative to the browser viewport, not another element. This is useful for creating effects such as a persistent navigation menu that always stays in the same place on the screen as the rest of the content scrolls.
  • Sticky positioning is a newer positioning method which makes an element act like position: static until it hits a defined offset from the viewport, at which point it acts like position: fixed.

Simple positioning example

To provide familiarity with these page layout techniques, we'll show you a couple of quick examples. Our examples will all feature the same HTML, which is as follows:

<h1>Positioning</h1>

<p>I am a basic block level element.</p>
<p class="positioned">I am a basic block level element.</p>
<p>I am a basic block level element.</p>

This HTML will be styled by default using the following CSS:

body {
  width: 500px;
  margin: 0 auto;
}

p {
    background-color: rgb(207,232,220);
    border: 2px solid rgb(79,185,227);
    padding: 10px;
    margin: 10px;
    border-radius: 5px;
}

The rendered output is as follows:

Relative positioning

Relative positioning allows you to offset an item from the position in normal flow it would have by default. This means you could achieve a task such as moving an icon down a bit so it lines up with a text label. To do this, we could add the following rule to add relative positioning:

.positioned {
  position: relative;
  top: 30px;
  left: 30px;
}

Here we give our middle paragraph a position value of relative — this doesn't do anything on its own, so we also add top and left properties. These serve to move the affected element down and to the right — this might seem like the opposite of what you were expecting, but you need to think of it as the element being pushed on its left and top sides, which result in it moving right and down.

Adding this code will give the following result:

.positioned {
  position: relative;
  background: rgba(255,84,104,.3);
  border: 2px solid rgb(255,84,104);
  top: 30px;
  left: 30px;
}

Absolute positioning

Absolute positioning is used to completely remove an element from normal flow, and place it using offsets from the edges of a containing block.

Going back to our original non-positioned example, we could add the following CSS rule to implement absolute positioning:

.positioned {
  position: absolute;
  top: 30px;
  left: 30px;
}

Here we give our middle paragraph a position value of absolute, and the same top and left properties as before. Adding this code, however, will give the following result:

.positioned {
    position: absolute;
    background: rgba(255,84,104,.3);
    border: 2px solid rgb(255,84,104);
    top: 30px;
    left: 30px;
}

This is very different! The positioned element has now been completely separated from the rest of the page layout and sits over the top of it. The other two paragraphs now sit together as if their positioned sibling doesn't exist. The top and left properties have a different effect on absolutely positioned elements than they do on relatively positioned elements. In this case the offsets have been calculated from the top and left of the page. It is possible to change the parent element that becomes this container and we will take a look at that in the lesson on positioning.

Fixed positioning

Fixed positioning removes our element from document flow in the same way as absolute positioning. However, instead of the offsets being applied from the container, they are applied from the viewport. As the item remains fixed in relation to the viewport we can create effects such as a menu which remains fixed as the page scrolls beneath it.

For this example our HTML is three paragraphs of text, in order that we can cause the page to scroll, and a box to which we will give position: fixed.

<h1>Fixed positioning</h1>

<div class="positioned">Fixed</div>

<p>Paragraph 1.</p>
<p>Paragraph 2.</p>
<p>Paragraph 3.</p>
.positioned {
    position: fixed;
    top: 30px;
    left: 30px;
}

Sticky positioning

Sticky positioning is the final positioning method that we have at our disposal. It mixes the default static positioning with fixed positioning. When an item has position: sticky it will scroll in normal flow until it hits offsets from the viewport that we have defined. At that point it becomes "stuck" as if it had position: fixed applied.

.positioned {
  position: sticky;
  top: 30px;
  left: 30px;
}

Note: to find more out about positioning, see our Positioning article.

Table layout

HTML tables are fine for displaying tabular data, but many years ago — before even basic CSS was supported reliably across browsers — web developers used to also use tables for entire web page layouts — putting their headers, footers, different columns, etc. in various table rows and columns. This worked at the time, but it has many problems — table layouts are inflexible, very heavy on markup, difficult to debug, and semantically wrong (e.g., screen reader users have problems navigating table layouts).

The way that a table looks on a webpage when you use table markup is due to a set of CSS properties that define table layout. These properties can be used to lay out elements that are not tables, a use which is sometimes described as "using CSS tables".

The example below shows one such use; using CSS tables for layout should be considered a legacy method at this point, for those situations where you have very old browsers without support for Flexbox or Grid.

Let's look at an example. First, some simple markup that creates an HTML form. Each input element has a label, and we've also included a caption inside a paragraph. Each label/input pair is wrapped in a <div>, for layout purposes.

<form>
  <p>First of all, tell us your name and age.</p>
  <div>
    <label for="fname">First name:</label>
    <input type="text" id="fname">
  </div>
  <div>
    <label for="lname">Last name:</label>
    <input type="text" id="lname">
  </div>
  <div>
    <label for="age">Age:</label>
    <input type="text" id="age">
  </div>
</form>

Now, the CSS for our example. Most of the CSS is fairly ordinary, except for the uses of the display property. The <form>, <div>s, and <label>s and <input>s have been told to display like a table, table rows, and table cells respectively — basically, they'll act like HTML table markup, causing the labels and inputs to line up nicely by default. All we then have to do is add a bit of sizing, margin, etc. to make everything look a bit nicer and we're done.

You'll notice that the caption paragraph has been given display: table-caption; — which makes it act like a table <caption> — and caption-side: bottom; to tell the caption to sit on the bottom of the table for styling purposes, even though the markup is before the <input> elements in the source. This allows for a nice bit of flexibility.

html {
  font-family: sans-serif;
}

form {
  display: table;
  margin: 0 auto;
}

form div {
  display: table-row;
}

form label, form input {
  display: table-cell;
  margin-bottom: 10px;
}

form label {
  width: 200px;
  padding-right: 5%;
  text-align: right;
}

form input {
  width: 300px;
}

form p {
  display: table-caption;
  caption-side: bottom;
  width: 300px;
  color: #999;
  font-style: italic;
}

This gives us the following result:

You can also see this example live at css-tables-example.html (see the source code too.)

Multi-column layout

The multi-column layout module gives us a way to lay out content in columns, similar to how text flows in a newspaper. While reading up and down columns is less useful in a web context as you don’t want to force users to scroll up and down, arranging content into columns can be a useful technique.

To turn a block into a multicol container we use either the column-count property, which tells the browser how many columns we would like to have, or the column-width property, which tells the browser to fill the container with as many columns of at least that width.

In the below example we start with a block of HTML inside a containing <div> element with a class of container.

<div class="container">
    <h1>Multi-column layout</h1>
    
    <p>Paragraph 1.</p>
    <p>Paragraph 2.</p>

</div>

We are using a column-width of 200 pixels on that container, causing the browser to create as many 200-pixel columns as will fit in the container and then share the remaining space between the created columns.

    .container {
        column-width: 200px;
    }

Summary

This article has provided a brief summary of all the layout technologies you should know about. Read on for more information on each individual technology!

In this module

문서 태그 및 공헌자

이 페이지의 공헌자: DeadIntegral
최종 변경자: DeadIntegral,