CSS 레이아웃 속성 기초2 - 디스플레이(Display) 속성을 이해하자.

포지션(Positon) 속성과 함께 CSS 레이아웃을 구현할 수 있도록 해주는 가장 중요한 속성입니다.

CSS 속성들 중에서 레이아웃을 만들기 위한 기능들이 가장 많이 추가되었습니다.

적용된 디스플레이(Display) 속성은 속성을 부여한 요소 자신에 적용되는 것과 자식 요소들에 적용되는 2가지로 구분할 수 있습니다.

요소 자신에 적용되는 것은 외부 디스플레이 타입(outer display type)이라고 하고, 자식 요소들의 레이아웃에 영향을 주는 것은 내부 디스플레이 타입(inner display type)이라고 합니다.

디스플레이 속성에 따라서는 외부 디스플레이 타입만 적용되는 것도 있고, 내/외부 디스플레이 타입이 모두 적용되는 것도 있습니다.

외부 디스플레이 타입은 인라인(inline), 또는 블록(block)의 형태 중 하나가 됩니다.

우리가 알고 있듯이 인라인 속성은 요소 안의 콘텐츠 크기만큼의 영역을 차지하고, 왼쪽에서 오른쪽으로 행을 따라 요소들이 채워집니다. 요소들이 다 채워지면 다음 행으로 위치가 바뀌면서 다시 채워지는 과정을 반복하게 됩니다.

이와 달리 블록은 한행에 하나의 요소가 자리를 차지하게 됩니다.

내부 디스플레이 타입은 자식 요소들(또는 손자 요소들까지 포함)에 적용되는 레이아웃 타입으로 디스플레이 속성에 따라 다양한 형태로 구현됩니다. 그리드를 표현하는 display: grid; 속성은 자식 요소들을 격자 형태로 정해진 가로 x 세로 셀들에 순서대로 채워서 배치합니다.


디스플레이 속성 사용 방법

내/외부 디스플레이 타입을 가지는 플렉스 박스를 생성하는 CSS을 예를 들어서 알아보겠습니다.

자식요소의 배치에 영향을 주는 플렉스 박스 디스플레이 속성은 display: flex; 속성만으로 정의합니다.

flex-wrap: wrap; 속성은 자식 요소들이 행을 다 채우면 다음 행으로 넘어가도록 하는 추가 속성입니다. 나머지 속성과 자식 요소를 위한 속성들은 플렉스 박스 레이아웃과는 무관한 장식용 속성입니다.

.flex{
    display: flex; /* 플렉스 레이아웃을 위한 디스플레이 속성 적용 */
    flex-wrap: wrap; /* 행을 다 채우면 다음행으로 개행 */
    width: 600px;
    height: 400px;
}
.flex > div{ /* 자식 요소들의 속성 설정 */
    min-width: 33.333333%;
    height: 200px;
    display: flex; /* 텍스트 가운데 정렬용*/
    justify-content: center;
    align-items: center;
}

다음 HTML 태그에 앞의 플렉스박스 CSS를 적용하면 

<div class="flex">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
</div>

다음과 같이 자식 요소들이 자동으로 적절히 행 단위로 채워지면서 배치되는 레이아웃을 만들 수 있습니다. 가로 600px인 요소에 200px 너비인 자식 요소들을 배치하면 한 행에 3개씩 채워지면서 행 단위로 자식 요소들이 채워집니다.

행을 다 채우면 다음 행을 채우도록 하려면 flex-wrap: wrap; 속성을 추가해서 자식 요소들이 정의한 너비 값 만큼의 영역을 차지하면서 다음행으로 개행이 되도록 해야 합니다.

display: flex; 속성 적용 예

기본 디스플레이 속성

- none

요소가 보이지 않게 되며, 자리도 차지하지 않게 됩니다. 따라서 HTML 문서 레이아웃에도 아무런 영향을 주지 않습니다.

불필요한 요소를 감춰서 완전히 사용자에게 보일 필요가 없을 때 사용합니다.

