Language/HTML, CSS

[HTML/CSS] Vertical-align 수직정렬에 대한 오해

Dev Uni 2022. 8. 3. 23:36

Vertical-align은 당신이 아는 수직정렬이 아니다.

Flex 박스 이용 시 컨텐츠를 어떻게 수직정렬 해야할까?

 

항상 html/css는 가볍게 공부하고 넘어가고 그때 그때 구현하기에 바빴어서 평상시 어려움을 겪었던 수직 정렬에 관하여 말하고자 한다. 자극적인 제목을 사용했지만, 사실 대부분의 사람들이 잘 구현하고 있을 것이다. 이 글은 html/css에 처음으로 뛰어들어 어려움을 겪는 분들에게 나의 경험을 공유하고자 함이다. 

 

 

 

이미지. 초기 화면

        <div class="container" style="display: flex">
            <p>개발자 신재윤입니다 :)</p>
            <img src="./광안리.png" />
        </div>

위와 같은 레이아웃이 있다고 하자. 현재 텍스트는 태그 내부에 작성했고 사진은 img 태그이다. 두 레이아웃은 flex를 이용한 가로배치를 했다. 여기서 우리가 하고자 원하는 작업은 글자를 수직정렬하여 가운데 보내기를 원할 것이다.

 

 

 

이미지. 내가 원하는 화면

        <div class="container" style="display: flex; vertical-align: middle;">
            <p>개발자 신재윤입니다 :)</p>
            <img src="./광안리.png" />
        </div>

그래서 vertical-align: middle 속성을 주면? 저런. 별다른 변화가 없다. 분명히 수평정렬을 할 때 div 박스에 text-align: middle 속성을 주면 글자가 가운데 배치 되었던 경험이 있는데 수직정렬인 vertical-align은 왜 되지 않는 것일까?

 

 

공식문서를 제발 "잘" 보도록 하자

구글 검색을 통하여 여러 게시글을 볼 시간에 공식문서를 먼저 보는 습관을 꼭! 기르자. MDN Docs - text align 를 먼저 보겠다.

 

CSS text-align 속성은 블록 요소나 표의 칸 상자의 가로 정렬을 설정합니다. 
vertical-align
과 동일하나 세로가 아닌 가로 방향으로 동작합니다.

 

 

처음 이 문구를 봤을 때는 vertical-align과 동일하게 동작한다고? 근데 vertical-align은 작동이 잘 안되던데? 라고 생각하고 넘겼지만, 잘 읽어보도록 한다. 분명 text-align은 블록 요소나 표의 칸 상자의 가로 정렬을 한다고 한다. 다음으로 MDN Docs - vertical align 을 살펴보면

 

 

 

vertical-align CSS 속성은 inline 또는 table-cell box에서의 수직 정렬을 지정합니다

 

 

vertical-align은 inline 또는 table-cell box에서의 수직 정렬을 지정한다고 한다. 추가로, 중단까지 내려가면 친절하게 "vertical-align은 오로지 inline과 table-cell 엘리먼트에만 적용된다는 것에 주의하세요: 이 속성을 block level 엘리먼트에 사용할 수 없습니다."라고 설명되어있다.

 

아까, 내가 작성한 문구는 분명 <p> 태그로 작성했었다. <p> 태그는 display 기본 속성이 block인 녀석이다. mdn 문서에서 block에는 적용되지 않는다고 친절히 적어놨는데 나는 왜 안되냐고 울부짖었던 것이다. (멍청이)

 

 

Vertical align의 역할

block level 엘리먼트에 사용할 수 없기 때문에 해당하는 p 태그를 감싸는 div 박스를 만들고 display 속성을 inline-block과 같이 줘서 vertical-align을 주고 수직 정렬을 시킬 수 있다. 하지만 vertical-align을 주로 사용하는 곳은 한 줄 자체에서 수직정렬을 맞출 때 사용하는 것이 더 맞다고 판단했다. 수직 정렬 하는 방법은 vertical-align 이외에도 여러 방법으로 할 수 있어서이다. 따라서 vertical align은 inline 내부의 수직정렬에 더 집중하는 역할이 맞다고 생각한다. 예를 들어, www.티스토리.com 이라고 하면 영어와 한글의 높이가 맞지 않는 경우에 사용할 수 있다.

 

