IT 개발노트

레이아웃(인라인 vs 블럭레벨, 박스모델, 마진겹침현상, 포지션) 본문

기초튼튼/CSS

레이아웃(인라인 vs 블럭레벨, 박스모델, 마진겹침현상, 포지션)

limsungju 2019. 3. 6. 11:49

1 레이아웃
1.1 html 엘리먼트들은 크게 두 가지로 구분된다.
- 화면 전체를 사용하는 태그 -> block element
- 화면의 일부를 차지하는 태그 -> inline level element
- block은 화면 전체를 차지하기 때문에 다음 문장이 자동으로 줄바꿈 된다.
- inline은 설정한 영역만큼만 차지하기 때문에 다음 문장이 줄바꿈 되지 않는다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <style>
            h1, a{ border:1px solid red; }
            h1 { display: inline; }
            a { display: block; }
        </style>
    </head>
    <body>
        <h1>Hello world</h1>
        안녕하세요. <a href="https://opentutorials.org">생활코딩</a>입니다.
    </body>
</html>


결과

- display 속성을 이용해서 block과 inline을 바꿔줄수 있다.

1.2 박스모델
- 테두리는 박스모델의 기준점을 선정해준다.
- inline 방식에서는 width값이나 height값은 무시된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <style>
            p,{ 
                border: 10px solid red;
                padding:20px; 
                margin:40px;
                width:120px;
            }
        </style>
    </head>
    <body>
        <p>
            Lorem ipsum dolor sit, amet consectetur adipisicing elit. Et, sint!
        </p>
        <p>
            Lorem ipsum dolor sit, amet consectetur adipisicing elit. Et, sint!
        </p>
        안녕하세요.<a href="https://a.com">생활코딩</a>입니다.
    </body>
</html>


결과

1.3 box-sizing
: box-sizing은 박스의 크기를 화면에 표시하는 방식을 변경하는 속성이다.
width와 height는 엘리먼트의 컨텐츠의 크기를 지정한다. 따라서 테두리가 있는 경우에는 테두리의 두께로 인해서 원하는 크기를 찾기가 어렵다. box-sizing 속성을 border-box로 지정하면 테두리를 포함한 크기를 지정할 수 있기 때문에 예측하기가 더 쉽다. 최근엔 모든 엘리먼트에 이 값을 지정하는 경우가 늘고 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <style>
            * {
                box-sizing: border-box;
            }
            div {
                margin:10px;
                width:150px;
            }
            #small {
                border:10px solid black;
            }
            #large {
                border:30px solid black;
            }
        </style>
    </head>
    <body>
        <div id="small">Hello</div>
        <div id="large">Hello</div>
    </body>
</html>


결과

1.4 마진겹침 현상
: 마진겹침(margin-collapsing) 현상은 상하 마진값이 어떤 상황에서 사라지는 현상을 의미한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <style>
            h1 {
                border:1px solid red;
                margin:100px;
            }
        </style>
    </head>
    <body>
        <h1>Hello world</h1>
        <h1>Hello world</h1>
    </body>
</html>


결과

- 크롬개발자 도구(F12)를 사용해서 확인해보면 마진이 겹쳐져있는 부분을 확인할 수 있다.
- 위에있는 태그와 아래있는 태그의 마진값의 더 큰값이 두 태그의 간격이 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <style>
            #parent {
                border:1px solid tomato;
                margin-top:100px;
            }
            #child {
                background-color: powderblue;
                margin-top:50px;
            }
        </style>
    </head>
    <body>
        <div id="parent">
            <div id="child">
                Hello world
            </div>
        </div>
    </body>
</html>


결과

- 마진겹침현상 없음

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <style>
            #parent {
                /* border:1px solid tomato; */
                margin-top:100px;
            }
            #child {
                background-color: powderblue;
                margin-top:50px;
            }
        </style>
    </head>
    <body>
        <div id="parent">
            <div id="child">
                Hello world
            </div>
        </div>
    </body>
</html>


결과

- 부모태그가 가지고있는 시각적인 효과가 사라지는 순간 자식태그와 마진겹침 현상이 일어나게 된다.
- 자식태그의 마진값이 부모태그의 마진값보다 커지게 되면 위치가 수정된다.
- 부모태그의 마진값이 자식태그의 마진값보다 작아지게 되면 위치가 수정된다.

