Skip to content

Commit 8b43cea

Browse files
[요소 사이즈와 스크롤] 재번역
1 parent 4f2094f commit 8b43cea

File tree

1 file changed

+47
-44
lines changed

1 file changed

+47
-44
lines changed

2-ui/1-document/09-size-and-scroll/article.md

Lines changed: 47 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# 요소 사이즈와 스크롤
22

3-
자바스크립트는 요소의 너비, 높이와 같은 기하 정보를 알려주는 다양한 프로퍼티를 지원합니다.
3+
자바스크립트는 요소의 너비나 높이 같은 기하 정보 관련 프로퍼티를 지원합니다.
44

5-
이런 프로퍼티들은 요소를 움직이거나 특정 좌표에 위치시킬 때 사용됩니다.
5+
이런 프로퍼티는 요소를 움직이거나 특정 좌표에 위치시킬 때 사용할 수 있습니다.
66

77
## 샘플 요소
88

@@ -23,22 +23,22 @@
2323
</style>
2424
```
2525

26-
`example`이라는 id가 붙은 이 요소는 border와 padding, 스크롤바 갖습니다. 기하 관련 기능을 테스트 하기 위해 적절한 조합이죠. margin은 요소 자체에 포함되지 않고, 관련 특수 프로퍼티가 없기 때문에 CSS 프로퍼티에 추가하지 않았습니다.
26+
`example`이라는 id가 붙은 이 요소에 border와 padding 프로퍼티 값을 주고, 스크롤바도 생기게 만들어두었습니다. 기하 프로퍼티를 실습해 보기 적절한 조합이죠. 참고로 margin은 요소 자체에 포함되지 않고, 관련한 특수 자바스크립트 프로퍼티도 없어서 CSS 프로퍼티에 추가하지 않았습니다.
2727

2828
요소의 생김새는 다음과 같습니다.
2929

3030
![](metric-css.svg)
3131

32-
[샌드박스](sandbox:metric)열면 요소를 직접 확인해 볼 수 있습니다.
32+
[샌드박스](sandbox:metric)열어 요소를 직접 확인해 보세요.
3333

3434
```smart header="스크롤바를 잊지 마세요."
35-
샘플로 사용하게 될 요소는 스크롤 바가 있는 가장 복잡한 상황을 나타냅니다. 모든 브라우저가 그런 건 아니지만 몇몇 브라우저는 콘텐츠 영역 너비('content width'로 표시한 영역) 일부를 빌려 스크롤바를 위치시킵니다.
35+
요소에 스크롤바가 생기면 복잡한 상황이 생깁니다. 모든 브라우저가 그런 건 아니지만 몇몇 브라우저는 콘텐츠 영역 너비('content width'로 표시한 영역) 일부를 빌려 스크롤바를 위치시키기 때문입니다.
3636
37-
스크롤바가 없었다면 content width는 `300px`이 되었을 겁니다. 그런데 스크롤바의 너비가 `16px`이기 때문에 content width는 `284px`(300 - 16)가 됩니다(스크롤바 너비는 브라우저나 디바이스마다 다릅니다). 개발자는 요소를 다룰 때 스크롤바가 차지하는 공간을 항상 염두하고 있어야 합니다. 스크롤바가 없다면 계산이 쉬웠겠지만, 연습을 위해 샘플 요소에 스크롤바를 필수적으로 포함시켰습니다.
37+
샘플 예시에서 스크롤바가 없었다면 콘텐츠 영역 너비는 `300px`이었을 겁니다. 그런데 스크롤바가 `16px`을 차지하기 때문에 콘텐츠 영역 너비가 `284px`(300 - 16)이 되었습니다(스크롤바 너비는 브라우저나 디바이스마다 다릅니다). 스크롤바가 없었다면 계산이 매우 쉬웠겠지만, 연습을 위해 샘플 요소에 스크롤바를 일부러 포함했습니다. 요소를 다룰 때는 스크롤바가 차지하는 공간을 항상 염두에 두세요.
3838
```
3939

4040
```smart header="`padding-bottom` 영역으로 텍스트가 넘칠 수 있습니다."
41-
패딩은 대개 비어있습니다. 그런데 요소 내 텍스트가 길어 넘치게 될 경우엔 브라우저가 이 텍스트들을 `padding-bottom`에도 표시하게 됩니다. 이는 정상적인 동작입니다.
41+
그림에선 패딩에 아무것도 보이지 않게 해두었긴 하지만 요소 내 텍스트가 길어 넘치게 될 경우엔 브라우저가 이 텍스트들을 `padding-bottom`에 표시합니다. 이는 정상적인 동작입니다.
4242
```
4343
4444
## 기하 프로퍼티
@@ -49,7 +49,7 @@
4949
5050
기하 프로퍼티의 값은 숫자인데 그 단위는 '픽셀'입니다. 기하 프로퍼티는 픽셀 단위로 측정된다고 보시면 됩니다.
5151
52-
이제 요소 제일 밖부터 시작해 기하 프로퍼티를 하나씩 살펴보도록 합시다.
52+
이제 요소 제일 밖부터 시작해 차근차근 기하 프로퍼티를 살펴보도록 합시다.
5353
5454
## offsetParent와 offsetLeft, offsetTop
5555
@@ -63,7 +63,7 @@ CSS `position` 프로퍼티가 설정되어있는 조상 요소가 없는 경우
6363
2. `<td>`나 `<th>`, 혹은 `<table>`
6464
3. `<body>`
6565
66-
`offsetLeft`, `offsetTop` 프로퍼티는 `offsetParent`를 기준으로 각각 요소가 오른쪽으로, 아래쪽으로 얼마나 떨어져 있는지를 나타냅니다.
66+
`offsetLeft` `offsetTop` 프로퍼티는 `offsetParent`를 기준으로 각각 요소가 오른쪽으로, 아래쪽으로 얼마나 떨어져 있는지를 나타냅니다.
6767
6868
예시를 살펴봅시다. 안쪽에 있는 `<div>`의 `offsetParent`는 `<main>`이고 `offsetLeft`와 `offsetTop`은 각각 `180`입니다.
6969
@@ -75,14 +75,14 @@ CSS `position` 프로퍼티가 설정되어있는 조상 요소가 없는 경우
7575
</main>
7676
<script>
7777
alert(example.offsetParent.id); // main
78-
alert(example.offsetLeft); // 180 (문자열 '180px'이 아닌 숫자가 반환됩니다.)
78+
alert(example.offsetLeft); // 180 (주의: 문자열 '180px'이 아닌 숫자 180이 반환됩니다.)
7979
alert(example.offsetTop); // 180
8080
</script>
8181
```
8282