vertical-align을 이용한 글자의 수직 정렬은 자세하게 설명되어 있는 곳이 있어서, 링크로 첨부한다.

 

 

 

해결방법 1. line-height / padding / margin (비추천)

현재, 저는 display를 block이나 inline-block으로 하지 않고 flex를 사용하여 진행하고 있음을 다시 한 번 밝힙니다. block이나 inline-block의 경우 세로 정렬하는 방법은 인터넷에 많이 나와있으니 찾아보시면 나올 것 같습니다 :)

 

- line-height

 

01. line-height를 준 모습

단순하게 p 태그에 line-height: 300px 정도 주고 맞춰본 모습이다. 글 한 줄이 굉장히 많은 영역을 차지하게 하여 가운데에 배치되도록 한 모습이다. line-height는 텍스트 한 줄을 세로 정렬할 때 사용하면 쓸만하다.

 

 

 

- padding

 

02. padding-top을 준 모습

다음으로, padding-top을 150px정도 줬다. 박스의 녹색 부분을 보면 패딩의 상단부분을 주면서 가운데로 내려왔음을 확인 가능하다.

 

 

 

- margin

 

03. margin-top을 준 모습

마지막으로, margin-top을 150px 정도 준 모습이다.

 

세 방법 모두 px(픽셀) 단위로 줬기 때문에 반응형 웹에서는 치명적이다. rem이나 em 단위를 사용하는 것이 반응형에 잘 대처할 수 있다. 하지만 눈 대중으로 픽셀을 주고 가운데 정렬 시키는 방법 보다는 아래의 방법을 추천한다.

 

 

해결방법 2. Flex의 Content를 정렬하는 방법 (추천)

MDN align-content를 보면 flex의 아이템에 관하여 정렬하는 방법이 자세히 나와있다. 

 

        <div class="container" style="display: flex; align-items: center">
            <p>개발자 신재윤입니다 :)</p>
            <img src="./광안리.png" />
        </div>

이렇게 flex의 아이템들에 관하여 align-items: center로 가운데 정렬 시킬 수 있고

 

        <div class="container" style="display: flex">
            <p style="align-self: center">개발자 신재윤입니다 :)</p>
            <img src="./광안리.png" />
        </div>

p 태그에 align-self: center를 이용하여 자기자신을 가운데 정렬 시킬 수도 있다.

 

눈대중으로 하는 방법보다는 이 방법이 훨씬 깔끔하지 않은가?

 

 

 

Bootstrap 사용 시

 

사실, 해당하는 문제는 부트스트랩을 사용하면서 겪었다. 부트스트랩 유틸리티에서 vertical-align: middle;과 동일한 역할을 하는 align-middle을 줬는데 아무리 해도 수직정렬이 되지 않았다. 애초에 <p> 태그에 계속 inline에서 사용 가능한 vertical을 적용하려고 하니 될리가 있나..

 

Bootstrap Docs vertical에서도 "To vertically center non-inline content (like <div>s and more), use our flex box utilities."라고 떡하니 나와있다. <div>는 flex box utilities를 사용하세요!

 

Bootstrap Docs aligns를 살펴보면 flex item들을 정렬하는 것이 잘 나와있었다. 부트스트랩을 사용한 수직 정렬의 코드 최종본은 아래와 같다.

 

        <div class="container">
            <p class="align-self-center">개발자 신재윤입니다 :)</p>
            <img src="./광안리.png" />
        </div>

 

 

사실, 굉장히 단순한 것인데 한 번은 제대로 정리하고 넘어가야겠다 싶어서 이렇게 정리하게 되었다. inline-block을 이용한 수직정렬은 앞으로 잘 사용하지 않을 것 같고 flex나 grid를 자주 사용할 것 같아서 이를 이용한 수직정렬 위주로 정리했다.

 

※ 본 게시글은 공부하면서 작성한 내용이라, 틀린 점이 있을 수 있습니다. 질문 사항이나 틀린 부분은 댓글을 남겨주시기 바랍니다.