HTML, CSS

반응형 웹 실전 프로젝트 #20 (레이아웃: position)

일등하이 2020. 7. 23. 17:02
반응형

레이아웃을 배치하거나 요소 위치를 지정하는 또 하나의 중요한 속성이 position이다 

CSS의 여러 실무팀들이 position으로 완성되고 있다 

position에서는 세로 배열, 가로 배열이 문제가 아니라 주로 부모박스의 좌표를 기준으로 요소의 위치기 결정된다 

따라서 부모박스가 어떤 요소인지가 매우 중요 하다 

기본적인 속성의 의미를 알아본뒤 예제를 통해 자세히 살펴보자 

 

 

 

position

position에는 static, relative, absolute, fixed 네 가지의 속성 값이 있으며 다음과 같이 표현된다 

position: relative;
속성 값 속성 설명
static  요소를 이동하거나 겹칠수 없는 원래 그대로의 상태
relative, absolute, fixed 했던 박스를 원상태로 회복
relative left, top 속성으로 이동할수 있음 
position: absolute로 지정된 요소의 부모요소 역할을 할수도 있음
absolute 원래 위치에 따로 떼어내 독립적으로 새로운 위치를 설정
left, right, top, bottom 속성으로 위치 지정 할수 있음
부모 박스를 기준으로 위치를 지정
fixed 요소의 위치를 screen 기준으로 지정
left, right, top, bottom 속성으로 위치를 지정할수 있음

우리가 지금까지 사용해 온 블록들은 이미 position: static; 상태였다

position은 매우 다양한 형태로 활용될수 있는데, 어떤 요소를 원래 위치에서 약간 이동해야 하거나 jQuery등으로 애니메이션을 지정해야 할때 position: relative; 할수 있으며, 다른 요소와 겹쳐야 할때나 마크업 순서와 다르게 위치를 설정 해야 할때 position: absolute; 할수 있다 

position: absolute; 된 요소의 부모 박스는 반드시 position: relative; 이거나 position: absolute; 또는 position: fixed; 되어야 하며, 부모 박스를 지정하지 않으면 body가 부모가 된다 

 

 

 

left, right, top, bottom

position속성이 relative, absolute, fixed 일경우 위치를 지정해준다 

속성 값 속성 설명
left: 100px; 요소를 부모 박스의 좌측에서 우측 방향으로 100px 떨어진 곳에 배치
right : 100px; 요소를 부모 박스의 우측에서 좌측 방향으로 100px 떨어진 곳에 배치
top: 150px; 요소를 부모박스의 상단에서 아래로 150px 떨어진 곳에 배치
bottom: 100px; 요소를 부모박스의 바닥에서 위로 100px 떨어진곳에 배치
left: auto; left값을 취소
right: auto; right값을 취소 
top: auto; top 값을 취소
bottom: auto; bottm 값을 취소 

만약 left와 right를 함께 사용하면 어떻게 될까 

left: 100px;
right: 100px;

위와 같이 하면 안된다 

둘중 하나만 써야 한다 

그러나 어떤 이유에서 이순서대로 속성을 기술해야 할 필요가 있다면, 그럴경우 right: 100px;을 쓰기전에 

left: auto; 하여 left에 들어 있던 속성 값을 초기화 해준다 

left: 100px;
left: auto;
right: 100px;

이렇게 하면 left: 100px; 이 실행되었다가 left값을 취소 하고 다시 right: 100px; 이 실행된다 

 

 

 

z-index

z-index는 겹쳐지는 요소들의 계층을 변경할때 사용되는 속성이다 

어떤 요소가 바닥에 깔리고 어떤 요소가 겉으로 올라오는지를 결정해준다

z-index값이 큰 요소가 적은 요소보다 겉으로 올라오게 된다 

z-index: -1;을 사용하면 보통 요소를 가장 바닥으로 깔아 배치 한다 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Position</title>
    <style type="text/css">
        body,
        div,
        p {
            margin: 0;
            padding: 0;
        }

        body {
            margin: 20px;
            background: url("public/images/bg_grid.gif");
        }

        .box {
            width: 650px;
            background: rgba(0, 0, 0, 0.3);
        }

        p {
            width: 250px;
            height: 100px;
            box-sizing: border-box;
            padding: 10px;
            font-weight: bold;
        }

        .red {
            background: crimson;
        }

        .green {
            background: lime;
        }

        .blue {
            background: dodgerblue;
        }
    </style>

</head>

