안녕하세요! 프론트엔드 강사입니다. CSS 논리적 속성(Logical Properties)의 세계로 오신 것을 환영합니다! 앞서 여백(Margin/Padding)이나 배치(Position)에서 논리적 속성을 어떻게 쓰는지 보셨다면, 이번에는 요소의 크기(Sizing)를 다룰 차례입니다.
공식 문서의 내용이 조금 낯설게 느껴지실 수 있지만, 제가 실무에서 어떻게 쓰이는지, 왜 이런 개념이 등장했는지 쏙쏙 이해되게 설명해 드릴게요. 자, 시작해 볼까요?
이 가이드에서는 우리 페이지의 요소들의 크기를 지정할 때 사용되는 '물리적 크기 속성(physical dimension properties)'과 글이 흐르는 방향에 맞춰 변하는 '논리적 속성(logical properties)' 사이의 매핑(연결) 관계에 대해 설명해 드릴 거예요.
아이템의 크기를 지정할 때, CSS 논리적 속성 및 값 (CSS logical properties and values) 모듈을 사용하면 수평과 수직(예: 왼쪽과 오른쪽)이라는 물리적인 차원에 얽매이지 않고, 텍스트가 흐르는 방향(인라인 및 블록)과 연관 지어 크기를 지정할 수 있는 엄청난 능력을 얻게 됩니다.
이러한 글의 흐름을 기준으로 하는(flow relative) 매핑 방식은 앞으로 우리 대부분에게 웹 디자인의 새로운 표준(default)이 될 가능성이 높습니다. 하지만 실무 디자인을 하다 보면 물리적 크기 지정과 논리적 크기 지정을 함께 섞어 써야 할 때도 분명 있을 거예요. 쓰기 모드(writing mode)가 어떻게 변하든 상관없이, 특정 요소의 크기는 무조건 물리적인 치수(가로/세로)를 유지해야 하는 경우도 있으니까요.
👨🏫 강사의 팁:
처음엔width,height만 쓰다가inline-size,block-size라는 단어를 보면 머리가 아플 수 있어요. 쉽게 외우는 법을 알려드릴게요!
inline-size: 글씨를 한 줄로 쭉 써 내려가는 방향의 길이입니다. (보통 우리가 아는 가로 넓이,width)block-size: 줄바꿈이 일어나면서 블록이 쌓이는 방향의 길이입니다. (보통 우리가 아는 세로 높이,height)
아래 표는 논리적 속성과 물리적 속성 간의 매핑 관계를 보여줍니다. 이 매핑은 여러분이 영어, 한국어, 아랍어처럼 가로로 글을 쓰는 horizontal-tb (가로쓰기, 위에서 아래로) 쓰기 모드 환경에 있다고 가정하고 작성되었습니다. 이 환경에서는 width가 inline-size에 매핑됩니다.
만약 여러분이 옛날 고문서처럼 세로로 글을 쓰는(vertical) 쓰기 모드로 변경한다면, 그때는 inline-size가 height와 연결되겠죠!
| 논리적 속성 (Logical Property) | 물리적 속성 (Physical Property) |
|---|---|
inline-size | width |
block-size | height |
min-inline-size | min-width |
min-block-size | min-height |
max-inline-size | max-width |
max-block-size | max-height |
width와 height에 대한 논리적 매핑 속성은 각각 인라인 방향의 길이를 설정하는 inline-size와 블록 방향의 길이를 설정하는 block-size입니다. 우리가 평소에 쓰는 한글이나 영어 환경에서 작업할 때는 width를 inline-size로, height를 block-size로 바꾸어 적기만 해도 완전히 동일한 레이아웃 결과를 얻을 수 있습니다.
아래 라이브 예제에서는 writing-mode(쓰기 모드)가 horizontal-tb(가로쓰기)로 설정되어 있습니다.
만약 CSS에서 이 값을 vertical-rl(세로쓰기, 우측에서 좌측으로)로 변경해 보세요. 그러면 width와 height를 사용한 첫 번째 물리적 박스 예제는 글자가 세로로 돌아갔음에도 불구하고 박스의 가로, 세로 크기가 멍청하게 변하지 않고 그대로 유지되는 것을 볼 수 있습니다.
하지만 inline-size와 block-size를 사용한 두 번째 논리적 박스 예제는, 마치 블록 전체가 회전한 것처럼 텍스트가 흐르는 방향을 똑똑하게 따라가면서 크기가 맞춰지는 것을 보실 수 있을 거예요!
<div class="container">
<div class="physical box">I have a width of 200px and a height of 100px.</div>
<div class="logical box">
I have an inline-size of 200px and a block-size of 100px.
</div>
</div>
* {
box-sizing: border-box;
}
.wrapper {
border: 2px solid #f76707;
border-radius: 5px;
background-color: #fff4e6;
}
.wrapper > div {
border: 2px solid #ffa94d;
border-radius: 5px;
background-color: #ffd8a8;
padding: 1em;
color: #d9480f;
}
body {
font: 1.2em / 1.5 sans-serif;
}
.container {
display: flex;
}
.box {
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
padding: 10px;
margin: 10px;
}
.box {
writing-mode: horizontal-tb;
}
.physical {
width: 200px;
height: 100px;
}
.logical {
inline-size: 200px;
block-size: 100px;
}
물론 min-width와 min-height를 위한 매핑 속성도 준비되어 있습니다! 바로 min-inline-size와 min-block-size 입니다. 이 속성들은 고정된 크기 대신 '최소 크기'를 설정한다는 점만 다를 뿐, 작동하는 원리는 inline-size, block-size와 완전히 똑같습니다.
첫 번째 예제와 마찬가지로 아래 코드에서 쓰기 모드를 vertical-rl로 바꿔보면서 어떤 효과가 나타나는지 확인해 보세요. 첫 번째 박스에서는 min-height를, 두 번째 박스에서는 min-block-size를 사용했습니다.
👨🏫 강사의 팁:
min-계열 속성은 안의 내용물(글자 등)이 박스보다 커질 때, 요소가 잘리지 않고 내용물에 맞춰 유연하게 쭉쭉 늘어나게(grow) 해주는 아주 고마운 속성이에요. 실무에서 반응형 웹을 만들 때 필수적인 요소죠!
<div class="container">
<div class="physical box">
I have a width of 200px and a min-height of 5em.
</div>
<div class="logical box">
I have an inline-size of 200px and a min-block-size of 5em.
</div>
</div>
body {
font: 1.2em / 1.5 sans-serif;
}
.container {
display: flex;
}
.box {
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
padding: 10px;
margin: 10px;
}
.box {
writing-mode: horizontal-tb;
}
.physical {
width: 200px;
min-height: 5em;
}
.logical {
inline-size: 200px;
min-block-size: 5em;
}
마지막으로, max-width와 max-height를 논리적으로 대체하기 위해 max-inline-size와 max-block-size를 사용할 수 있습니다. 앞선 예제들처럼 이것도 이리저리 수정해 보면서 어떻게 달라지는지 테스트해 보세요.
<div class="container">
<div class="physical box">I have a max-width of 200px.</div>
<div class="logical box">I have a max-inline-size of 200px.</div>
</div>
body {
font: 1.2em / 1.5 sans-serif;
}
.container {
display: flex;
}
.box {
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
padding: 10px;
margin: 10px;
}
.box {
writing-mode: horizontal-tb;
}
.physical {
max-width: 200px;
}
.logical {
max-inline-size: 200px;
}
resize 속성은 사용자가 박스의 크기를 임의로 조절할 수 있게 할지 말지를 설정하는 속성입니다. 이 속성에는 원래 horizontal(가로로만 리사이즈)과 vertical(세로로만 리사이즈)이라는 물리적 값이 존재하죠.
하지만 resize 속성에도 논리적 키워드 값이 생겼습니다! resize: inline을 사용하면 텍스트가 흐르는 인라인 차원 방향으로만 크기를 조절할 수 있게 되고, resize: block을 사용하면 블록이 쌓이는 차원 방향으로만 조절할 수 있게 됩니다.
그리고 both라는 키워드는 물리적인 관점이나 논리적인 관점 모두에서 동일하게 작동합니다. 이건 양방향(두 차원) 모두 한 번에 크기 조절을 허용하겠다는 뜻이니까요. 자, 아래 예제에서 박스 우측 하단의 크기 조절 손잡이(handle)를 마우스로 직접 잡아끌어 보면서 테스트해 보세요!
👨🏫 강사의 팁:
이resize속성은<textarea>태그에서 기본적으로 활성화되어 있어서 유저들이 입력창 크기를 마음대로 늘릴 수 있죠. 만약 세로 방향(글이 많아지는 방향)으로만 늘리게 하고 가로폭은 찌그러지지 않게 막고 싶다면, 바로resize: block을 써주시면 아주 스마트하게 처리된답니다!
<div class="container">
<div class="physical box">
I have a width of 200px and a height of 100px. I can be resized
horizontally.
</div>
<div class="logical box">
I have an inline-size of 200px and a block-size of 100px. I can be resized
in the inline direction.
</div>
</div>
body {
font: 1.2em / 1.5 sans-serif;
}
.container {
display: flex;
}
.box {
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
padding: 10px;
margin: 10px;
}
.box {
writing-mode: horizontal-tb;
overflow: scroll;
}
.physical {
width: 200px;
height: 100px;
resize: horizontal;
}
.logical {
inline-size: 200px;
block-size: 100px;
resize: inline;
}
수고하셨습니다! 이제 CSS에서 크기를 지정할 때 단순히 width나 height에만 머물지 않고, 다국어 처리나 쓰기 모드의 변화까지 대비하는 '논리적 속성(Logical Properties)'을 자유자재로 다루실 수 있을 거예요. 실무에서도 꼭 활용해 보시기 바랍니다! 화이팅!