감추어진 요소는 사용자 액션을 받을 수 없기 때문에, 사용자 액션에 따른 이벤트도 발생시키지 않습니다.

참고로 display: none; 은 보이지 않고 자리도 차지하지 않지만, visibility: none; 은 보이지 않지만 자리를 차지합니다.

- block

요소가 블록 속성을 가지도록 합니다. 뒤에 나오는 레이아웃 속성인 flex, grid, table 속성 또한 블록 속성을 함께 가집니다.

요소에 width, height, padding, margin 속성을 사용해 크기와 여백을 설정할 수 있습니다.

블록 속성은 요소가 화면에 표시되며, 한 행에 하나의 요소가 위치합니다. 기본 속성으로는 가로 영역을 100% 채웁니다.

padding, margin 속성을 사용할 수 있어 요소의 안과 바깥쪽에 여백을 설정할 수 있습니다.

대표적인 인라인 요소인 <span> 태그에 display: block; 속성을 부여하면 블록타입 요소로 바뀌면서 width, height, padding, margin 속성을 사용할 수 있게 됩니다.

- inline

HTML 요소의 순서에 따라 왼쪽에서 오른쪽으로 채워지면서 요소가 배치됩니다. 요소가 다 채워지면 다음 행의 왼쪽에서부터 요소가 채워집니다. 요소의 너비는 요소 안의 콘텐츠 내용만큼이 됩니다.

블록 속성을 가진 요소에 display: inline; 속성을 부여해서 인라인 요소로 바꾸면 width, height, padding, margin 속성 값이 모두 무시되고, 배치 순서에 따라 행의 왼쪽에서 오른쪽으로 나란히 배치됩니다.

- inline-block

inline 속성과 block 속성을 모두 가집니다.

요소에 width, height, padding, margin 속성을 사용해 크기와 여백을 설정할 수 있지만, inline 속성에 따라 왼쪽에서부터 오른쪽으로 요소들이 채워지면서 배치됩니다.

다만 기본 속성일 때 인라인으로 배치되는 요소들 사이에 약간씩 마진(구글 크롬 기준 4px)이 생기는 현상이 있습니다.

표준 규약에 따른 것이어서 버그는 아니지만, 의도하지 않아도 요소 사이에 여백이 생기기 때문에 레이아웃을 설정할 때 여백을 없애고 싶으면 추가의 여백 속성으로 강제 조정을 해야하는 번거로움이 있습니다.

웹 브라우저 종류에 따라서는 여백의 너비가 4px가 아닌 경우도 있기 때문에 임의로 4px의 여백을 조정하면 호환성 문제가 발생합니다. 

여백을 없애려면 float: left; 속성을 추가해서 레이아웃을 왼쪽으로 붙이는 식으로 추가 속성을 설정해야 합니다.

<p class="inlineblock">
    <span>인라인</span>
    <span>텍스트</span>
    <span>출력</span>
</p>

앞의 HTML 태그의 태그에 다음 CSS를 적용하면 패딩 속성이 적용되지 않습니다.

.inlineblock span{
    padding: 20px;
}

다음과 같이 수정하면 <span> 태그가 인라인 블록 속성으로 바뀌면서 패딩이 적용됩니다.

.inlineblock span{
    display: inline-block;
    padding: 20px;
}

레이아웃 속성

 

- contents

최신 디스플레이 속성으로 인터넷 익스플로러에서는 지원되지 않습니다.

속성이 부여된 요소의 컨테이너를 없애는 특징을 가지고 있습니다. 컨테이너가 없어진 요소는 태그는 존재하지만, 하위 요소를 담는 컨테이너의 기능을 못하기 때문에 width, height, padding, margin 속성을 사용할 수 없으며(속성 값 자체가 존재하지 않음), 자식 요소는 상위 요소의 디스플레이 속성의 영향을 받게 됩니다.

<div class="flex">
  <div class="wrapper">
    <p>컨텐츠 컨텐이너 적용 확인</p>
    <p>flex 속성이 적용되는지 확인할 수 있습니다.</p>
  </div>