8383
![](metric-offset-parent.svg)
8484

85-
다음과 같은 경우에 `offsetParent` `null`입니다.
85+
다음 같은 경우엔 `offsetParent` `null`이 될 수 있습니다.
8686

8787
1. 화면에 보이지 않는 요소(CSS `display` 프로퍼티가 `none`이거나 문서 내에 있지 않은 요소)
8888
2. `<body>``<html>`
@@ -92,71 +92,71 @@ CSS `position` 프로퍼티가 설정되어있는 조상 요소가 없는 경우
9292

9393
이제 본격적으로 요소 자체에 집중해 봅시다.
9494

95-
`offsetWidth``offsetHeight`는 가장 간단한 프로퍼티입니다. 두 프로퍼티는 각각 요소 '전체'가 차지하는 너비와 높이 정보를 제공합니다. '전체'이기 때문에 테두리 역시 포함됩니다.
95+
`offsetWidth``offsetHeight`는 가장 간단한 프로퍼티입니다. 두 프로퍼티는 각각 요소 '가장 바깥 부분(outer)'이 차지하는 너비와 높이 정보를 제공합니다. 테두리를 포함한 요소 '전체'의 사이즈 정보를 제공한다고 보시면 됩니다.
9696

9797
![](metric-offset-width-height.svg)
9898

9999
샘플 요소를 대상으로 `offsetWidth``offsetHeight`를 계산하면 다음과 같습니다.
100100

