본문 바로가기

별걸다하는 IT/기타IT

[css] element 또는 요소(div) 가운데 정렬시키는 몇 가지 방법 (position, margin, flex 등등)

div table 등등 가운데 정렬시키기~

이번에는 상황에 따라(?) 요소를 가운데 정렬시키는 법을 정리해보려고 해요.

 

먼저 화면에 요소를 가운데 정렬시키고 싶을 때!

1. position 속성 사용 [inline-block]

간단하게 또 로그인 예제를 사용해서 살펴봅시다.

<style>
div#login_wrapper { border: 1px solid gray ;}
</style>
<body> 
	<div id="login_wrapper">
		<h3>Welcome to login site</h3>
		<div>
			<label>아이디</label>
			<input type="text" id="id" name="id" maxlength="20" placeholder="username">
		</div>
		<div>
			<label>비밀번호</label>
			<input type="password" id="pwd" name="pwd" maxlength="20" placeholder="password">
		</div>
		<button type="button" id="btn_login">로그인</button>
	</div>
</body>

 

[그림1]구분하기 쉽게 정렬하고자 하는 div에 테두리를 쳐줬어요

부모인 body를 기준으로 위치를 맞출것이므로 position 속성을 absolute 로 맞춰줍니다

absolute 절대적이라는 의미로 자신의 위치를 부모 객체를 대상으로 맞춥니다. (다른 요소들에게 영향받지 않아요)

position이라는 속성들의 조합은 레이아웃을 디자인하는데 엄청난 사용성(?)을 발휘하는 데 나중에 따로 다뤄보도록 할게요 

css를 이렇게 바꿔줄게요

div#login_wrapper{
    position: absolute;
    top: 50%;
    left: 50%;
    border: solid 1px gray;
}

 

[그림2]실제 구현 화면과 원리

보면 알겠지만 사각형이 딱 가운데에 와있지 않아요

top : 50%는 위에서부터 딱 중간 지점, left: 50%는 왼쪽부터 중간지점으로 하트 스티커의 위치를 가리켜요

즉 top, left속성은 사각형의 중심 좌표를 가리키는 것이 아니라 div 컨테이너의 시작점을 가리키기 때문이예요 (div컨테이너는 빨간 스티커에서 시작)

div에 absolute position을 적용하면, display:block이었던 속성이 display:inline-block으로 자동변경돼, 하나의 라인을 차지하고 있던 블럭이 내부 요소의 크기만큼 바운더리를 갖게됩니다. (그림1과 그림2 테두리 비교를 통해 참고로 알고만 있으세요 ~)

 

이제 정렬하려면 어떻게 해야 하는지 눈에 보이시죠? 저 사각형 가로 길이의 반만큼 왼쪽으로 이동시키고, 세로 길이의 반만큼 다시 위로 빽해주면 됩니다. 고로 div 컨테이너의 가로 세로 길이를 정해준 뒤 아래와 같이 설정해주면

div#login_wrapper { 
    position: absolute;
    top: 50%;  left: 50%;
    border: solid 1px gray;
    width: 300px; height: 160px;
    margin-left: -150px;
    margin-top : -80px;
}

[그림3] 가운대로 옮겨진 것을 확인 할 수 있습니다.

2. margin : 0px auto; 사용 (가로 정렬) [조건: block, width]

정말 많이 쓰이고 간편한 방법이지만 주의해야 할 점이 있습니다. 이 속성은 정렬하고자 하는 요소가 display: block속성을 가지고 있어야 할 뿐만 아니라 width 크기가 꼭 지정이 되어야 적용됩니다!! 이 방법이 먹히지 않는다면 가로 길이를 내가 지정해줬는지 꼭 확인해주세요 :) 

1.
margin-left: auto;
margin-right: auto;
2.
margin: 0px auto;

둘 다 같은 방법으로 1번을 사용해도, 2번을 사용해도 똑같이 가로 center 정렬이 됩니다.

문제는 여기서 사람들이 많이 헷갈리는 데,

1.
margin-top: auto;
margin-bottom: auto;
2.
margin: auto 0px;

height center 정렬을 생각하고 이렇게 소스코드를 작성했다가는 가운데 정렬이 먹지 않습니다!

If 'margin-top', or 'margin-bottom' are 'auto', their used value is 0.