<body>
    <div class="box">
        <p class="red">박스의 크기와 위치를 잘 살펴보아야 한다.</p>
        <p class="green">박스의 포지션 속성을 바꿔가며 테스트 해보아야 한다.</p>
        <p class="blue">포지션을 이해하기 위해서는 시험해보고 관찰해 보는 것이 절대적으로 필요하다.</p>
    </div>
</body>

</html>

 

예상대로 박스들이 세로로 나열되고 있다 

이제 속성의 변경을 시도해보자 

 .green {
   background: lime;
   position: absolute;
 }

.green 요소에 position: absolute; 된 모습이다

 

.green 요소에 position: absolute; 되어 본래의 레이아웃에서 떨어져나와 떠있게 된다 

.green이 없었다면 .red아래 .blue가 붙어 있게 된다 

다만 .green 아래 .blue 가 깔려 안보일뿐이다 

.absolute요소는 위치 값을 주지 않으면 이렇게 그 자리에서 떠버리게 된다 

 

 

 

absolute된 .green요소의 위치를 변경해보자 

.green {
  background: lime;
  position: absolute;
  left: 70px;
  top: 50px;
}

일단 요소의 위치가 변경된것을 알수있다

.blue가 아래 있었다는 것도 알수있다 

변경된 위치가 맞는지 주의 깊게 살펴보자 

.green은 어디서 70px, 50px 떨어져서 배치 되었다는것인가?

.box의 좌측 상단에서가 아니라 body의 좌측 상단에서 70px 50px 떨어진 위치로 배치 되었다 

모든 요소들이 body를 기준으로만 배치된다면 웹표준 이전의 테이블 코딩과 다를바 없다 

당연히 부모 요소를 기준으로 좌표를 잡아야 부모 요소가 이동할때 함께 이동된다 

 

 

 

 

 

.green 요소가 부모 박스를 기준으로 좌표를 잡도록 코드를 변경해보자 

.box {
  position: relative;
  width: 650px;
  background: rgba(0, 0, 0, 0.3);
}

.box요소가 .green요소의 부모박스가 된 모습을 확인한다 

녹색 상자의 위치가 이전과 바뀐것을 확인할수 있나?

.green은 .box의 좌측 상단으로부터 70px 50px떨어진곳에 자리 잡았다 

 

 

 

.blue요소의 position을 relative로 변경하고 비교해보자 

.blue {
	position: relative;
	background: dodgerblue;
}

.blue를 position: relative; 하여도 다른 컨텐츠들의 위치에 영향을 미치지 않는다 

absolute처럼 레이아웃을 크게 망가뜨리지 않았다

그러나 요소의 계층이 달라져 .blue가 가장 겉으로 나오게 된다 

 

 

 

 

.blue요소에 위치 변경을 해보자 

.blue {
	position: relative;
	background: dodgerblue;
	left: 100px;
	top: 40px;

}

.blue요소의 위치는 어디를 기준으로 100px 40px이동된것인지 살펴 보자 

body도 아니고 부모 박스도 아니다 

relative요소는 absolute요소와 달리 자기 자신을 기준으로 이동한다 

따라서 파란 상자는 주변 요소들의 신변에 변화를 주지 않고 원래 있었던 위치에서 100px, 40px이동한것이다 

 

 

 

 

 

 

이번엔 요소들의 계층을 변경해보겠다 

.blue 보다 아래 깔려 있는 .green을 다시 위로 끌어 올리려면 z-index 속성을 이용한다 

.green {
	background: lime;
	position: absolute;
	left: 70px;
	top: 50px;
	z-index: 1;
}

파란상자에 딸려 있던 .green 요소가 겉으로 올라온것을 확인 할수 있다 

 

 

지금까지 살펴보았던 css의 완성된 코드는 다음과 같다 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Position</title>
    <style type="text/css">
        body,
        div,
        p {
            margin: 0;
            padding: 0;
        }

        body {
            margin: 20px;
            background: url("public/images/bg_grid.gif");
        }

        .box {
            position: relative;
            width: 650px;
            background: rgba(0, 0, 0, 0.3);
        }

        p {
            width: 250px;
            height: 100px;
            box-sizing: border-box;
            padding: 10px;
            font-weight: bold;
        }

        .red {
            background: crimson;
        }

        .green {
            background: lime;
            position: absolute;
            left: 70px;
            top: 50px;
            z-index: 1;
        }

        .blue {
            position: relative;
            background: dodgerblue;
            left: 100px;
            top: 40px;

        }
    </style>

</head>

