본문 바로가기

푸로그래밍/HTML, CSS

[HTML, CSS] 요소를 (상하좌우)정렬하기

반응형

이번 글에서는 필자가 알고 있는 가운데 정렬중에 쓸만한 몇가지를 쓰려한다.

필자가 알고있는 정렬방식은 7가지정도가 되지만 그중에 찐따같은것은 제외하고 좀 정상적인 것으로 소개하려 한다.

 

필자가 생각하는 정렬은 정적으로 N(px)만큼 빼고 더하는것이 아니라 자동적으로 알아서 되는것이다.

 

여기서는 정렬을 하려는 요소의 상태에 따라서 어떻게 작용하는지까지 다룬다.

 

일단 가운데 정렬이든, 왼쪽 정렬이든, 오른쪽 정렬이든 아무튼 정렬을 다루기 전에는 필수적으로 알아야 할 요소가 한가지 있다. 대부분의 요소정렬글에서는 이러한 부분이 빠져있으며, 그냥 '이렇게하면 됨 ㅅㄱ'라는 식의 글로 끝나고 있기에 자세히 적어본다.

CSS [display] 속성

모든 요소에는 display속성이 있다.

여러분들이 알고있는 display: block;, display: inline;이 바로 그것이다.

 

따로 명시하지 않는한 div는 block이고, span은 inline이며, table은 table이다.

왜냐하면 div는 요소들을 묶을때 사용하고 span은 텍스트를 묶을때 사용하기 때문이다.

물론 코딩에 정답은없다. table 태그를 쓰고 display속성으로 block로 주면 div와 같이동작한다.

 

그러나 그렇게 이상하게 쓰는 사람이 없고 html 태그의 갯수가 display의 속성의 갯수와 다른 이유는 CSS의 display속성과는 상관없이, 필요이유와 목적에 따라서 html의 태그를 나누어 놓았기 때문이다.

 

그렇기 때문에 div의 기본 width, height속성은 100%인것이고, 줄바꿈이되며

span의 기본 width, height은 요소의 크기이고 바꿀수 없으며, 줄바꿈이 되지않는다.

헷갈린다면 바로 editer를 켜고 해보면 알것이다.

 

혹자는 이렇게 말한다. div의 정렬방식과 span의 정렬방식이 다르다.

그러나 이는 정확하지 않은 말이다. div의 display속성과, span의 display속성이 다르기때문에 정렬방식이 다른것이지, 태그때문이아니다. 실제로 span태그에 display속성을 block를 주고, 소위div의 정렬방식이라 불려지는 방식으로 정렬을 하면 정렬이 되는것을 볼 수 있을것이다.

 

1. margin을 이용한 정렬 (display: block, display: flex)

<style>
    #box{
        width: 100%;
        background: #000;
    }
    .box1{
        width: 100px;
        height: 100px;
        background: #22b8cf;
        margin: 0 auto;
    }
</style>
<div id="box">
    <div class="box1">box1</div>
</div>

이렇게 margin: 0 auto;를 준다. 

CSS의 margin속성은

margin: 상, 우, 하, 좌;

margin: 상하, 좌우;

margin: 상하좌우;

 

와같이 세가지로 나눌 수 있다.

위의 코드에서는 상하에는 0을 좌우에는 auto를 줌으로써 margin에 의해 알아서 가운데로 정렬되게끔 한 코드이며 일반적으로 많이 쓰인다. 세로정렬은 안된다.

실행 결과이다.

이 방식으로 정렬할때는 정렬되는 자식의 display속성이 block또는 flex여야한다. 또한 margin방식은 가로 가운데정렬밖에 안된다. 하지만 .container나 .wrap같은걸 쓸때 많이쓴다.

 

Animation

이 방식은 auto로 알아서 동적으로 정렬되는 것이기 때문에 부모의 속성이 바뀌어도 transition속성이 있다면 애니메이션이 된다.

 

 

2. position: absolute; 방식

