
CSS가 사용자 경험과 인터페이스를 구성하는 데 있어서 핵심 요소이지만, 많은 개발자분들이 JavaScript 학습에 집중하여 그 중요성을 놓치게 되는 경우가 많습니다. 이로 인해 실무에서는 예상치 못한 스타일링 이슈에 부딪히는 경우가 빈번하게 발생하는데요.
최근에도 한 동료 개발자분께서 스타일링 문제로 도움을 요청하셨습니다. 이 문제는 display 속성만을 활용해 매우 간단하게 해결할 수 있었음에도 불구하고 해결방법을 찾기 어려워하셨습니다. 이러한 상황을 통해 더 많은 개발자분들에게 display속성의 활용법을 공유하고자 이 글을 준비하게 되었습니다.

문제가 발생한 프로젝트에는 아래와 같은 요구사항이 있습니다.
TableActionBar: 사용자가 테이블 데이터와 상호작용할 수 있도록 다양한 컨트롤 요소를 제공하는 컴포넌트입니다.
Table: 정렬된 데이터 집합을 시각적으로 표현하는 컴포넌트입니다.
이 두 컴포넌트는 아래 이미지와 같이 배치되어야 합니다.

TableActionBar와 Table은 동일한 너비를 가져야 합니다.Table의 너비는 데이터의 양과 타입에 따라 변할 수 있습니다. 따라서 TableActionBar의 넓이를 고정적으로 지정할 수 없습니다.다음은 상기된 문제의 코드를 단순화한 버전입니다.
<div>
<TableActionBar />
<Table />
</div>
이렇게 코드를 작성하면, TableActionBar의 너비가 화면 크기에 따라 변하게 됩니다. 이로 인해 추가버튼과 저장버튼의 위치도 변하게 되어 요구 사항을 충족하지 못하게 되죠.

이에 대한 해결방법은 간단합니다.
두 컴포넌트를 감싸는 컴포넌트에 inline-block 속성을 추가하는 것입니다.
<div css={{display: "inline-block"}}>
<TableActionBar />
<Table />
</div>
이렇게 하면,TableActionBar의 너비가 Table의 너비와 동일하게 유지되어, 화면크기가 변해도 버튼의 위치가 변하지 않게 됩니다.

그렇다면 이런 현상이 왜 일어나는지, display속성에 대해 자세히 알아보도록 하겠습니다.
CSS의 display속성은 웹페이지에서 요소의 렌더링 방식을 지정하는 중심적인 역할을 하며, 요소의 내부와 외부 디스플레이 유형을 결정하게 됩니다.
다음은 mdn 사이트의 display 속성에 대한 설명입니다.
The display CSS property sets whether ① an element is treated as a block or inline box and ② the layout used for its children, such as flow layout, grid or flex.
위 설명에 따르면 ① 외부 디스플레이 유형은 요소가 block과 inline 중 어떤 방식으로 플로우 레이아웃에 참여할지를 나타내고, ② 내부 디스플레이 유형은 자식의 레이아웃 방식을 설정합니다.
먼저, '외부 디스플레이 유형'은 요소가 플로우 레이아웃에 어떻게 참여할지를 나타냅니다.
자주 사용하는 외부타입은 다음과 같습니다.
- inline: 요소가 수평으로 배치되며, 주로 텍스트나 다른 인라인 요소와 함께 사용됩니다.
- block: 요소가 수직 방향으로 배치되며, 구조적 요소나 컨테이너에 자주 사용됩니다.
- inline-block: inline의 특성과 block의 특성을 모두 가지고 있어, 수평 배치와 동시에 너비와 높이 설정이 가능합니다.
inline은 요소를 수평 방향으로 배치하는 속성입니다.
width와 height를 명시적으로 설정할 수 없으며, 요소의 크기는 주로 컨텐츠 와line-height에 의해 사이즈가 결정됩니다.
inline 속성은 요소를 수평으로 배치하므로, 수평 방향의 패딩과 마진은 정상적으로 적용되지만 수직 방향에는 영향을 미치지지 않습니다.
특히 inline 속성의 수직 패딩은 스타일링에는 영향을 주지만 다른 요소를 밀어내지 않으므로 주의가 필요합니다.

