Post

[CSS] Calendar가 부모 요소를 벗어나 overflow 되는 현상

작은 모바일 화면에서 Calendar가 부모 요소를 벗어나 overflow되어 스크롤이 생겨버리는 상황

[CSS] Calendar가 부모 요소를 벗어나 overflow 되는 현상

모바일 청첩장 프로젝트에서, 열심히 캘린더를 만들어 레포지토리에 푸쉬했습니다. 그런데…

문제 - 1

Image

이렇게 부모 컨테이너를 벗어나 overflow-scroll이 되어버리는 현상이 발생했습니다.

전체 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table';

const days = ['', '', '', '', '', '', ''];

const CalendarContent = () => {
  const firstDay = new Date(2025, 3, 1).getDay(); // 화요일 = 2
  const lastDate = new Date(2025, 4, 0).getDate(); // 30일

  const dates = Array(firstDay)
    .fill(null)
    .concat([...Array(lastDate)].map((_, i) => i + 1));

  return (
    <div className="w-full h-full leading-9">
      <div className="font-medium text-2xl tracking-wide">2025.04.05</div>
      <div className="mb-5 tracking-wider">토요일 오후 3시</div>

      <div className="text-center px-10 pb-10">
        <Table className="">
          <TableHeader>
            <TableRow>
              {days.map((day, index) => (
                <TableHead
                  key={index}
                  className={
                    day === '' ? 'text-[#c6472b] text-center' : 'text-center'
                  }
                >
                  {day}
                </TableHead>
              ))}
            </TableRow>
          </TableHeader>
          <TableBody>
            {Array.from({ length: Math.ceil(dates.length / 7) }, (_, week) => (
              <TableRow key={week}>
                {dates.slice(week * 7, (week + 1) * 7).map((date, i) => (
                  <TableCell
                    key={i}
                    className={
                      (i === 0 ? 'text-[#c6472b]' : '') ||
                      (date === 5 ? 'bg-[#858585] text-white rounded-full' : '')
                    }
                  >
                    {date || ''}
                  </TableCell>
                ))}
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </div>
    </div>
  );
};

export default CalendarContent;

문제가 되는 부분은 이 부분인 것 같습니다.

1
2
3
4
...
<div className="text-center px-10 pb-10">
  <Table className="">
...

현재 shadCn의 UI 컴포넌트를 사용하고 있는데, Table 컴포넌트의 바깥쪽 컨테이너와 안 쪽 컨테이너를 보시면 w-full이 적용되어 있고, 바깥쪽에는 overflow-auto가 적용되어 있는 것을 볼 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
const Table = React.forwardRef<
  HTMLTableElement,
  React.HTMLAttributes<HTMLTableElement>
>(({ className, ...props }, ref) => (
  <div className="w-full overflow-auto">
    <table
      ref={ref}
      className={cn("w-full caption-bottom text-sm", className)}
      {...props}
    />
  </div>
))
Table.displayName = "Table"

트러블 슈팅 - 1

Image

부모 컨테이너의 너비를 벗어나고 있는 애는 table 태그 요녀석이었습니다.

이전 코드를 보니 px-10으로 왼쪽과 오른쪽에 패딩을 주고 있었는데, 이 패딩값과 테이블의 전체 너비가 맞지 않아서 발생하는 문제일 수 있겠다라는 생각을 했습니다.

그래서 px-10px-4로 줄여보고, 부모 너비를 넘지 않는 선에서 자신의 컨텐츠 크기만큼 차지하게 하기 위해 테이블 태그에 max-w-full을 적용해보았습니다.

max-w-full
max-width: 100% 를 적용해주는 Tailwind 클래스입니다. 이 속성은 요소가 부모 컨테이너의 너비보다 커지는 것을 방지해줍니다. 즉, 요소가 부모보다 커지려고 하면 부모 width 만큼만 커지도록 제한하고, 요소가 부모보다 작다면 요소의 원래 크기를 유지합니다.

결과 - 1

여전히 overflow되어 scroll이 생겨있었습니다… 그리고 원래 요소의 크기를 유지하다보니 화면의 너비가 커지면 왼쪽에 치우쳤습니다.

Image

트러블 슈팅 - 2

치우쳤다면.. 가운데에 놓으면 되지 않나!

table 태그를 감싸고 있던 div 컨테이너에 flex justify-center 를 추가하고, 스크롤이 생기는 것을 방지하기 위해 overflow-auto를 지워줍니다.

table 태그의 max-w-full은 다시 부모 컨테이너의 100%를 유지하기 위해 w-full로 돌려놔주고, justify-center로 인해 남는 공간을 모두 차지하기 위해 flex-1을 추가합니다.

최종 결과

Image

가로 길이가 제일 작았던 Galaxy Z Fold 5 (344px) 에서도 스크롤과 잘림 없이 제대로 가운데에 위치해있는 걸 볼 수 있었습니다! 성공!

➕ 아예 자식 요소들의 width를 정해줄 수도 있지만 유연하게 가고 싶어서 flex를 선택해봤습니다.

This post is licensed under CC BY 4.0 by the author.