101-
- `offsetWidth = 390` -- 안쪽 너비(콘텐츠 너비 + 스크롤바)에 패딩(`2 * 20px`)과 테두리(`2 * 25px`) 더한 값
102-
- `offsetHeight = 290` -- 전체 높이
101+
- `offsetWidth = 390` -- CSS width 프로퍼티(`300px`)를 사용해 얻을 수 있는 바깥 너비에 패딩(`2 * 20px`)과 테두리(`2 * 25px`) 너비를 더한 값
102+
- `offsetHeight = 290` -- 바깥 높이
103103

104-
````smart header="화면에 표시되지 않는 요소의 기하 프로퍼티는 0 또는 null입니다."
105-
기하 프로퍼티는 오직 보이는 요소(displayed element)를 대상으로 계산됩니다.
104+
````smart header="화면에 표시되지 않는 요소의 기하 프로퍼티 값은 0 또는 null입니다."
105+
기하 프로퍼티는 보이는 요소(displayed element)를 대상으로만 계산됩니다.
106106
107-
따라서 요소(혹은 이 요소의 조상 요소 중 어떤 것이든)의 CSS `display` 프로퍼티가 `none`이거나 문서 내에 해당 요소가 없는 경우, 모든 기하 프로퍼티 값은 0이 됩니다(`offsetParent` 프로퍼티의 값은 `null`).
107+
따라서 요소(혹은 이 요소의 조상 요소 중 어떤 것이든)의 CSS `display` 프로퍼티가 `none`이거나 문서 내에 해당 요소가 없으면 모든 기하 프로퍼티 값이 0이 됩니다(`offsetParent` 프로퍼티의 값은 `null`).
108108
109109
요소를 만들긴 했지만 아직 문서에 삽입하기 전이라던가, 새롭게 만든 요소의 `display` 프로퍼티가 `none`이면 기하 프로퍼티 값은 0, `offsetParent` 프로퍼티의 값은 `null`이 되는 것이죠.
110110
111-
이런 특징을 이용하면 요소의 숨김 상태 여부를 아래와 같은 방법을 사용해 확인할 수 있습니다.
111+
이런 특징을 이용하면 요소의 숨김 상태 여부를 아래 같은 방법으로 확인할 수 있습니다.
112112
113113
```js
114114
function isHidden(elem) {
115115
return !elem.offsetWidth && !elem.offsetHeight;
116116
}
117117
```
118118
119-
그런데 위 함수 `isHidden`은 요소가 화면에 있긴 하지만 사이즈가 0일 때(비어있는 `<div>` 등)도 `true`를 반환하기 때문에 주의해서 사용해야 합니다.
119+
참고로 `isHidden`은 요소가 화면에 있긴 하지만 사이즈가 0일 때(비어있는 `<div>` 등)도 `true`를 반환하기 때문에 주의해서 사용해야 합니다.
120120
````
121121

122122
## clientTop과 clientLeft
123123

124-
요소 내엔 테두리(border) 있습니다.
124+
테두리(border)는 요소 내에 있습니다.
125125

126-
테두리 두께는 `clientTop``clientLeft`사용해 측정할 수 있습니다.
126+
`clientTop``clientLeft`사용하면 테두리 두께를 측정할 수 있습니다.
127127

128-
샘플 예시의 프로퍼티 값은 다음과 같습니다.
128+
샘플 예시에서 테두리 두께를 계산하면 다음과 같습니다.
129129

130130
- `clientLeft = 25` -- 왼쪽 테두리 너비
131131
- `clientTop = 25` -- 위쪽 테두리 높이
132132

133133
![](metric-client-left-top.svg)
134134

135-
그런데 사실 이 두 프로퍼티는 테두리의 너비, 높이와 정확히 일치하진 않습니다. 정확히는 테두리 바깥쪽을 기준으로 하는 요소 안쪽의 상대 좌표를 나타냅니다.
135+
그런데 사실 `clientTop``clientLeft` 프로퍼티는 테두리 높이, 너비와 정확히 일치하지 않습니다. 정확히는 테두리 바깥을 기준으로 한 테두리 안 상대 좌표를 나타냅니다.
136136

137137
조금 헷갈릴 수 있으니 자세히 설명해보겠습니다.
138138