</div>
.flex{
    display: flex;
    background-color: #f8f8f8;
}
.wrapper{
    display: contents;/* 컨테이너의 기능이 사라짐 */
    background-color: #a88;
}

.wrapper 클래스에 display: contents; 속성이 없으면 다음처럼 블록 속성을 가진 태그가 적용되어 배경색이 적용되고, 자식 요소들인 <p> 태그들이 블록 속성을 유지합니다.

.wrapper 클래스에 display: contents; 속성이 추가되면 요소의 컨테이너가 사라지기 때문에 배경색이 적용되지 않습니다. 그리고 바로 위 부모 요소의 display: flex; 속성이 그대로 자식 요소에 전달되어 <p> 태그들이 플렉스 속성의 자식 요소로 동작하게 됩니다.

- flex

레이아웃과 배치에 사용하는 차세대 속성이라고 할 만큼 범용적이고 활용도가 높은 속성입니다.

이름처럼 플렉시블한 특징을 가지고 있어서 많은 경우에 자동으로 자식 요소들의 너비를 분배해서 레이아웃을 맞춰주기 때문에 사용하기가 쉽고 편리합니다.

가변 레이아웃이나 반응형 웹에서 웹 브라우저 너비에 따라 자동으로 레이아웃의 너비가 조절되도록 할 수 있기 때문에 쉽고 빠른 레이아웃 구현이라는 요구 조건에 잘 부합하는 속성입니다.

기본적으로 블록 속성을 가지고 있습니다.

<div class="flex">
    <p>컨텐츠 컨텐이너 적용 확인</p>
    <p>flex 속성이 적용되는지 확인할 수 있습니다.</p>
</div>

플랙스  디스플레이 속성을 적용하면 자식 요소들은 플렉스 컨테이너의 구성 요소가 되어, 인라인으로 요소들이 배치됩니다.

.flex{
    display: flex;
    background-color: #f8f8f8;
}
플렉스 박스 자식 요소들은 인라인으로 배치됨

플렉스 디스플레이 속성의 자식 요소들은 인라인으로 컨텐츠 영역만큼 자리를 차지하기 때문에 크기 속성을 부여해서 영역을 채울 수 있습니다. 인라인 요소이기 때문에 전체 너비보다 자식 요소들의 너비 합이 더 넓으면 비율에 따라 너비 값이 자동으로 정해집니다.

.flex{
    display: flex;
    background-color: #f8f8f8;
    width: 600px;
}
.flex > p {
	width: 400px;
}
자식 요소의 너비에 따라 실제 너비가 비율에 맞춰 분배됨

- grid

격자형 그리드 구조를 만들 수 있는 속성 값입니다.

바둑판 모양의 행과 열을 가진 구조를 추가 속성 선언만으로 간편하게 만들 수 있고, 셀(들)을 병합해서 영역의 구획을 나눌 수도 있습니다.

행과 열 사이의 여백도 설정할 수 있기 때문에 격자형 구조를 구현하는데는 최적의 속성입니다.

기본적으로 블록 속성을 가집니다.

<div class="grid">
    <div>1행1열</div>
    <div>1행2열</div>
    <div>1행3열</div>
    <div>2행1열</div>
    <div class="merge">2행2열</div>
</div>

<table> 태그, 또는 테이블 디스플레이 속성보다 간편하고 빠르게 격자형 레이아웃 구조를 생성할 수 있습니다.

.grid {
    display: grid;
    width: 600px;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 5px;
    margin: 20px;
}
.grid > div{
    padding: 20px;
    box-sizing: border-box;
}
.grid .merge {
    grid-column: 2/4;
    grid-row: 2;
}

- table

table 태그와 유사한 레이아웃을 CSS로 구현할 수 있도록 해주는 속성입니다. 

모던 웹에 적합하지 않은 테이블 태그를 대신해 일반 태그로 테이블과 같은 격자형 배치를 가능하도록 합니다.

