Divider

Divider (구분선)

Divider 컴포넌트는 요소들을 그룹으로 묶어 시각적 위계를 강조하기 위해 쓰는 가늘고 눈에 거슬리지 않는 선이에요. Material UI의 Divider는 기본적으로 짙은 회색 <hr>로 렌더링되며, 몇 가지 유용한 props만으로 스타일을 빠르게 조정할 수 있어요.

출처: 문서

본문

소개 (Introduction)

Divider는 기본적으로 짙은 회색 <hr> 요소로 렌더링되고, 스타일을 빠르게 조정할 수 있는 여러 유용한 props를 제공해요.

import Card from '@mui/material/Card';
import Box from '@mui/material/Box';
import Chip from '@mui/material/Chip';
import Stack from '@mui/material/Stack';
import Divider from '@mui/material/Divider';
import Typography from '@mui/material/Typography';

export default function IntroDivider() {
  return (
    <Card variant="outlined" sx={{ maxWidth: 360 }}>
      <Box sx={{ p: 2 }}>
        <Stack
          direction="row"
          sx={{ justifyContent: 'space-between', alignItems: 'center' }}
        >
          <Typography gutterBottom variant="h5" component="div">
            Toothbrush
          </Typography>
          <Typography gutterBottom variant="h6" component="div">
            $4.50
          </Typography>
        </Stack>
        <Typography variant="body2" sx={{ color: 'text.secondary' }}>
          Pinstriped cornflower blue cotton blouse takes you on a walk to the park or
          just down the hall.
        </Typography>
      </Box>
      <Divider />
      <Box sx={{ p: 2 }}>
        <Typography gutterBottom variant="body2">
          Select type
        </Typography>
        <Stack direction="row" spacing={1}>
          <Chip color="primary" label="Soft" size="small" />
          <Chip label="Medium" size="small" />
          <Chip label="Hard" size="small" />
        </Stack>
      </Box>
    </Card>
  );
}

기본 사용법 (Basics)

import Divider from '@mui/material/Divider';

Variants

Divider 컴포넌트는 세 가지 variant를 지원해요: fullWidth(기본값), inset, middle.

import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemText from '@mui/material/ListItemText';
import Divider from '@mui/material/Divider';

const style = {
  py: 0,
  width: '100%',
  maxWidth: 360,
  borderRadius: 2,
  border: '1px solid',
  borderColor: 'divider',
  backgroundColor: 'background.paper',
};

export default function DividerVariants() {
  return (
    <List sx={style}>
      <ListItem>
        <ListItemText primary="Full width variant below" />
      </ListItem>
      <Divider component="li" />
      <ListItem>
        <ListItemText primary="Inset variant below" />
      </ListItem>
      <Divider variant="inset" component="li" />
      <ListItem>
        <ListItemText primary="Middle variant below" />
      </ListItem>
      <Divider variant="middle" component="li" />
      <ListItem>
        <ListItemText primary="List item" />
      </ListItem>
    </List>
  );
}

Orientation

orientation prop을 쓰면 Divider를 가로에서 세로로 바꿀 수 있어요. 세로 방향을 사용할 때 Divider는 WAI-ARIA spec을 지키기 위해 <hr> 대신 해당 접근성 속성을 가진 <div>로 렌더링돼요.

import FormatAlignLeftIcon from '@mui/icons-material/FormatAlignLeft';
import FormatAlignCenterIcon from '@mui/icons-material/FormatAlignCenter';
import FormatAlignRightIcon from '@mui/icons-material/FormatAlignRight';
import FormatBoldIcon from '@mui/icons-material/FormatBold';
import Box from '@mui/material/Box';
import Divider, { dividerClasses } from '@mui/material/Divider';

export default function VerticalDividers() {
  return (
    <Box
      sx={{
        display: 'flex',
        alignItems: 'center',
        border: '1px solid',
        borderColor: 'divider',
        borderRadius: 1,
        bgcolor: 'background.paper',
        color: 'text.secondary',
        '& svg': {
          m: 1,
        },
        [`& .${dividerClasses.root}`]: {
          mx: 0.5,
        },
      }}
    >
      <FormatAlignLeftIcon />
      <FormatAlignCenterIcon />
      <FormatAlignRightIcon />
      <Divider orientation="vertical" flexItem />
      <FormatBoldIcon />
    </Box>
  );
}

Flex item

flexItem prop을 쓰면 flex 컨테이너 안에서 Divider를 표시할 수 있어요.

import FormatBoldIcon from '@mui/icons-material/FormatBold';
import FormatItalicIcon from '@mui/icons-material/FormatItalic';
import Box from '@mui/material/Box';
import Divider from '@mui/material/Divider';

export default function FlexDivider() {
  return (
    <Box
      sx={{
        display: 'inline-flex',
        alignItems: 'center',
        border: '1px solid',
        borderColor: 'divider',
        borderRadius: 2,
        bgcolor: 'background.paper',
        color: 'text.secondary',
        '& svg': {
          m: 1,
        },
      }}
    >
      <FormatBoldIcon />
      <Divider orientation="vertical" variant="middle" flexItem />
      <FormatItalicIcon />
    </Box>
  );
}