1.5 포지션
: 엘리먼트의 위치를 지정하는 4가지 방법이 있다.
- static
- relative
- absolute
- fixed
이 4가지 방법을 정확하게 이해하고 사용하는 것이 css를 자유자재로 이용하는데 중요하다.

1.5.1 static vs relative (상대위치)
position타입이 static인 경우 left, right, top, bottom과 같은 오프셋을 설정해도 변화가 없다.
position타입이 relative인 경우 left, right, top, bottom과 같은 오프셋을 적용할 수 있으며, left와 right를 동시에 설정할 경우 left를 따르며, top과 bottom을 동시에 설정할 경우 top을 따르게 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <style>
            html { border: 1px solid gray; }
            div { 
                border: 5px solid tomato; 
                margin: 10px;
            }
            #me {
                /* position: static; */
                position: relative;
                left: 100px;
                /* right: 100px; */
                top: 100px;
                /* bottom: 100px; */
            }
        </style>
    </head>
    <body>
        <div id="other">other</div>
        <div id="parent">
            parent
            <div id="me">me</div>
        </div>
    </body>
</html>


결과

1.5.2 absolute(절대 위치)
: 부모중에 포지션 타입이 지정된 부모를 기준으로 위치가 지정되며, 부모와 관계성이 끊기기 때문에 자식의 크기는 자신의 컨텐츠 크기만해진다. 부모도 자식이 없는것처럼 작동한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <style>
            #parent, #other {
                border: 5px solid tomato;
            }
            #parent {
                position: relative;
            }
            #me {
                position: absolute;
                background-color: black;
                color: white;
            }
        </style>
    </head>
    <body>
        <div id="other">other</div>
        <div id="grand">
            grand
            <div id="parent">
                parent
                <div id="me">me</div>
            </div>
        </div>
    </body>
</html>


결과

1.5.3 fixed (고정된 위치)
: fixed도 absolute처럼 width와 height값을 지정하지 않으면, 부모가 없어지기 때문에 자신의 부피를 자신의 컨텐츠 크기로 설정된다. fixed의 부모 엘리먼트는 자식 엘리먼트와 관계가 끊기기 때문에 크기가 줄어든다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <style>
            body {
                padding-top: 30px;
            }
            #parent, #other {
                border: 5px solid tomato;
            }
            #large {
                height: 10000px;
                background-color: tomato;
            }
            #me {
                position: fixed;
                color: white;
                background-color: black;
                left: 0;
                top: 0;
                width: 100%;
                height: 30px;
                text-align: center;
            }
        </style>
    </head>
    <body>
        <div id="other">other</div>
        grand
        <div id="parent">
            parent
            <div id="me">me</div>
        </div>
        <div id="large">large</div>
    </body>
</html>


결과

- 페이지 창이 커서 스크롤이 생겼을때 스크롤을 내려도 position을 fixed로 설정하게 되면 위치가 변하지않고 그대로 표현된다.

1.5.4 position 정리
: 엘리먼트의 위치를 지정하는 방법은 static, relative, absolute, fixed가 있다.
position 속성 미지정시 기본값은 static이다.

- static : 원래 있어야 되는 위치에 정적으로 위치함(offset 무시) 위치 설정이 되지 않은 상태
top, bottom, left, right(offset)을 적용하고 싶을 경우 position의 값을 static외의 값으로 지정해야 한다.
(bottom, right < top, left 적용)

*position을 지정해도 offset값을 지정하지 않을경우 static처럼 원래 있어야 할 위치에 있게된다.

- relative : 원래의 위치에서 상대적으로 위치를 변경한다.

- absolute : html element를 기준으로 절대적인 위치로 변경한다.

* 부모-자식 관계에 놓인 태그의 경우
1) 자식태그가 absolute인 경우 부모태그는 자신의 크기만 가진다.
이때 자식태그는 block태그여도 inline태그처럼 컨텐츠만한 크기로 변한다.
width와 height 값을 지정하면 크기 변경이 가능하다. (fixed도 같은 효과)
2) 여러 부모태그 중 absolute인 자식태그는 position이 relative인 부모태그안에서 절대적으로 위치를 변경한다.

- fixed : 화면의 위치에 고정시켜 스크롤으로부터 독립되게 한다.