top이나 bottom이 auto을 경우에는 0으로 취급되기 때문이예요

 

한가지 방법이 있는데, flex를 이용하는 겁니다.

부모 컨테이너에 display: flex; 속성과 함께 가로 세로 크기를 지정해주면, 자식컨테이너에서 margin: auto auto; 가 잘 작동합니다. 

 

3. flex property 사용

근데 사실 margin을 사용하는 방식은 권장되지 않습니다

margin을 사용하게 되면 요소들끼리 상호작용을 할시 전체 높이 값을 알 수가 없게 되는 경우가 많기 때문이예요

그래서 이번은 그냥 margin사용을 최대한 자제하고, 요소 배치 레이아웃 속성인 flex를 이용해 정렬을 해보겠습니다

div#login_wrapper{
    display: flex;
    height: 100vh;
    justify-content: center; /*가로에서 가운데에 요소(자식요소)를 배치하겠다*/
    align-items: center; /* 세로에서 가운데에 요소를 배치하겠다 */
    border: solid 1px gray;
}

이렇게 할 경우, 

세로를 화면 크기에 맞게 설정해주었음에도 불구하고 (1vh란 화면의 1퍼센트를 의미)

세로에 스크롤이 생긴것을 알 수 있어요

왠지 개발자도구에서 분석해보면 body에 부여하지 않은 margin의 값이 주어졌다는 것을 알 수 있습니다.

원래 태그는 태그 자체에 각각의 css속성들을 가지고 있어요 그래서 보통 작업할 때 초기화작업을 해줘요

그러므로 margin을 다시 0으로 만들어줍니다. 또 기존의 content 기준을 border기준으로 변경시켜주는 작업을 해줘야 border 1px때 생긴 추가적인 길이에 영향을 받지 않아요. 이렇게 이런것들에 영향을 받지 않기 위해 하는 작업이 즉 초기화작업인거죠~

(border 1px 이거 적용하지 않았으면 그냥 내부에 태그때문에 생긴 기본 css속성을 없애는 padding:0px; margin:0px; 만 해줘도 됩니다)

* { box-sizing: border-box; margin: 0px; }

그럼 이와 같이 스크롤 없이 딱 가운데 정렬이 됩니다.

앞의 예제와 같이 똑같이 login_wrapper에 테두리를 주었는데 결과가 달라졌죠?

앞의 1번의 경우 div의 높이를 화면 전체가 아닌 내부 컴포넌트들의 길이에 맞춘 후 변경시켜줬고

이 flex를 사용할 경우엔 flex속성이 부여된 컴포넌트의 자식 요소들을 내 높이 안에서 정렬시킨다는 것을 알 수 있습니다.

 

4. text-align 사용

div#login_wrapper{
   text-align: center;  border: solid 1px gray;
}

이렇게 text-align을 사용하면 

이와 같이 가로 가운데 정렬이 된 것을 확인할 수 있습니다.

응용

<style>
#login_wrapper { 
    border: 20px solid lightblue;
    padding: 5px 20px;
    position: absolute;
    top: 50%;
    left: 50%;
    width: 450px; height: 250px;
    margin-left: -220px;
    margin-top : -170px;
    
    display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
} 
h1{
	font-size: 25px;
	padding-bottom: 20px;
}
.form{
	width: 300px;
}
.form > div{
	display: flex;
	justify-content: center;
	padding-bottom: 7px;
	align-items: center;
}
label{
	flex: 1;
	text-align: left;
}
button{
	width: 85px;
	float: right;
	padding: 3px;
}
input {
	padding: 5px;
}
</style>
<body>
<div id="login_wrapper">
		<h1>Welcome to Login Example</h1>
		<form action="login" method="POST" class="form">
			<div>
				<label>아이디</label>
				<input type="text" id="id" name="id" maxlength="20" placeholder="username" required>
			</div>
			<div>
				<label>비밀번호</label>
				<input type="password" id="pwd" name="pwd" maxlength="20" placeholder="password" required>
			</div>
			<button type="submit" id="btn_login" >로그인</button>
		</form>
	</div>  
</body>

도움이 되셨다면 공감이나 광고보답은 어떤가요?! :) 

또 다른 좋은 정보로 찾아뵐게요 다음에 봐요 !