With children

textAlign prop을 쓰면 Divider로 감싼 요소들의 정렬을 지정할 수 있어요.

import { styled } from '@mui/material/styles';
import Divider from '@mui/material/Divider';
import Chip from '@mui/material/Chip';

const Root = styled('div')(({ theme }) => ({
  width: '100%',
  ...theme.typography.body2,
  color: (theme.vars || theme).palette.text.secondary,
  '& > :not(style) ~ :not(style)': {
    marginTop: theme.spacing(2),
  },
}));

export default function DividerText() {
  const content = (
    <p>{`Lorem ipsum dolor sit amet, consectetur adipiscing elit.`}</p>
  );

  return (
    <Root>
      {content}
      <Divider>CENTER</Divider>
      {content}
      <Divider textAlign="left">LEFT</Divider>
      {content}
      <Divider textAlign="right">RIGHT</Divider>
      {content}
      <Divider>
        <Chip label="Chip" size="small" />
      </Divider>
      {content}
    </Root>
  );
}

커스터마이징 (Customization)

Use with a List

List의 항목들을 분리할 때는 component prop을 써서 <li>로 렌더링해야 해요. 그렇게 하지 않으면 유효한 HTML 요소가 아니게 돼요.

import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemText from '@mui/material/ListItemText';
import Divider from '@mui/material/Divider';

const style = {
  p: 0,
  width: '100%',
  maxWidth: 360,
  borderRadius: 2,
  border: '1px solid',
  borderColor: 'divider',
  backgroundColor: 'background.paper',
};

export default function ListDividers() {
  return (
    <List sx={style} aria-label="mailbox folders">
      <ListItem>
        <ListItemText primary="Inbox" />
      </ListItem>
      <Divider component="li" />
      <ListItem>
        <ListItemText primary="Drafts" />
      </ListItem>
      <Divider component="li" />
      <ListItem>
        <ListItemText primary="Trash" />
      </ListItem>
      <Divider component="li" />
      <ListItem>
        <ListItemText primary="Spam" />
      </ListItem>
    </List>
  );
}

Icon grouping

아래 데모는 variant="middle"과 orientation="vertical" props를 함께 조합하는 방법을 보여줘요.

import Card from '@mui/material/Card';
import Divider, { dividerClasses } from '@mui/material/Divider';
import FormatAlignLeftIcon from '@mui/icons-material/FormatAlignLeft';
import FormatAlignCenterIcon from '@mui/icons-material/FormatAlignCenter';
import FormatAlignRightIcon from '@mui/icons-material/FormatAlignRight';
import FormatBoldIcon from '@mui/icons-material/FormatBold';

export default function VerticalDividerMiddle() {
  return (
    <Card
      variant="outlined"
      sx={{
        display: 'flex',
        color: 'text.secondary',
        '& svg': {
          m: 1,
        },
        [`& .${dividerClasses.root}`]: {
          mx: 0.5,
        },
      }}
    >
      <FormatAlignLeftIcon />
      <FormatAlignCenterIcon />
      <FormatAlignRightIcon />
      <Divider orientation="vertical" variant="middle" flexItem />
      <FormatBoldIcon />
    </Card>
  );
}

접근성 (Accessibility)

Divider는 <hr> 요소이기 때문에 내재된 separator 역할 때문에 화면 낭독기가 이를 "Horizontal Splitter"(또는 orientation prop을 쓰면 vertical)로 알려줘요.

순수하게 스타일 용도로만 사용한다면 aria-hidden="true"를 설정해서 화면 낭독기가 건너뛰도록 권장해요.

<Divider aria-hidden="true" />

텍스트나 칩 같은 다른 요소를 감싸는 용도로 Divider를 쓴다면, component prop으로 렌더링 요소를 일반 <div>로 바꾸고 role="presentation"을 설정하는 걸 권장해요. 이렇게 하면 화면 낭독기가 알려주지 않으면서도 내부 요소의 시맨틱은 그대로 유지돼요.

<Divider component="div" role="presentation">
  <Typography>Text element</Typography>
</Divider>

구조 (Anatomy)

Divider 컴포넌트는 루트 <hr> 하나로 구성돼요.

<hr class="MuiDivider-root">
  <!-- Divider children goes here -->
</hr>

Divider API

임포트 (Import):

import Divider from '@mui/material/Divider';
// or
import { Divider } from '@mui/material';

주요 props:

Name Type Default Description
absolute bool false 절대 위치로 배치되는지 여부
flexItem bool false flex 컨테이너 안에서 사용하는지 여부
orientation 'horizontal' | 'vertical' 'horizontal' 방향 설정
textAlign 'center' | 'left' | 'right' 'center' 자식 요소 정렬
variant 'fullWidth' | 'inset' | 'middle' | string 'fullWidth' 구분선 스타일

ref는 루트 요소인 HTMLHRElement로 전달되고, 그 외의 props는 루트 네이티브 요소에 그대로 전달돼요. 테마에서 MuiDivider를 사용하면 이 컴포넌트의 기본 props를 바꿀 수 있어요.

더 알아보기 (Learn more)