고정된 행과 열 구조를 가지는 테이블과 달리 반응형으로 행과 열 구조를 변경할 수 있기 때문에 조금 더 유연한 격자형 구조를 만들 수 있습니다.

table 속성과 함께 사용할 수 있는 전용 속성 개수가 적어서 다른 레이아웃 속성들의 도움을 받아야 테이블 태그의 속성과 같은 수준의 레이아웃을 만들 수 있습니다.

기본적으로 블록 속성을 가집니다.

table-row, table-column, table-cell 등의 하위 속성을 자식 요소에 적용해 테이블과 유사한 구조를 만들 수 있습니다.

<div class="table">
    <div class="row">
        <div>1행1열</div>
        <div>1행2열</div>
        <div>1행3열</div>
    </div>
    <div class="row">
        <div>2행1열</div>
        <div>2행2열</div>
        <div>2행3열</div>
    </div>
</div>

테이블(table) 디스플레이 속성으로 테이블 구조를 만들 때는 자식 요소와 손자 요소를 사용해야 합니다.

실제 <table> 태그로 테이블을 만들 때, 테이블 외곽을 담당하는 <table> 태그와 행(<tr>) 태그, 그리고 셀(<td>) 태그를 계층으로 감싸서 테이블을 정의는 것처럼, table, table-row, table-cell 디스플레이 속성을 자식 요소와 손자 요소에 순차적으로 적용해야 합니다.

.table{
	display: table;
}
.row {
	display: table-row;
}
.row > div{
  display: table-cell;
  padding: 15px;
  box-sizing: border-box;
  width: 150px;
  height: 100px;
  vertical-align: middle;
  text-align: center;
}
실제 <table> 태그로 만든 테이블과 같은 구조를 만들 수 있음

- list-item

요소가 목록 아이템 태그인 <li> 의 특성을 가지도록 합니다. 목록 태그인 <ul>, <ol>과 동일한 레이아웃을 만들 수 있습니다.

다음 같이 <h2> 태그로 된 목록이 있을 때, 순서 없는 목록(<ol>)과 똑같은 모양을 리스트 아이템(list-item) 속성으로 만들 수 있습니다.

<div class="listitem">
    <h2>첫 번째 아이템</h2>
    <h2>두 번째 아이템</h2>
    <h2>세 번째 아이템</h2>
    <h2>네 번째 아이템</h2>
    <h2>다섯 번째 아이템</h2>
</div>

앞서 설명한대로 리스트 아이템 속성은 <li> 태그 1개를 선언하는 기능을 합니다. 목록 형태를 표현하려면 다음처럼 자식 요소들에 개별 적용해야 합니다.

.listitem > h2{
    display: list-item;
    list-style-type: disc;
    list-style-position: outside;
}

인라인 속성 추가된 레이아웃 속성

- inline-flex

블록 속성을 가진 플렉스 레이아웃을 인라인 속성으로 나열되도록 합니다. 나머지 특징은 flex 속성과 같습니다. 다른 인라인 속성을 가진 요소, 또는 인라인 플렉스 요소들이 배치 순서에 따라 왼쪽에서 오른쪽으로 행을 따라 배치됩니다.

- inline-grid

블록 속성을 가진 그리드 레이아웃을 인라인 속성으로 나열되도록 합니다. 다른 인라인 속성을 가진 요소, 또는 인라인 그리드 요소들이 배치 순서에 따라 왼쪽에서 오른쪽으로 배치됩니다. 나머지 특징은 grid 속성과 같습니다. 

- inline-table

블록 속성을 가진 테이블 레이아웃을 인라인 속성으로 나열되도록 합니다. 다른 인라인 속성을 가진 요소, 또는 인라인 테이블 요소들이 배치 순서에 따라 왼쪽에서 오른쪽으로 배치됩니다. 나머지 특징은 table 속성과 같습니다.


초기화 속성

- inherit

부모 요소의 디스플레이 속성을 상속 받습니다.

- initial

디스플레이 속성을 태그의 기본 속성으로 초기화합니다.