<style>
    #box{
        width: 100%;
        height: 100%;
        background: #000;
        position: relative;
    }
    .box1{
        width: 100px;
        height: 100px;
        background: #22b8cf;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }
</style>
<div id="box">
    <div class="box1">box1</div>
</div>

이렇게 부모요소에 position: relative;를 주고

정렬시킬 자식요소에 position: absolute;를 준다.

그리고 자식요소를 왼쪽으로(위쪽으로) 50%를 밀어버린다. 

그렇게되면 요소의 왼쪽맨위점이 딱 50%로 가게 되므로 요소자체가 중앙정렬이되는것이 아니라 요소의 왼쪽맨위점이 중앙정렬이 된다. 그렇기 때문에 요소의 절반만큼 왼쪽으로(위쪽으로) 땡길필요가 있다.

그 역할을 transform: translate(x, y) 가 해주는 것이다. 

 

가로정렬만 시킬거면 left: 50%; transform: translateX(-50%);만 하면 된다.

세로정렬만 시킬거면 top: 50%; transform: translateY(-50%);만 하면 된다.

둘다할거면 둘다 쓰면 된다. 

 

부모요소에 relative를 주는것은 정렬을 부모기준으로 하기 위함이다.

왜냐하면 자식요소에 position: absolute;를 주게 되는순간 자식은 부모를 멋어나 폐룬아가 되어버리기 때문이다.

직접 해보면 안다.

그러나 부모요소에 replative를 주면 absolute를 가진 자식요소가 부모요소를 벗어나지 않게된다. 이말은 즉 어떤속성을 주면 부모기준으로 들어간다는 것이다.

실행결과이다.

position속성을 사용할 수 있는 모든 태그에대하여 작동한다. 이것도 많이 쓰인다.

 

Animation

이 방식은 position을 사용하여 left, top, right, bottom과같은 위치속성을 사용할 수 있게 해주었고, 자신의 크기만큼 동적으로 정렬하는 방식이기때문에 부모의 속성이 바뀌어도 transition속성이 있다면 애니메이션이 된다.

이 방식으로 중앙에있던 것을 왼쪽으로 옮기고 싶으면 left: 0을 하면 되는데 이 경우, 이미 있던 속성의 값이 바뀌는 것이기 때문에 transition속성이 있다면 애니메이션이 된다.

 

 

3. display: flex; 방식

사실 이게 제일 편한 방식이긴 하다.

<style>
    #box{
        width: 100%;
        height: 100%;
        background: #000;
        display: flex;
        justify-content: space-around;
        align-items: center;
    }
    .box1{
        width: 100px;
        height: 100px;
        background: #22b8cf;
    }
</style>
<div id="box">
    <div class="box1">box1</div>
</div>

이렇게 자식요소에는 아무것도 하지 않는다.

부모요소에 display: flex;를 주면 flex에 지원하는 속성들을 사용할 수 있다.

justify-content는 가로정렬을 어떻게할건지,

align-items는 세로정렬을 어떻게할건지 정한다.

 

사실은 여기서 설명한 의미하고는 조금 다르나, 이 글의 목적이 flex를 설명하는 글도 아닐뿐만 아니라, 나중에 다른글을 통해서 display: flex;에 대해 소개하도록 하겠다.

 

justify-content속성에 flex-start를 하면 왼쪽정렬, flex-end를 하면 오른쪽정렬이 된다.

align-items도 마찬가지로 flex-start를 하면 위쪽정렬, flex-end를 하면 아래쪽정렬이 된다.

이 둘을 조합해서 사용하는것도 가능하다.

 

사실 justify-content: center;도 있긴있다. 그러나 이건 갓스플로러에서 제대로된 실행을 보장할수 없다.

따라서 자식이 하나일때 같은결과를 내는 space-around를 사용하였다. 크롬만 할거면 center를 써도 괜찮다.

실행결과이다.

사실 이게 제일 간단하고 좋은 방법인것 같다.

 

Animation

이 방식은 부모가 속성으로 잡아주기는 하지만 동적인 속성이 아니다. 그냥 위치를 정해는 것뿐이다.

그렇기때문에 애니메이션으로 부모의 width, height와 같은 속성이 변경되면 위치를 정해주기 때문에 정렬되는 자식도 서서히 이동한다.

그러나 예를들어 가운데였다가 왼쪽으로 이동하고싶어서 flex-start속성으로 바꾸면, 이는 위치나 속성의 값이 변경된것이 아니라 위치를 정해주는 방법 자체가 변경된 것이기 때문에 기존의자리에서 새로운자리까지 애니메이션되지 않는다.

 

 

 

이렇게 대강 3가지의 방식을 알아보았다. 여기서 서술한 모든 방법은 width, height를 절대 정적으로 박아넣는 방식을 사용하지 않았다. 따라서 부모의 크기에 따라서 위치가 동적으로 변화한다.

 

글을 쓰기 위해서 내가 알고있는 지식이 맞는지 보기 위해서 검색을 해본 결과, 100px짜리 div를 margin-left로 밀고 50px을 정적으로 빼주고있었다. 더 심한것은 height 50%짜리 div를 위에다가 놓고 정렬할 자식요소에 margin-top: -50px;을 하고있는 충격적인 장면을 볼 수 있었다. 이렇게 짜면 애니메이션 넣을때도, 유지보수할때도 조진다.

 

하나의 완성된 application을 만든다고 했을때 물론 정적일 수 도 있겠지만, db에 무슨내용이 들어가있는지에 따라서, 내용이 얼마나 많은지, 적은지에 따라서 width, height는 바뀔 수 있는데 이러한 상황에서 정적으로 px을 입력해서 박아넣는것은 반응형웹을 제작할 때에도 좋지 못하고, 설령 같은 페이지를 보여준다고 하더라도, 모든 디바이스의 width, height값이 같은것도 아니다. 당장 f11만 눌러도 전체화면이 되는데 이러한 상황에서 적정으로 값을 박아서 정렬하는 것은 의미가 없다고 본다.

 

그럼 ㅅㄱ

반응형

'푸로그래밍 > HTML, CSS' 카테고리의 다른 글

[CSS] box-sizing: border-box;  (0) 2019.11.21
[CSS] CSS로 반응형 웹 만드는 방법  (0) 2019.10.29