<body>
    <div class="box">
        <p class="red">박스의 크기와 위치를 잘 살펴보아야 한다.</p>
        <p class="green">박스의 포지션 속성을 바꿔가며 테스트 해보아야 한다.</p>
        <p class="blue">포지션을 이해하기 위해서는 시험해보고 관찰해 보는 것이 절대적으로 필요하다.</p>
    </div>
</body>

</html>

 

 

 

z-index 값의 최대치가 2147483647 이라고는 하지만 처음부터 큰 값을 사용하지 않는것이 좋다

퍼블리싱을 진행하다 보면 계획 또는 예상하지 못한 요소도 발생한다 

10단위나 100단위등 가이드를 미리 정하고 증가시켜 나가다가 중간에 끼워 넣을 요소가 생겼을때 중간 값을 사용할수 있게 계획하자 

 

 

이번에는 position: fixed의 경우를 상펴본다 

요소가 화면을 기분으로 배치된다는것은 스크롤이 일어나도 화면에서 움직이지 않고, 화면 좌측 상단을 0, 0 기분으로 하여 자리 잡는다는 뜻이다 

스크롤이 되어도 어느 정도 따라 올라가다가 상단에 고정되는 메뉴들을 흔히 position: fixed; 로 지정 되어 있다 

예제를 통해 스크롤이 일어날수 있도록 컨텐츠 부분에 내용을 몇줄 추가 하자 

<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="utf-8">
    <title>WEB PAGE TEMPLATE</title>
    <style type="text/css">
        body,
        header,
        div,
        footer,
        h1,
        p,
        ul,
        li {
            margin: 0;
            padding: 0;
        }

        li {
            list-style-type: none;
        }

        .clear:after {
            content: "";
            display: block;
            clear: both;
        }

        body {
            font: 14px 'Malgun Gothic', '맑은고딕';
        }

        a {
            text-decoration: none;
            color: #444;
        }

        a:hover {
            text-decoration: underline;
        }

        #wrap {
            background: #cfc;
        }

        header {
            background: crimson;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 40px;
        }

        header h1 {
            float: left;
            margin-right: 40px;
        }

        header .gnb {
            float: left;
            padding-top: 10px;
        }

        header .gnb li {
            float: left;
        }

        header .gnb li a {
            display: block;
            width: 50px;
            text-align: center;
            font-size: 16px;
        }

        .lnb {
            float: left;
            width: 20%;
            background: lightgreen;
        }

        .lnb li a {
            display: block;
            padding: 5px 20px;
        }

        .content_area {
            float: left;
            width: 80%;
            background: forestgreen;
        }

        .content_area p {}

        #container {
            margin-top: 40px;
        }

        footer {
            padding: 10px;
            background: lightgray;
        }

        footer p {
            text-align: center;
        }
    </style>
</head>

<body>
    <div id="wrap">
        <header class="clear">
            <h1><a href="#">logotype</a></h1>
            <ul class="gnb clear">
                <li><a href="#">m1</a></li>
                <li><a href="#">m2</a></li>
                <li><a href="#">m3</a></li>
                <li><a href="#">m4</a></li>
            </ul>
        </header>
        <div id="container" class="clear">
            <ul class="lnb">
                <li><a href="#">s1</a></li>
                <li><a href="#">s2</a></li>
                <li><a href="#">s3</a></li>
                <li><a href="#">s4</a></li>
            </ul>
            <div class="content_area">
                <p>내용<br> 헤더를 상단에 고정<br> 헤더를 상단에 고정<br> 헤더를 상단에 고정<br> 헤더를 상단에 고정<br> 헤더를 상단에 고정<br> 헤더를 상단에 고정<br> 헤더를
                    상단에 고정<br>
                    헤더를 상단에 고정<br> 헤더를 상단에 고정<br> 헤더를 상단에 고정<br> 헤더를 상단에 고정<br> 헤더를 상단에 고정<br> 헤더를 상단에 고정<br> 헤더를 상단에
                    고정<br> 헤더를 상단에 고정</p>
            </div>
        </div>
        <footer>
            <p>copyright</p>
        </footer>
    </div>
</body>

</html>

화면을 스크롤 하여 내용이 올라가도 header는 따라 올라가지 않는다 

 

 

 

 

float과 position으로 레이아웃 만들기

어떤 레이아웃에는 float을 쓰고 어떤 레이아웃에는 position만 써야 하는 법칙이 있는것은 아니다 