139-
두 프로퍼티의 차이는 운영 체제 언어가 아랍어나 히브리어처럼 오른쪽에서 왼쪽으로 글이 전개되는 언어로 세팅되어 있을 때 드러납니다. 이때는 스크롤바가 오른쪽이 아닌 왼쪽에 나타나게 되는데, 그럼 `clientLeft`에 스크롤바의 너비가 포함됩니다.
139+
`clientTop``clientLeft` 차이는 아랍어나 히브리어처럼 오른쪽에서 왼쪽으로 글이 전개되는 언어일 때 드러납니다. 아랍어가 세팅된 브라우저에선 스크롤바가 오른쪽이 아닌 왼쪽에 나타나게 되는데, 그럼 `clientLeft`에 스크롤바의 너비가 포함됩니다.
140140

141-
따라서 `clientLeft``25`가 아닌 스크롤바 너비를 포함한 `41(25 + 16)`됩니다.
141+
`clientLeft``25`가 아닌 스크롤바 너비를 포함한 `41(25 + 16)`되는 거죠.
142142

143-
히브리어 예시를 그림으로 직접 살펴봅시다.
143+
히브리어를 예시로 직접 살펴봅시다.
144144

145145
![](metric-client-left-top-rtl.svg)
146146

147147
## clientWidth와 clientHeight
148148

149-
clientWidth와 clientHeight 프로퍼티는 테두리 안에 있는 영역의 사이즈 정보를 제공합니다.
149+
clientWidth와 clientHeight 프로퍼티는 테두리 영역의 사이즈 정보를 제공합니다.
150150

151-
여기엔 콘텐츠 너비에 더불어 패딩이 포함되는데, 스크롤바 너비는 포함되지 않습니다.
151+
테두리 안에는 콘텐츠 너비와 패딩이 포함되는데, 스크롤바 너비는 포함되지 않습니다.
152152

153153
![](metric-client-width-height.svg)
154154

155155
그림에서 `clientHeight`로 표시된 부분을 먼저 살펴봅시다.
156156

157-
수평 스크롤바가 없기 때문에 `clientHeight`는 테두리 안쪽에 있는 영역 전체를 더한 값이 됩니다. 높이 `200px`에 위, 아래 패딩(`2 * 20px`)을 더한 값인 `240px`되는 것이죠.
157+
가로 스크롤바가 없기 때문에 `clientHeight`는 테두리 영역 전체를 더한 값이 됩니다. 높이 `200px`에 위, 아래 패딩(`2 * 20px`)을 더한 값인 `240px`되죠.
158158

159-
이제 `clientWidth`를 계산해 봅시다. `clientWidth`를 계산할 때 주의할 점은 수직 스크롤바가 차지하는 너비 `16px` 때문에 콘텐츠 너비는 `300px`이 아닌 `284px`이 된다는 점입니다. 따라서 `clientWidth`는 콘텐츠 너비 `284px`에 왼쪽, 오른쪽 패딩(`2 * 20px`)을 더한 값인 `324px`가 됩니다.
159+
이제 `clientWidth`를 계산해 봅시다. `clientWidth`를 계산할 때 주의할 점은 세로 스크롤바가 차지하는 너비 `16px` 때문에 콘텐츠 너비는 `300px`이 아닌 `284px`이 된다는 점입니다. 따라서 `clientWidth`는 콘텐츠 너비 `284px`에 왼쪽, 오른쪽 패딩(`2 * 20px`)을 더한 값인 `324px`가 됩니다.
160160

161161
**패딩이 없었다면 `clientWidth``clientHeight`는 테두리와 스크롤바 안쪽에 있는 콘텐츠 영역의 너비, 높이와 정확히 일치했을 겁니다.**
162162

@@ -166,21 +166,24 @@ clientWidth와 clientHeight 프로퍼티는 테두리 안에 있는 영역의
166166

167167
## scrollWidth와 scrollHeight
168168

169-
`scrollWidth``scrollHeight` 프로퍼티는 `clientWidth``clientHeight` 유사한데, 스크롤바에 의해 감춰져 있는 숨겨진 영역도 포함한다는 점에서 차이가 있습니다.
169+
`scrollWidth``scrollHeight` 프로퍼티는 `clientWidth``clientHeight` 유사한데, 스크롤바에 의해 감춰진 영역도 포함한다는 점에서 차이가 있습니다.
170170

