Layout
VStack
자식 요소를 세로로 배치하는 수직 스택 컴포넌트.
개요
VStack은 <Flex $css={{ flexDirection: 'column' }}> 의 단축 컴포넌트입니다. display: flex, flex-direction: column이 기본 적용되며, Box의 모든 props를 그대로 상속합니다.
폼 필드 목록이나 카드 내부 콘텐츠처럼 요소를 위에서 아래로 쌓을 때 사용합니다.
언제 사용하나요
- 폼 필드를 위에서 아래로 나열할 때
- 카드 내부의 제목, 본문, 버튼을 수직으로 구성할 때
- 페이지 섹션을 차례로 쌓아 올릴 때
- 수직 방향 간격(gap)만 제어하면 되는 단순한 레이아웃
언제 사용하면 안 되나요
- 요소를 가로로 나열할 때 →
HStack - 방향을 동적으로 바꾸거나 양방향 레이아웃이 필요할 때 →
Flex - 격자 형태로 배치할 때 →
Grid
접근성
기본적으로 <div>를 렌더링합니다. render prop으로 의미에 맞는 요소를 지정하세요.
// 폼 컨테이너
<VStack render={<form />} $css={{ gap: '$spacing-400' }}>
<input type="text" />
<input type="email" />
<button type="submit">제출</button>
</VStack>
// 정렬되지 않은 목록
<VStack render={<ul />} $css={{ gap: '$spacing-200', listStyle: 'none' }}>
<li>항목 1</li>
<li>항목 2</li>
</VStack>Usage
기본 사용법
<VStack $css={{ gap: '$spacing-300' }}> <Box $css={{ padding: '$spacing-300', bgColor: '$primary-10', rounded: '$radius-100' }}><Typo variant="$body-2">One</Typo></Box> <Box $css={{ padding: '$spacing-300', bgColor: '$primary-10', rounded: '$radius-100' }}><Typo variant="$body-2">Two</Typo></Box> <Box $css={{ padding: '$spacing-300', bgColor: '$primary-10', rounded: '$radius-100' }}><Typo variant="$body-2">Three</Typo></Box> </VStack>
gap으로 간격 조정
<HStack $css={{ gap: '$spacing-600', alignItems: 'flex-start' }}> <VStack $css={{ gap: '$spacing-100' }}> <Box $css={{ padding: '$spacing-200', bgColor: '$background-3', rounded: '$radius-100' }}><Typo variant="$body-2">좁은 간격</Typo></Box> <Box $css={{ padding: '$spacing-200', bgColor: '$background-3', rounded: '$radius-100' }}><Typo variant="$body-2">좁은 간격</Typo></Box> <Box $css={{ padding: '$spacing-200', bgColor: '$background-3', rounded: '$radius-100' }}><Typo variant="$body-2">좁은 간격</Typo></Box> </VStack> <VStack $css={{ gap: '$spacing-400' }}> <Box $css={{ padding: '$spacing-200', bgColor: '$background-3', rounded: '$radius-100' }}><Typo variant="$body-2">넓은 간격</Typo></Box> <Box $css={{ padding: '$spacing-200', bgColor: '$background-3', rounded: '$radius-100' }}><Typo variant="$body-2">넓은 간격</Typo></Box> <Box $css={{ padding: '$spacing-200', bgColor: '$background-3', rounded: '$radius-100' }}><Typo variant="$body-2">넓은 간격</Typo></Box> </VStack> </HStack>
stretch (기본 alignItems)
flexbox의 기본 align-items가 stretch이므로, 별도 설정 없이도 자식 요소가 부모 너비를 꽉 채웁니다.
<VStack $css={{ gap: '$spacing-200', width: '300px' }}> <Box $css={{ padding: '$spacing-300', bgColor: '$primary-10', rounded: '$radius-100' }}><Typo variant="$body-2">꽉 찬 너비</Typo></Box> <Box $css={{ padding: '$spacing-300', bgColor: '$primary-20', rounded: '$radius-100' }}><Typo variant="$body-2">꽉 찬 너비</Typo></Box> <Box $css={{ padding: '$spacing-300', bgColor: '$primary-30', rounded: '$radius-100' }}><Typo variant="$body-2">꽉 찬 너비</Typo></Box> </VStack>
alignItems로 가로 정렬 변경
flex-start로 자식 요소를 내용 너비만큼만 렌더링하거나, center로 중앙 정렬합니다.
<HStack $css={{ gap: '$spacing-600', alignItems: 'flex-start' }}> <VStack $css={{ gap: '$spacing-200', alignItems: 'flex-start' }}> <Box $css={{ padding: '$spacing-200', bgColor: '$primary-10', rounded: '$radius-100' }}><Typo variant="$body-2">짧음</Typo></Box> <Box $css={{ padding: '$spacing-200', bgColor: '$primary-10', rounded: '$radius-100' }}><Typo variant="$body-2">조금 더 긴 텍스트</Typo></Box> <Box $css={{ padding: '$spacing-200', bgColor: '$primary-10', rounded: '$radius-100' }}><Typo variant="$body-2">A</Typo></Box> </VStack> <VStack $css={{ gap: '$spacing-200', alignItems: 'center', width: '160px' }}> <Box $css={{ padding: '$spacing-200', bgColor: '$primary-10', rounded: '$radius-100' }}><Typo variant="$body-2">짧음</Typo></Box> <Box $css={{ padding: '$spacing-200', bgColor: '$primary-10', rounded: '$radius-100' }}><Typo variant="$body-2">조금 더 긴 텍스트</Typo></Box> <Box $css={{ padding: '$spacing-200', bgColor: '$primary-10', rounded: '$radius-100' }}><Typo variant="$body-2">A</Typo></Box> </VStack> </HStack>
반응형 gap
<VStack $css={{ gap: { mobile: '$spacing-200', tablet: '$spacing-400', desktop: '$spacing-600' } }}> <Box $css={{ padding: '$spacing-300', bgColor: '$background-2', rounded: '$radius-200' }}><Typo variant="$body-2">섹션 1</Typo></Box> <Box $css={{ padding: '$spacing-300', bgColor: '$background-2', rounded: '$radius-200' }}><Typo variant="$body-2">섹션 2</Typo></Box> <Box $css={{ padding: '$spacing-300', bgColor: '$background-2', rounded: '$radius-200' }}><Typo variant="$body-2">섹션 3</Typo></Box> </VStack>
폼 레이아웃
<VStack $css={{ gap: '$spacing-400', padding: '$spacing-500', bgColor: '$background-2', rounded: '$radius-300', maxWidth: '360px' }}> <VStack $css={{ gap: '$spacing-100' }}> <Box render={<label />} $css={{ color: '$text-1' }}><Typo variant="$label-2">이름</Typo></Box> <Box render={<input />} $css={{ padding: '$spacing-200', rounded: '$radius-100', bgColor: '$background-1', borderColor: '$border-default' }} style={{ border: '1px solid', width: '100%', boxSizing: 'border-box' }} placeholder="홍길동" /> </VStack> <VStack $css={{ gap: '$spacing-100' }}> <Box render={<label />} $css={{ color: '$text-1' }}><Typo variant="$label-2">이메일</Typo></Box> <Box render={<input />} $css={{ padding: '$spacing-200', rounded: '$radius-100', bgColor: '$background-1', borderColor: '$border-default' }} style={{ border: '1px solid', width: '100%', boxSizing: 'border-box' }} placeholder="hello@example.com" /> </VStack> <Box render={<button />} $css={{ padding: '$spacing-300', bgColor: '$primary-50', color: '$white', rounded: '$radius-200' }} style={{ border: 'none', cursor: 'pointer', width: '100%' }}><Typo variant="$body-2">제출</Typo></Box> </VStack>
$css로 추가 스타일 적용
<VStack $css={{ gap: '$spacing-300', padding: '$spacing-400', bgColor: '$background-2', rounded: '$radius-300', maxWidth: '240px', elevation: '$elevation-md' }}> <Box $css={{ color: '$text-1' }}><Typo variant="$heading-6">카드 제목</Typo></Box> <Box $css={{ color: '$text-3' }}><Typo variant="$body-2">카드 본문 내용이 여기에 들어갑니다.</Typo></Box> <Box $css={{ padding: '$spacing-200', bgColor: '$primary-10', rounded: '$radius-100', color: '$primary-80', alignSelf: 'flex-start' }}><Typo variant="$label-2">더 보기</Typo></Box> </VStack>
Props
VStack은 별도의 props를 추가하지 않습니다. BoxProps를 그대로 사용합니다.
Prop
Type
스타일
VStack은 내부적으로 아래 스타일을 기본 적용합니다. $css로 덮어쓸 수 있습니다.
| CSS 속성 | 기본값 |
|---|---|
display | flex |
flex-direction | column |