속성을 정확히 알고 구현하면 그것이 정답이다 position: relative와 float: left는 함께 쓸수 있다 둘다 주변과 어울리게 해준다 그러나 position: absolute; 와 float: left; 는 함께 쓸수 없다 absolute는 어울림의 반대 즉, 따로 떨어져 나온 독립된 요소이기 때문에 부모 박스가 자동으로 감사주지 않는다

2단 레이아웃을 완성 하는 몇가지 방법 

지금까지 배운것을 활용해 스토리 보드를 기준으로 2단 레이아웃을 완성 하는 방법을 정리해보자 더 많은 방법이 있겠지만 가장 많이 쓸것 같은 네가지 경우를 살펴본다2단 container안의 가로로 나열된 두 박스, sidemenu와 content다 

float 방식 sidemenu는 float: left; 하고 
content는 float: right; 
float의 해제가 필요함
position- 절대, 상대위치 sidemenu는 position: absolute; 하고
content는 position: relative;
세로로 긴쪽을 relative해야 container가 포함할수 있음
부모 박스를 지정해줘야 함
position - 절대, 마진 방식 sidemenu는 position: absolute; 하고 content는 margin-left
부모박스를 지정해줘야 함
float + position sidemenu는 position: absolute; 하고 
content는 float: right;
float의 해제가 필요하고 부모 박스를 지정해줘야 함 

 

 

float 방식 

float된 두개의 박스를 해제하기 위해 그들을 감싸는 container의 가상요소 : after에 clear: both;를 한다 

 

 

 

 

 

position - 절대, 상대 위치

가로로 나열된 두 박스중 세로로 짧은쪽에 absolute를 주고 세로로 긴쪽에 relative를 준다 

absolute는 레이아웃에서 주변과 독립된 박스이고 relative는 주변과 어울린 박스이므로, 긴쪽에 absolute를 주면 contaienr가 감사지 못한다 

또한, content 박스를 왼쪽 박스만큼 우측으로 밀어 배치해야 할 것에 주의 한다

 

 

 

 

 

position - 절대, 마진 방식

절대, 상대 위치 방식에서 파생된 방식으로, 세로로 긴 박스에 position을 하지 않고 그대로 바깥 여백을 주어 미는것

 

 

 

 

 

 

float + position

가로로 나열된 두 박스중 세로로 짧은 쪽에 absolute를 주고 세로로 긴 쪽에 float를 한다

길이가 긴 박스가 float되어 어울려져 있어야 모든 박스의 위치가 흔들리지 않는다 

content의 float을 해제 하기 위해 그들을 감싸는 container에도 float하고, 그 float을 해제 하기 위해 다음 박스인 footer에 clear: both 하는 방식이다 

 

 

 

 

 

 

 

 

 

 

3단 레이아웃을 완성하는 몇가지 방법 

3단 레이아웃을 완성하는 방법을 정리해보자 

float 방식 sidemenu와 content는 float: left; 하고 
banner만 float: right; 
float의 해제가 필요함
position - 절대, 상대 위치 sidemenu와 banner는 position: absolute; 하고
content는 position: relative; 
부모 박스를 지정해줘야 함
position - 절대, 마진 방식 sidemenu와 banner는 position: absolute; 하고
content는 margin-left
부모박스를 지정해줘야 함
float + position sidemenu는 float: left; 하고 
banner는 float:right; 하고 
content는 position: absolute; (내용이 길면 부모박스에 height를 지정)
float 해제가 필요 하고 부모 박스를 지정해줘야 함 

 

 

 

 

float방식

float된 세개의 박스를 해제 하기위해 그들을 감싸는 container의 가상요소 :after에 clear: both; 를 한다 

 

 

 

 

 

position - 절대, 상대 위치 

position 방식에서 absolute인 박스는 부모박스와 left, top값을 주어야 한다 

부모박스에 가로 사이즈를 명시 해야 한다 

 

 

 

 

position - 절대, 마진 방식 

양쪽 두개의 박스를 absolute 하고 중아의 컨텐츠 박스는 가로 폭과 좌측 여백을 준다 

 

 

 

 

 

float + position

float이 있으니 해제도 해줘야 하고 , absolute 박스가 있으니 부모도 설정해줘야 하고 가운데 상자가 absolute박스이니 양쪽 박스보다 가운데 길이가 긴 레이아웃에는 적합 하지 않다 

 

 

 

 

position 응용 예제

이제 position을 포함 하여 지금까지 살펴본 CSS를 가지고 몇가지 예를 다뤄보자 

건넝뛰기 링크 스타일 

웹페이지 상단에는 메뉴를 건너뛰고 본문 내용으로 직접 가게 해주는 건너뛰기 링크가 있다

