> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/creator/content-creator-ko/sdk7/2d-ui/ui-positioning.md).

# UI 배치

UI 엔티티의 위치, 크기, 패딩 및 기타 속성을 설정합니다.

모든 종류의 UI 콘텐츠에는 `uiTransform` 컴포넌트를 사용해 크기, 위치 및 엔터티 정렬과 관련된 기타 속성을 설정합니다.

이 `uiTransform` 컴포넌트는 화면의 2D 공간에서, 매우 비슷하게 작동합니다 `Transform` 컴포넌트는 씬의 3D 공간에서 작동합니다.

***ui.tsx 파일:***

```ts
import { UiEntity, ReactEcs } from '@dcl/sdk/react-ecs'
import { Color4 } from '@dcl/sdk/math'

export const uiMenu = () => (
	<UiEntity
		uiTransform={{
			width: '200px',
			height: '100px',
			justifyContent: 'center',
			alignItems: 'center',
		}}
		uiBackground={{ color: Color4.Green() }}
	/>
)
```

***index.ts 파일:***

```ts
import { ReactEcsRenderer } from '@dcl/sdk/react-ecs'
import { uiMenu } from './ui'

export function main() {
    ReactEcsRenderer.setUiRenderer(uiMenu)
}
```

{% hint style="warning" %}
**📔 참고**: 이 페이지의 아래 모든 코드 조각은 다음이 있다고 가정합니다: `.ts` 위와 비슷한 `ReactEcsRenderer.setUiRenderer()` 함수.
{% endhint %}

## 위치 지정 속성

UI 엔터티의 정렬은 Flexbox 정렬 모델을 기반으로 합니다. 이는 크기가 달라질 수 있는 모달 내부의 중첩 엔터티를 동적으로 구성하는 데 매우 강력한 모델입니다.