171171
![](metric-scroll-width-height.svg)
172172

173173
그림을 살펴봅시다.
174174

175175
- `scrollWidth = 324` -- 수평 스크롤바가 없기 때문에 안쪽 영역 전체를 나타내는 `clientWidth`와 동일합니다.
176-
- `scrollHeight = 723` -- 수직 스크롤바에 가려진 부분을 포함하는 콘텐츠 영역 안쪽 전체의 높이입니다.
176+
- `scrollWidth = 324` -- 스크롤 때문에 가려진 영역을 포함한 콘텐츠 영역 높이 전체
177+
178+
- `scrollHeight = 723` -- 세로 스크롤바에 가려진 부분을 포함하는 콘텐츠 영역 안쪽 전체의 높이
179+
- `scrollWidth = 324` -- 콘텐츠 영역 안쪽 전체의 너비. 그림은 가로 스크롤바가 없기 때문에 `clientWidth`와 동일합니다.
177180

178181
`scrollWidth``scrollHeight`는 요소 크기를 콘텐츠가 차지하는 만큼 늘리고자 할 때 사용할 수 있습니다.
179182

180183
예시:
181184

182185
```js
183-
// 콘텐츠가 차지하는 높이만큼 요소 높이를
186+
// 콘텐츠가 차지하는 높이만큼 요소 높이를 늘림
184187
element.style.height = `${element.scrollHeight}px`;
185188
```
186189

@@ -194,31 +197,31 @@ element.style.height = `${element.scrollHeight}px`;
194197

195198
## scrollLeft와 scrollTop
196199

197-
`scrollLeft``scrollTop` 프로퍼티는 수평 스크롤이 오른쪽, 수직 스크롤이 아래로 움직임에 따라 가려진 영역의 너비와 높이를 나타냅니다.
200+
`scrollLeft``scrollTop`은 가로 스크롤이 오른쪽, 세로 스크롤이 아래로 움직임에 따라 가려진 영역의 너비와 높이를 나타냅니다.
198201

199-
수직 스크롤바를 아래로 조금 내린 경우를 가정한 아래 그림을 살펴봅시다. `scrollHeight`에서 `scrollTop`이 얼마만큼의 영역을 차지하는지를 살펴볼 수 있습니다.
202+
세로 스크롤바를 아래로 조금 내린 경우를 가정한 그림을 예시로 들어봅시다. `scrollHeight`에서 `scrollTop`이 얼마만큼의 영역을 차지하는지를 살펴볼 수 있습니다.
200203

201204
![](metric-scroll-top.svg)
202205

203-
`scrollTop`은 '수직 스크롤 바에 의해 가려져 보이지 않는' 위쪽 콘텐츠의 높이라고 이해하시면 됩니다.
206+
이렇게 `scrollTop`은 '세로 스크롤바에 의해 가려져 보이지 않는' 위쪽 콘텐츠의 높이가 됩니다.
204207

205-
````smart header="`scrollLeft``scrollTop`수정할 수 있습니다."
206-
대부분의 기하 프로퍼티는 읽기전용이지만 `scrollLeft``scrollTop`은 변경이 가능합니다. 스크립트를 사용해 프로퍼티를 수정하면 자동으로 요소 내 스크롤이 움직이죠.
208+
````smart header="`scrollLeft``scrollTop`수정 가능합니다."
209+
기하 프로퍼티 대부분은 읽기전용이지만 `scrollLeft``scrollTop`은 변경이 가능합니다. 스크립트로 프로퍼티를 수정하면 자동으로 요소 내 스크롤이 움직입니다.
207210

208211
```online
209212
요소를 클릭하면 스크롤바가 `10px` 아래로 내려가도록 `elem.scrollTop += 10`을 스크립트에 추가해 놓았습니다.
210213
211214
<div onclick="this.scrollTop+=10" style="cursor:pointer;border:1px solid black;width:100px;height:80px;overflow:auto">여기를<br>클릭<br>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9</div>
212215
```
213216