block 속성은 요소를 수직 방향으로 배치하는 속성입니다.

block속성의 width는 기본적으로 부모 요소의 너비의 거의 100%를 차지[1]하며, 부모 요소의 크기를 결정하는 데 영향을 미칩니다.
width와 height를 명시적으로 설정할 수 있습니다.
margin과 padding값이 수직/수평 모두 적용됩니다.
수직 마진이 서로 중첩된다는 특징이 있습니다. 이는 두 개 이상의 블록 요소가 수직으로 배치될 때, 그 사이의 마진이 하나로 합쳐지는 현상을 말합니다.
inline처럼 수평방향으로 배치되며, 너비의 기본값이 컨텐츠의 크기입니다.block처럼 width와 height를 설정할 수 있습니다.
block과는 다르게 수직마진이 중첩되지 않습니다.
❓ inline-block에서 요소를 배치할 때 gap이 생긴다면?
inline-block으로 요소를 배치할 때 아래와 같이 요소 간에 gap이 발생할 수 있는데요, 이는 소스코드에서 공백을 제거하거나 flex를 사용하면 해결할 수 있습니다.
이에 대한 자세한 내용은 다음 링크를 통해 확인하시면 됩니다.
inline vs block vs inline-block 요약| inline | block | inline-block | |
|---|---|---|---|
| 배치 방향 | 수평 | 수직 | 수평 |
| 기본 너비 | 컨텐츠 크기 | 부모의 거의 100% | 컨텐츠 크기 |
| 너비 설정 | ❌ | ✅ | ✅ |
| 높이 설정 | ❌ | ✅ | ✅ |
| 수평 마진 | ✅ | ✅ | ✅ |
| 수직 마진 | ❌ | ✔️ (중첩) | ✔️(중첩x) |
| 수평 패딩 | ✅ | ✅ | ✅ |
| 수직 패딩 | ✔️ (다른 요소를 밀어내지 못함) | ✅ | ✅ |
요소의 레이아웃 방식을 정의하는 '내부 디스플레이 유형'은 그 요소 자신이 아닌 그 아래의 자식 요소에 적용됩니다.
이 유형의 대표적인 예로는 아래 두 가지가 있습니다.
두 레이아웃 방식은 웹 페이지 구성에서 서로 다른 역할을 하면서도 함께 사용될 수 있는데요, 각각에 대한 더 자세한 내용은 다음 포스팅에서 자세히 알아보겠습니다.

그렇다면 앞선 문제로 돌아가서, 위와 같은 상황이 발생하는 원인은 무엇일까요?

이 문제의 주요 원인은 컨테이너의 기본 block 디스플레이 값이었습니다. div 태그는 기본적으로 block 디스플레이 값을 가지고 있기 때문에, TableActionBar의 너비도 화면의 100%를 차지하게 된 것입니다.

하지만 컨테이너에 inline-block을 적용하면 컨테이너는 Table 너비만큼의 width를 가지게 되고, TableActionBar도 부모의 너비를 차지하게 되어 문제가 해결됩니다.
지금까지 diaplay 속성에 대해 분석해보았습니다.
이번 포스팅에서는 문제가 발생했던 inline, block, inline-block 위주로 알아보았지만 display에는 더 많은 속성이 있습니다. 이에 대해 더 많은 정보를 원하신다면 W3C의 display를 확인해주세요.
지금까지 긴 글 읽어주셔서 감사드리며, 이번 포스팅이 여러분들께 도움이 되기를 기원합니다 👍
block 인 경우 부모 요소의 너비를 100% 차지하지만, margin border padding 등의 CSS 박스 모델 속성이 적용되어 있을 수 있으므로 "거의" 100% 라고 표현했습니다.
잘 읽고 갑니다! 좋은 정보네요! 다음 포스트도 기대하겠습니다 ^^