{% hint style="info" %}
**💡 팁**: Decentraland의 UI 구현은 다음을 기반으로 합니다 [Yoga](https://yogalayout.com/docs/). 읽어보세요 [이 문서](https://www.joshwcomeau.com/css/interactive-guide-to-flexbox/) Flexbox에서 사용할 수 있는 속성들을 매우 이해하기 쉽고 깊이 있게 다루는 내용을.
{% endhint %}

### 엔터티 크기

다음을 사용하세요 `width` 과 `height` 엔터티의 크기를 설정하려면 다음과 같은 값들을 지원합니다:

* `auto`: 크기는 내부 콘텐츠에 맞게 조정됩니다. 길이가 달라질 수 있는 텍스트에 매우 편리합니다. 값을 "auto"로 작성하세요.
* **백분율**: 부모 측정값의 백분율입니다. 값은 "%"로 끝나는 문자열로 작성하세요. 예를 들어 `10 %`.
* **픽셀**: 값은 숫자로 작성하세요.
* **화면 너비 또는 높이**: vw(뷰 너비)와 vh(뷰 높이)는 Decentraland를 실행하는 창의 전체 크기에 대한 일부를 나타내는 데 사용할 수 있습니다. 예를 들어 `10vw` 는 창 너비의 10%를 의미하고, `25vh` 는 창 높이의 25%를 의미합니다.

이 속성들은 **default** 그 항목의 크기, 즉 flex grow 및 flex shrink 계산이 수행되기 전의 크기에 영향을 줍니다. 최종 크기는 부모 엔터티의 크기와 설정된 Flexbox 속성에 따라 다르게 해석될 수 있습니다.

{% hint style="warning" %}
**📔 참고**: 숫자와 문자열을 모두 지원하는 속성에서는 픽셀 단위로 값을 설정하려면 숫자를 작성하세요. 이러한 필드를 부모의 측정값에 대한 백분율로 설정하려면 값이 "%"로 끝나는 문자열로 작성하세요. 예를 들어 `10 %`. 또한 문자열 끝에 `px`를 붙여 픽셀 값을 문자열로 설정할 수도 있습니다. 예를 들어 `200px`.

* 값이 백분율로 표현될 때, 항상 부모 컨테이너를 기준으로 합니다. UI의 최상위 엔터티에도 부모가 있습니다. 렌더러는 기본적으로 기기 안전 영역인 [`screenInset`](/creator/content-creator-ko/sdk7/2d-ui/onscreen-ui.md#screen-inset-area)안에 이를 배치합니다. 따라서 루트 수준의 `100%` 는 그 영역의 100%입니다. 즉, 휴대폰에서는 화면보다 좁은 영역이며, 데스크톱에서는 둘이 일치합니다. 전체 화면을 기준으로 한 백분율이 필요하다면 `screenInset: 'none'` 를 전달하세요.
* 값이 픽셀 단위로 표현되면 부모의 스케일에는 영향을 받지 않지만, 그렇다고 해서 **아닙니다** 기기의 실제 화면 픽셀을 그대로 쓰는 것도 아닙니다. 기본적으로 활성화되어 있는 가상 화면에서 파생된 UI 스케일 계수로 곱해집니다.  [가상 화면](/creator/content-creator-ko/sdk7/2d-ui/onscreen-ui.md#screen-virtual-scale)가상 화면, 기본적으로 활성화되어 있습니다.  `width: 200` 는 "가상 화면 크기의 화면에서 200px"을 의미하며, 다른 화면에서는 그 비율에 맞게 커지거나 작아집니다.
* 값이 `vh` 또는 `vw`로 표현되면, 부모의 스케일, 가상 화면, 또는 `screenInset`.

에서 `auto` width/height가 작동하려면 다음 규칙이 적용됩니다:

* width/height를 “auto”로 사용하는 UiTransform은 `alignSelf`: `“center”`/`“flex-start”`/`“flex-end”` 또는 `positionType: “absolute”`
* 자식의 UiTransform이 `positionType: “absolute”`, 부모는 그 크기/위치에 맞춰 조정되지 않습니다
* 자식의 UiTransform이 위치 덮어쓰기를 사용하면, 부모는 그 크기/위치에 맞춰 조정되지 않습니다
  {% endhint %}

크기를 더 고급 방식으로 조정할 수 있도록 다음의 다른 속성들도 사용할 수 있습니다:

* `maxWidth` 과 `maxHeight`: *number* 또는 문자열(예: height와 width). 엔터티가 가질 수 있는 최대 크기입니다.
* `minWidth` 과 `minHeight`: *number* 또는 문자열(예: height와 width). 엔터티가 가질 수 있는 최소 크기입니다. 부모가 엔터티의 최소 크기를 담기에 너무 작으면, 자식은 부모 밖으로 넘칠 수 있습니다.
* `flexBasis`: 이는 주 축을 따라 항목의 기본 크기를 축에 독립적으로 제공하는 방식입니다. 자식의 flex basis를 설정하는 것은, 부모가 flex direction: row인 컨테이너일 경우 그 자식의 width를 설정하는 것과 비슷하고, 부모가 flex direction: column인 컨테이너일 경우 자식의 height를 설정하는 것과 비슷합니다.

```ts
import { UiEntity, ReactEcs } from '@dcl/sdk/react-ecs'
import { Color4 } from '@dcl/sdk/math'

export const uiMenu = () => (
	<UiEntity
		uiTransform={{
			alignSelf: 'center',
			alignContent: 'center',
			width: '80%',
			height: '30%',
			minWidth: 300,
			maxWidth: 2500,
			margin: { left: '10%', right: '10%' },
		}}
		uiBackground={{ color: Color4.Green() }}
	/>
)
```

### 자식 엔터티 정렬

기본적으로 자식 엔터티는 부모의 왼쪽 위 모서리를 기준으로 배치됩니다. 다음과 같은 속성을 사용해 `justifyContent` 과 `alignItems` 이 동작을 변경할 수 있습니다.

{% hint style="info" %}
**💡 팁**: 다음을 참조하는 속성은 *content* 주 축을 따라 있는 엔터티를 참조합니다( `flexDirection`). 다음을 참조하는 속성은
{% endhint %}

* `flexDirection`: Flex direction은 노드의 자식들이 배치되는 방향을 제어합니다. 이를 주 축이라고도 합니다. 주 축은 자식들이 배치되는 방향입니다. 교차 축은 주 축에 수직인 축, 또는 줄바꿈된 행이 배치되는 축입니다. 이는 `FlexDirectionType` 타입에서 값을 가져옵니다. 사용 가능한 옵션은 다음과 같습니다:
  * `row` (기본값)
  * `row-reverse`
  * `column`
  * `column-reverse`
* `justifyContent`: 이 속성은 컨테이너의 주 축 안에서 자식들을 어떻게 정렬할지 설명합니다. 예를 들어, 이 속성을 사용하면 `flexDirection` row로 설정된 컨테이너에서는 자식을 가로로, 또는 `flexDirection` column으로 설정된 컨테이너에서는 세로로 가운데 정렬할 수 있습니다. 이 속성의 값은 `JustifyType` 타입의 값이어야 합니다. 가능한 값은 다음과 같습니다:
  * `flex-start` (기본값): 컨테이너의 주 축 시작 부분에 컨테이너의 자식들을 정렬합니다.
  * `flex-end`: 컨테이너의 주 축 끝에 컨테이너의 자식들을 정렬합니다.
  * `center`: 컨테이너의 주 축 중앙에 컨테이너의 자식들을 정렬합니다.
  * `space-between`: 자식들 사이에 남은 공간을 분배하면서, 컨테이너의 주 축 전체에 자식들을 고르게 배치합니다.
  * `space-around`: 자식들 주위를 포함해 남은 공간을 분배하면서, 컨테이너의 주 축 전체에 자식들을 고르게 배치합니다. space-between과 비교하면 space-around를 사용했을 때 첫 번째 자식의 시작 부분과 마지막 자식의 끝 부분에도 공간이 분배됩니다.
  * `space-evenly`: 자식들 사이와 자식들과 컨테이너 가장자리 사이의 간격이 모두 같도록, 남은 공간을 분배하면서 컨테이너의 주 축 전체에 자식들을 고르게 배치합니다.
* `alignItems`: 컨테이너의 교차 축을 따라 자식들을 어떻게 정렬할지 설명합니다. align items는 justify content와 매우 비슷하지만, 주 축에 적용되는 대신 교차 축에 적용됩니다. 이 속성은 다음의 값을 필요로 합니다 `AlignType` 타입에서 값을 가져옵니다. 사용 가능한 옵션은 다음과 같습니다:
  * `stretch`: (기본값) 컨테이너의 자식들을 컨테이너의 교차 축 높이에 맞게 늘립니다.
  * `flex-start`: 컨테이너의 자식들을 컨테이너의 교차 축 시작 부분에 정렬합니다.
  * `flex-end`: 컨테이너의 자식들을 컨테이너의 교차 축 끝 부분에 정렬합니다.
  * `center`: 컨테이너의 교차 축 중앙에 컨테이너의 자식들을 정렬합니다.
  * `baseline`: 컨테이너의 자식들을 공통 기준선에 맞춰 정렬합니다. 개별 자식은 부모에 대한 기준선 참조로 설정할 수 있습니다.
* `alignSelf`: Align self는 `alignItems` 와 같은 옵션과 효과를 갖지만, 컨테이너 내부의 자식들에게 영향을 주는 대신 이 속성을 단일 자식에 적용해 부모 안에서의 정렬을 변경할 수 있습니다. align self는 align items로 부모가 설정한 옵션을 덮어씁니다. 값은 `AlignType`, 참고: `alignItems` 위의 옵션 설명을 참조하세요.
* `alignContent`: align content는 교차 축을 따라 줄들의 분포를 정의합니다. 이는 항목들이 `flexWrap`를 사용해 여러 줄로 감싸질 때만 효과가 있습니다. 값은 `AlignType` 타입에서 값을 가져옵니다. 사용 가능한 옵션은 다음과 같습니다:
  * `flex-start`: (기본값) 감싸진 줄들을 컨테이너의 교차 축 시작 부분에 정렬합니다.
  * `flex-end`: 감싸진 줄들을 컨테이너의 교차 축 끝 부분에 정렬합니다.
  * `stretch`: 감싸진 줄들을 컨테이너의 교차 축 높이에 맞게 늘립니다.
  * `center`: 감싸진 줄들을 컨테이너의 교차 축 중앙에 정렬합니다.
  * `space-between`: 남은 공간을 줄들 사이에 분배하면서, 컨테이너의 주 축 전체에 감싸진 줄들을 고르게 배치합니다.
  * `space-around`: 줄들 주위를 포함해 남은 공간을 분배하면서, 컨테이너의 주 축 전체에 감싸진 줄들을 고르게 배치합니다. space-between과 비교하면 space-around를 사용했을 때 첫 번째 줄의 시작 부분과 마지막 줄의 끝 부분에도 공간이 분배됩니다.
* `flexGrow`: 이는 컨테이너 안의 공간이 주 축을 따라 자식들 사이에 어떻게 분배되어야 하는지를 설명합니다. 자식들을 배치한 뒤 컨테이너는 자식들이 지정한 flex grow 값에 따라 남은 공간을 분배합니다. flex grow는 0 이상의 부동소수점 값을 허용하며, 0이 기본값입니다. 컨테이너는 자식의 flex grow 값에 가중치를 두어 남은 공간을 자식들 사이에 분배합니다.
* `flexShrink`: 자식들의 총 크기가 주 축에서 컨테이너 크기를 초과하는 경우, 주 축을 따라 자식들을 어떻게 줄일지 설명합니다. flex shrink는 flex grow와 매우 비슷하며, 넘친 크기를 음수의 남은 공간으로 간주하면 같은 방식으로 생각할 수 있습니다. 이 두 속성은 필요에 따라 자식들이 커지거나 줄어들 수 있게 해 주므로 함께 잘 작동합니다. flex shrink는 0 이상의 부동소수점 값을 허용하며, 1이 기본값입니다. 컨테이너는 자식의 flex shrink 값에 가중치를 두어 자식들을 줄입니다.
* `overflow`: 엔터티의 자식 크기가 부모를 초과할 때 어떤 일이 발생하는지 결정합니다. 값은 다음의 값을 사용합니다 `OverflowType` 타입으로 해석할 수 있습니다.
  * `hidden`: 넘친 엔터티는 보이지 않게 됩니다.
  * `visible`: 넘친 엔터티가 부모의 여백 밖으로 벗어납니다.
  * `scroll`: 영역이 스크롤 가능해져 플레이어가 넘친 콘텐츠를 스크롤할 수 있습니다. 다음을 참조하세요 [스크롤 가능한 컨테이너](#scrollable-containers) 를 참조하세요.
* `flexWrap`: flex wrap 속성은 컨테이너에 설정되며, 자식이 주 축을 따라 컨테이너 크기를 초과할 때 어떤 일이 일어나는지 제어합니다. 기본적으로 필요하면 자식들은 주 축을 따라 여러 줄로 감싸집니다. wrapping이 `nowrap`으로 비활성화되면 자식들은 한 줄로 강제 배치됩니다(이로 인해 엔터티가 줄어들 수 있습니다). wrap reverse는 wrap과 동일하게 동작하지만 줄의 순서는 반대로 됩니다. 이 속성은 `FlexWrapType` 타입으로 해석할 수 있습니다.
  * `wrap`
  * `nowrap`
  * `wrap-reverse`

### 여백과 패딩

* `margin`: 이 속성은 노드 바깥쪽 주변의 간격에 영향을 줍니다. margin이 있는 노드는 부모의 경계로부터 떨어지게 배치되며, 동시에 형제의 위치도 밀어냅니다. 노드의 margin은 부모가 auto size인 경우 부모의 전체 크기에 기여합니다. 엔터티와 부모의 margin 사이의 공간을 설정합니다. 예상되는 값은 다음 속성을 포함하는 객체입니다 `top`, `왼쪽`, `bottom`, 그리고 `오른쪽`.
* `padding`: 이 속성은 적용된 노드의 크기에 영향을 줍니다. Yoga의 padding은 box-sizing: border-box;가 설정된 것처럼 동작합니다. 즉, 명시적인 크기가 설정되어 있으면 padding은 엔터티의 총 크기에 더해지지 않습니다. auto 크기 노드의 경우 padding은 노드의 크기를 늘리고 자식의 위치도 밀어냅니다. 예상되는 값은 다음 속성을 포함하는 객체입니다 `top`, `왼쪽`, `bottom`, 그리고 `오른쪽`.

### 위치 미세 조정

Flexbox에서는 엔터티의 위치가 주로 부모-자식 관계와 부모와 자식에 설정된 배치 속성에 의해 결정됩니다. 그래서 보통은 `위치` 속성을 전혀 설정할 필요가 없습니다. 하지만 이를 조정하거나, Flexbox의 일반 흐름을 완전히 덮어쓰고 절대 위치를 설정하려는 경우에는 관련 속성이 다음과 같습니다:

* `positionType`: 엔터티가 어떻게 배치되는지 정의합니다. 값은 다음의 값을 사용합니다 `PositionType` 열거형.
  * `relative`: (기본값) 기본적으로 엔터티는 상대적으로 배치됩니다. 이는 엔터티가 레이아웃의 일반 흐름에 따라 배치된 다음, `top`, `오른쪽`, `bottom`, 그리고 `왼쪽`의 값에 따라 해당 위치를 기준으로 오프셋된다는 뜻입니다. 이 오프셋은 형제나 부모 엔터티의 위치에는 영향을 주지 않습니다.
  * `absolute`: 절대적으로 배치되면 엔터티는 일반 레이아웃 흐름에 참여하지 않습니다. 대신 형제와 독립적으로 배치됩니다. 위치는 다음을 기준으로 결정됩니다 `top`, `오른쪽`, `bottom`, 그리고 `왼쪽` 값을.
* `위치`: 위치 값 `top`, `오른쪽`, `bottom`, 그리고 `왼쪽` 은 `positionType`에 따라 다르게 동작합니다. 상대 엔터티의 경우, 지정된 방향으로 엔터티의 위치를 오프셋합니다. 하지만 절대 엔터티의 경우 이러한 속성은 엔터티의 해당 변이 부모의 같은 변으로부터 얼마나 떨어져 있는지를 지정합니다. 예상되는 값은 다음 속성을 포함하는 객체입니다 `top`, `왼쪽`, `bottom`, 그리고 `오른쪽`.

{% hint style="warning" %}
**📔 참고** : 다음에 대한 양수 값 `top` 또는 `왼쪽` 은 부모의 같은 가장자리에서 안쪽으로 측정한 거리입니다. 예: 상단과 왼쪽에 대해 부모를 기준으로 20픽셀의 여백을 남기고 component를 배치하려면 `위치` 를 `{ top: 20, left: 20 }`.
{% endhint %}

### 가시성

* `표시`: 엔터티가 보이는지 여부를 결정합니다. 엔터티를 보이지 않게 하려면 `표시` 를 `none`.

### Z 인덱스

이 `zIndex` 속성은 `UiEntity` 엔터티가 렌더링되는 순서를 결정합니다. 더 높은 `zIndex` 를 가진 엔터티가 더 낮은 `zIndex`보다 위에 렌더링됩니다. 기본 `zIndex` 는 0입니다.

```ts
import { UiEntity, ReactEcs } from '@dcl/sdk/react-ecs'
import { Color4 } from '@dcl/sdk/math'

export const uiMenu = () => (
	<UiEntity
		uiTransform={{
			zIndex: 4
		}}
		uiBackground={{ color: Color4.Green() }}
	/>
)
```

{% hint style="warning" %}
**📔 참고** : `zIndex` 속성은 직접적인 형제 간의 순서만 지정하며, 레이아웃 트리의 다른 부분보다 위에 엔터티를 렌더링하는 데 사용할 수는 없습니다. HTML/CSS 용어로 말하면 모든 DCL UI 요소는 새로운 [스태킹 컨텍스트](https://web.dev/learn/css/z-index#stacking_context)를 만듭니다. 함께 추가된 독립적인 UI 모듈의 순서를 서로 맞추려면 `addUiRenderer()` 을 기준으로 `zIndex` 의 [렌더러 옵션](/creator/content-creator-ko/sdk7/2d-ui/onscreen-ui.md#stacking-order-between-ui-modules) 대신 사용하세요.

맵, 채팅 등을 포함한 기본 Decentraland UI는 항상 다른 모든 UI 요소 위에 렌더링됩니다.
{% endhint %}

## 스크롤 가능한 컨테이너

UI 엔터티에 할당된 크기보다 더 많은 콘텐츠가 있을 때, 영역을 스크롤 가능하게 만들려면 `overflow` 를 `scroll` 를 엔터티의 `uiTransform`에 설정하세요. 그러면 플레이어는 드래그하거나 마우스 휠을 사용해 콘텐츠를 스크롤할 수 있습니다.

스크롤 가능한 컨테이너를 만들려면 부모 엔터티가 고정 크기여야 하며( `width` 과 `height`를 사용하여), 자식들은 그 크기를 초과해야 합니다.

```ts
import { UiEntity, Label, ReactEcs } from '@dcl/sdk/react-ecs'
import { Color4 } from '@dcl/sdk/math'

export const scrollableMenu = () => (
	<UiEntity
		uiTransform={{
			width: 300,
			height: 400,
			overflow: 'scroll',
			flexDirection: 'column',
		}}
		uiBackground={{ color: Color4.fromHexString('#1a1a1a') }}
	>
		{/* 이 자식들은 부모의 400px 높이를 초과하므로 영역이 스크롤 가능해집니다 */}
		<Label value="항목 1" fontSize={18} uiTransform={{ width: '100%', height: 80 }} />
		<Label value="항목 2" fontSize={18} uiTransform={{ width: '100%', height: 80 }} />
		<Label value="항목 3" fontSize={18} uiTransform={{ width: '100%', height: 80 }} />
		<Label value="항목 4" fontSize={18} uiTransform={{ width: '100%', height: 80 }} />
		<Label value="항목 5" fontSize={18} uiTransform={{ width: '100%', height: 80 }} />
		<Label value="항목 6" fontSize={18} uiTransform={{ width: '100%', height: 80 }} />
		<Label value="항목 7" fontSize={18} uiTransform={{ width: '100%', height: 80 }} />
	</UiEntity>
)
```

이는 긴 목록, 인벤토리, 채팅 로그, 리더보드 또는 콘텐츠가 화면에 들어가는 크기를 넘어 계속 늘어날 수 있는 모든 패널을 만드는 데 유용합니다.

또한 다른 UI 레이아웃 안에 스크롤 가능한 컨테이너를 중첩할 수도 있습니다. 예를 들어, 고정된 헤더와 스크롤 가능한 본문이 있는 대화 모달:

```ts
import { UiEntity, Label, ReactEcs } from '@dcl/sdk/react-ecs'
import { Color4 } from '@dcl/sdk/math'

export const dialogWithScroll = () => (
	<UiEntity
		uiTransform={{
			width: 400,
			height: 500,
			flexDirection: 'column',
		}}
		uiBackground={{ color: Color4.fromHexString('#2a2a2a') }}
	>
		{/* 고정 헤더 */}
		<Label
			value="리더보드"
			fontSize={22}
			uiTransform={{ width: '100%', height: 60 }}
		/>

		{/* 스크롤 가능한 본문 */}
		<UiEntity
			uiTransform={{
				width: '100%',
				flexGrow: 1,
				overflow: 'scroll',
				flexDirection: 'column',
			}}
		>
			<Label value="1. Alice - 9500" fontSize={16} uiTransform={{ width: '100%', height: 50 }} />
			<Label value="2. Bob - 8200" fontSize={16} uiTransform={{ width: '100%', height: 50 }} />
			<Label value="3. Charlie - 7800" fontSize={16} uiTransform={{ width: '100%', height: 50 }} />
			<Label value="4. Diana - 6100" fontSize={16} uiTransform={{ width: '100%', height: 50 }} />
			<Label value="5. Eve - 5500" fontSize={16} uiTransform={{ width: '100%', height: 50 }} />
			<Label value="6. Frank - 4900" fontSize={16} uiTransform={{ width: '100%', height: 50 }} />
			<Label value="7. Grace - 4200" fontSize={16} uiTransform={{ width: '100%', height: 50 }} />
			<Label value="8. Hank - 3800" fontSize={16} uiTransform={{ width: '100%', height: 50 }} />
			<Label value="9. Ivy - 3100" fontSize={16} uiTransform={{ width: '100%', height: 50 }} />
			<Label value="10. Jack - 2700" fontSize={16} uiTransform={{ width: '100%', height: 50 }} />
		</UiEntity>
	</UiEntity>
)
```

{% hint style="info" %}
**💡 팁**: 다음을 사용하세요 `flexGrow: 1` 스크롤 가능한 엔터티에 설정해 부모의 남은 공간을 채우도록 하세요. 그러면 다른 형제(예: 헤더나 푸터)가 크기를 바꿔도 자동으로 맞춰집니다.
{% endhint %}

## 반응형 UI 크기

화면 크기가 다른 플레이어는 UI 레이아웃을 다르게 볼 수 있습니다. 픽셀 값은 [가상 화면](/creator/content-creator-ko/sdk7/2d-ui/onscreen-ui.md#screen-virtual-scale) 을 기준으로 스케일링되므로, 동일한 UI가 해상도 전반에서 비율을 유지합니다 — **직접 스케일 계수를 계산할 필요가 없습니다**, 이렇게 하면 스케일링이 두 번 적용됩니다.

{% hint style="warning" %}
**📔 참고**: `devicePixelRatio` 은 UI 레이아웃에 관여하지 않습니다. 이는 디스플레이 밀도 힌트일 뿐이며, 1x, 2x, 3x 텍스처 버전 중 하나를 고를 때 유용합니다. 씬 크기를 이전 SDK 버전에서 조정했다면, 픽셀 크기의 UI가 고밀도(레티나 및 모바일) 화면에서 최대 2\~3배 더 크게 렌더링될 수 있으니, 수동으로 조정한 부분은 다시 확인하세요.
{% endhint %}

{% hint style="danger" %}
**📔 자신의 스케일 계수를 제거하세요.** 씬이 크기를 다음에서 계산한 계수로 곱한다면 `UiCanvasInformation` — 일반적으로 `Math.min(width / 1920, height / 1080)` — 그 곱셈을 제거하세요. 이는 SDK가 이제 기본적으로 적용하는 것과 같은 계수이므로, 둘 다 유지하면 화면 크기에 따라 UI가 제곱 비율로 커집니다. 자신의 계수만 남기고 싶다면 `setUiRenderer(ui, { virtualWidth: 0, virtualHeight: 0 })`.
{% endhint %}

`UiCanvasInformation`, 씬의 루트 엔터티에 기본으로 추가되는 이 항목은 스케일링으로 표현할 수 없는 레이아웃 결정을 내릴 때 여전히 올바른 도구입니다. 예를 들어 좁은 화면에서 다른 대화 배치를 선택하거나, 다음에서 텍스처 해상도를 고르거나 `devicePixelRatio`, 또는 안전 영역을 직접 읽어올 때 그렇습니다. 이것은 크기 지정에 적합한 도구가 아닙니다.

이 `UiCanvasInformation` 컴포넌트에는 다음 정보가 들어 있습니다:

* `height`: 캔버스 높이(픽셀)
* `width`: 캔버스 너비(픽셀)
* `devicePixelRatio`: 기기의 물리 픽셀 해상도와 캔버스 픽셀 간의 비율입니다. 예를 들어 1x, 2x, 3x 텍스처 버전 중 하나를 고를 때 유용한 디스플레이 밀도 힌트입니다.
* `interactableArea`: 하나의 `BorderRect` 객체로, 씬 UI 요소에 지정된 영역을 자세히 설명합니다. 이 객체에는 다음 값이 포함됩니다 `top`, `bottom`, `왼쪽` 과 `오른쪽`, 각각은 탐색기 UI가 차지하는 화면 가장자리의 픽셀 수입니다.
* `screenInsetArea`: 하나의 `BorderRect` 객체로, 기기 또는 플랫폼 UI가 예약한 화면 내부 여백 영역(safe margins)을 자세히 설명합니다. 예를 들어 모바일의 노치, 상태 표시줄, 홈 인디케이터 또는 둥근 모서리 등이 이에 해당합니다. 이 객체에는 다음 값이 포함됩니다 `top`, `bottom`, `왼쪽` 과 `오른쪽`, 각각은 화면 해당 가장자리에서 예약된 픽셀 수입니다. 데스크톱에서는 일반적으로 `0` 모든 면에서

{% hint style="warning" %}
**📔 참고** : 서로 다른 Decentraland 탐색기는 플랫폼의 전역 UI가 다를 수 있으므로 이 값들이 서로 다를 수 있으며, 사용자가 다양한 전역 UI 메뉴를 확장하거나 숨길 때 값이 동적으로 변경될 수도 있습니다.
{% endhint %}

```ts
import { engine, UiCanvasInformation } from "@dcl/sdk/ecs"

export function Main() {
  const canvas = UiCanvasInformation.getOrNull(engine.RootEntity)
  if (!canvas) return
  console.log("캔버스 크기: ", canvas.width, canvas.height)
}
```

UI 크기와 관련한 몇 가지 다른 모범 사례:

* 어떤 UI 요소의 너비나 높이가 동적이라면, 다음도 함께 사용하는 것이 좋습니다 `maxWidth`, `minWidth`, `maxHeight`, 그리고 `minHeight` 매개변수를 사용해 값이 적절한 범위 안에 머물도록 하세요.
* 숫자 폰트 크기는 가상 픽셀 값으로, 다른 값들과 마찬가지로 스케일링됩니다. 대신 캔버스를 기준으로 한 크기를 원해 가상 화면과 상관없이 유지되게 하려면, 다음을 전달하세요 `vw`/`vh` 문자열 — 다음을 참조하세요 [반응형 텍스트 크기](/creator/content-creator-ko/sdk7/2d-ui/ui_text.md#responsive-text-size)

{% hint style="info" %}
**💡 팁**: UI 크기 조정의 작동 예시는 다음을 참조하세요 [`81,-2-ui-screen-inset-area`](https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/81,-2-ui-screen-inset-area) 테스트 씬으로, 세 가지 `screenInset` 모드(`'none'`, `'device'`, `'interactable'`)를 서로 공존하는 세 개의 렌더러로 실행하고, 실시간 `screenInsetArea` 과 `interactableArea` 값과 [`76,-10-UiCanvasInformation`](https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/76,-10-UiCanvasInformation), 이를 읽어 `UiCanvasInformation` 매 프레임마다 UI를 반응형으로 크기 조정합니다.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.decentraland.org/creator/content-creator-ko/sdk7/2d-ui/ui-positioning.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