214-
이런 특징을 이용하면 `scrollTop``0`이나 `1e9`같이 아주 큰 숫자로 설정해 스크롤 바를 최상단이나 최하단으로 옮길 수 있습니다.
217+
이런 특징을 이용하면 `scrollTop``0`이나 `1e9`같은 아주 큰 숫자로 설정해 스크롤바를 최상단이나 최하단으로 옮길 수 있습니다.
215218
````
216219
217220
## CSS를 사용해 너비와 높이를 얻지 마세요
218221
219-
지금까지 요소 너비와 높이, 요소 포지셔닝 관련 거리를 구하는 데 사용되는 다양한 기하프로퍼티에 대해 알아보았습니다.
222+
지금까지 요소 너비와 높이, 요소 포지셔닝 관련 거리를 구하는 데 사용되는 기하 프로퍼티를 살펴보았습니다.
220223
221-
그런데 우리는 앞서 `getComputedStyle`를 사용해 CSS가 적용된 요소의 높이와 너비를 구할 수 있다는 것을 <info:styles-and-classes> 챕터에서 알아본 바 있습니다.
224+
그런데 우리는 <info:styles-and-classes> 챕터에서 `getComputedStyle`를 사용해 CSS가 적용된 요소의 높이와 너비를 구할 수 있다는 것을 알아본 바 있습니다.
222225
223226
그렇다면 왜 `getComputedStyle`를 사용해 요소 너비와 높이를 얻지 말라고 하는 걸까요?
224227
@@ -234,7 +237,7 @@ alert( getComputedStyle(elem).width ); // CSS가 적용된 elem의 너비
234237
2. CSS `width`와 `height`는 `auto`일 수 있습니다. 인라인 요소(inline element)가 이런 경우에 속합니다.
235238
236239
```html run
237-
<span id="elem">안녕하세!</span>
240+
<span id="elem">안녕하세요!</span>
238241
239242
<script>
240243
*!*
@@ -243,9 +246,9 @@ alert( getComputedStyle(elem).width ); // CSS가 적용된 elem의 너비
243246
</script>
244247
```
245248
246-
CSS 관점에서 보면 `width:auto`는 전혀 이상할 없어 보입니다. 그런데 자바스크립트 입장에선 정확한 `px`값이 있어야 계산을 할 수 있기 때문에 auto라는 값은 쓸모가 없습니다.
249+
CSS 관점에서 보면 `width:auto`는 전혀 이상할 없어 보입니다. 그런데 자바스크립트 입장에선 정확한 `px`값이 있어야 계산을 할 수 있기 때문에 auto라는 값은 쓸모가 없습니다.
247250
248-
이외에도 다른 한 가지 이유가 더 있습니다. 바로 스크롤바입니다. 스크롤바가 없으면 정상 동작하는데, 스크롤바가 생기면 의도한 대로 동작하지 않는 코드들이 있습니다. 이런 일은 스크롤바가 콘텐츠 영역을 차지하는 몇몇 브라우저에서 발생합니다. 이런 브라우저들에선 콘텐츠가 실제 차지하는 영역이 CSS로 설정한 너비보다 *좁은데*, `clientWidth`와 `clientHeight`는 이를 고려해 클라이언트 요소가 차지하는 공간을 잽니다.
251+
다른 한 가지 이유는 스크롤바때문입니다. 스크롤바가 없으면 정상 동작하는데, 스크롤바가 생기면 의도한 대로 동작하지 않는 코드가 있습니다. 이런 일은 스크롤바가 콘텐츠 영역을 차지하는 몇몇 브라우저에서 발생합니다. 이들 브라우저에선 콘텐츠가 실제 차지하는 영역이 CSS로 설정한 너비보다 *좁은데*, `clientWidth`와 `clientHeight`는 이를 고려해 클라이언트 요소가 차지하는 공간을 계산합니다.
249252
250253
그런데 `getComputedStyle(elem).width`를 사용하면 상황이 달라집니다. Chrome 같은 브라우저는 스크롤바 너비를 제외한 진짜 내부 너비를 반환하는데 Firefox 같은 브라우저는 스크롤바를 무시하고 CSS로 설정한 너비를 반환합니다. 이런 브라우저 간 차이 때문에 `getComputedStyle`이 아닌 기하 프로퍼티를 사용해야 합니다.
251254

0 commit comments

Comments
 (0)