그 스타일은 어떻게 처리 하는게 좋을까?

디자인을 해치지 않는다면 그대로 노출 하는것도 좋다 

여기서는 건너뛰기 링크가 처음에는 숨겨져 안보이다가 포커스가 있을때 나타나는 것으로 해보자 

<!DOCTYPE html>
<html lang="ko"> 
<head>
<meta charset="utf-8">
<title>민화</title> 
<style type="text/css">
    body, h1, h2, ul, li, p {margin:0; padding:0;}
    li {list-style-type:none;}
    a {color:#000;}
    .box_inner {width:700px; margin:0 auto;}
    body {background:#f1f1f1; font-size:13px; color:#333;}
    .wrap {}
    header {background:#357;}
    h1 {font-size:25px; color:#cc0; padding:10px;}
    h1:first-letter {font-size:1.5em;}
    h1 strong {color:#ffd;}
    h1 em {font-style:normal; font-size:1.5em; color:#fff;}
    #container {position:relative;}
	.gnb {position:absolute; left:0; top:0; width:150px; padding:20px;}
	.gnb li {padding:5px 0;}
    .content {position:relative; left:200px; width:500px;}
    h2 {padding:10px 20px; color:crimson;}
	p {padding:20px; text-align:justify;}
    footer {background:#aaa;}
</style>
</head>
<body>
    <div class="wrap">
	    <header>
		    <h1 class="box_inner">
		        <strong>호랑이</strong>를 <span>주제</span>로 한 <em>민화</em>
            </h1>
	    </header>
	    <div id="container" class="box_inner">
		    <ul class="gnb">
                <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="content">
                <h2>  승운용호도</h2>
                <p>  사람 이름 같기도 한 이 그림을 처음 보았을 때 티셔츠에 새길 그림을 일러스트레이터로 작업 중이었다. 비록 그림을 보며 원본대로 그려내는 작업이었지만 즐거웠다. 용과 겨루는 황금빛 호랑이의 모습이 용맹하기도 했지만 내게는 약간 귀여워 보였고 무엇보다 순수해 보였다. 어둠 속에서 나타난 비겁한 용보다는 맑은 물을 튀며 신성한 기운을 드러내는 우리 호랑이에서 무한한 애정을 느꼈기 때문이다.</p>
                <h2>  길상백호</h2>
                <p>  호랑이 그림은 예로부터 아래로 내려오는 것보다 위로 올라가는 형상이 더 좋다고 하였다. 하지만 이 그림은 달랐다. 아래로 내려오고 있기는 하지만 윤기나는 등의 털과 그윽하게 쳐다보는 두 눈은 백호의 여유로움을 충분히 공감할 수 있게 해주었기 때문이다. 채도가 내려앉아 버린 백호의 그림이지만 건조해 보이기보다는 은빛으로 촉촉해 보이는 호랑이의 자태에 반했다고 할까? 알록달록함이 주는 아기자기함은 없지만 세련된 무채색에 다부지게 밟아 짚은 앞발에서 오히려 나를 지켜주는 든든함까지 느껴진다. 호랑이가 밟은 풀잎들에서도 우리를 한 공간 안에 무사히 존재하게 하는 안정감이 있는 듯하다. 그림을 감상할 때 그 시대적 배경과 소재의 재질 등을 함께 감상하여 아는 즐거움을 늘려야 하겠지만 나는 아무 부수적인 요소들을 제하고 오로지 내 눈과 그림이 서로 교감하여 빚어내는 상상의 공간을 좋아한다. 시대를 알고 의도를 아는 것도 중요하겠지만 작가가 우리에게 오로지 늘 같은 그것만 바라지는 않았을 것 같다. 심지어 바랬다고 해도 그냥 미안하게 생각하고 나만의 감상포인트를 놓치지 말아야겠다. 이것도 정체성을 잃지 않으려는 관객의 필사적인 노력으로 보아주기를 바래본다.</p>
		    </div>
	    </div>
        <footer>
            <p class="box_inner">Copyright &copy; Allright Reserved.</p>
        </footer>
    </div>
</body>

 

 

먼저 body안에 건너뛰기 링크를 마크업 한다 

주메뉴를 건너뛰어 본문으로 직행하는 링크를 모든 요소의 위에 코딩한다 

<ul class="skipnavi">
	<li><a href="#container">본문내용</a></li>
</ul>

그 다음 건너뛰기 링크의 처음에 안보이는 스타일과, 탭 키를 눌러 포커스가 나타난경우 스타일을 부여한다 

 

반응형