[Bootstrap] 15. 레이아웃 깨짐과 디버깅 방법

[Bootstrap] 15. 레이아웃 깨짐과 디버깅 방법

이전 글에서는 Bootstrap으로 간단한 UI 섹션을 직접 구성해보았습니다. 이번 글에서는 Bootstrap을 사용할 때 자주 발생하는 레이아웃 깨짐 문제와 그 문제를 어떻게 확인하고 해결할 수 있는지 정리해보겠습니다.

Bootstrap은 빠르게 화면을 만들 수 있게 도와주지만, 클래스 구조를 잘못 사용하거나 CSS와 JavaScript 연결이 빠지면 화면이 의도와 다르게 보일 수 있습니다. 처음에는 단순한 오타처럼 보여도, 실제로는 그리드 구조나 반응형 클래스 사용 방식에서 문제가 생기는 경우가 많습니다.


1. Bootstrap 디버깅에서 먼저 확인할 것

Bootstrap 화면이 깨졌을 때는 무작정 클래스를 추가하기보다 기본 연결과 구조부터 확인하는 것이 좋습니다.

  • Bootstrap CSS가 제대로 연결되었는가?
  • Bootstrap JavaScript가 필요한 컴포넌트인가?
  • container → row → col 구조를 지켰는가?
  • 반응형 클래스가 의도한 화면 크기에 맞게 작성되었는가?
  • 직접 작성한 CSS가 Bootstrap 스타일을 덮어쓰고 있지는 않은가?

특히 Dropdown, Modal, Offcanvas, Toast, Tooltip, Popover처럼 동작이 필요한 컴포넌트는 Bootstrap JavaScript가 없으면 제대로 작동하지 않습니다.


2. CSS 연결이 안 된 경우

가장 기본적인 문제는 Bootstrap CSS가 연결되지 않은 경우입니다. 이 경우 버튼, 카드, 그리드, 폼 스타일이 거의 적용되지 않습니다.


<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">

위 코드가 HTML의 head 영역에 들어가 있어야 Bootstrap 스타일이 적용됩니다.


<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>

CSS가 연결되지 않았다면 btn-primary 같은 클래스를 사용해도 일반 버튼처럼 보입니다. 화면이 너무 기본 HTML처럼 보인다면 가장 먼저 CSS 연결을 확인해야 합니다.


3. JavaScript 연결이 안 된 경우

Bootstrap에는 CSS만으로 충분한 컴포넌트도 있고, JavaScript가 필요한 컴포넌트도 있습니다.

CSS만으로 가능한 예 JavaScript가 필요한 예
Button Modal
Card Dropdown
Badge Offcanvas
Table Toast
Alert 기본 스타일 닫을 수 있는 Alert

Modal 버튼을 눌러도 열리지 않거나 Dropdown 메뉴가 펼쳐지지 않는다면 Bootstrap JavaScript 연결을 확인해야 합니다.


<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>

보통 body 태그가 끝나기 직전에 script를 넣습니다. bundle 파일에는 Popper도 포함되어 있어 Tooltip, Popover, Dropdown 같은 컴포넌트 사용 시 편리합니다.


4. viewport meta 태그가 없는 경우

모바일 반응형이 이상하게 보인다면 viewport 설정이 빠져 있는지 확인해야 합니다.


<meta name="viewport" content="width=device-width, initial-scale=1.0">

이 태그가 없으면 모바일 화면에서 Bootstrap의 반응형 그리드가 의도대로 동작하지 않을 수 있습니다. 모바일 화면을 고려하는 웹페이지라면 거의 필수로 들어간다고 보면 됩니다.


5. container 없이 사용하는 경우

Bootstrap 화면이 양쪽 끝에 너무 붙어 보인다면 container가 빠졌을 가능성이 있습니다.

잘못된 예


<div class="row">
  <div class="col-md-6">왼쪽</div>
  <div class="col-md-6">오른쪽</div>
</div>

좋은 예


<div class="container">
  <div class="row">
    <div class="col-md-6">왼쪽</div>
    <div class="col-md-6">오른쪽</div>
  </div>
</div>

container는 화면 전체 폭을 적절히 제한하고 가운데 정렬해줍니다. 일반적인 본문 영역이라면 container를 사용하는 것이 자연스럽습니다.

반대로 화면 전체를 꽉 채우는 배너나 대시보드 영역에서는 container-fluid를 사용할 수 있습니다.


<div class="container-fluid">
  화면 전체 너비를 사용하는 영역
</div>

6. row 없이 col을 사용하는 경우

Bootstrap 그리드는 기본적으로 container → row → col 구조를 따릅니다. 그런데 row 없이 col을 바로 사용하면 정렬이나 간격이 어색해질 수 있습니다.

잘못된 예


<div class="container">
  <div class="col-md-4">카드 1</div>
  <div class="col-md-4">카드 2</div>
  <div class="col-md-4">카드 3</div>
</div>

좋은 예


<div class="container">
  <div class="row">
    <div class="col-md-4">카드 1</div>
    <div class="col-md-4">카드 2</div>
    <div class="col-md-4">카드 3</div>
  </div>
</div>

row는 col들을 가로로 배치하기 위한 부모 역할을 합니다. col은 가능하면 row 안에서 사용하는 습관을 들이는 것이 좋습니다.


7. 컬럼 합이 12를 넘는 경우

Bootstrap의 한 줄은 기본적으로 12칸 기준입니다. 한 줄에서 컬럼 숫자의 합이 12를 넘으면 다음 줄로 넘어갑니다.


<div class="row">
  <div class="col-6">A</div>
  <div class="col-6">B</div>
  <div class="col-6">C</div>
</div>

위 코드는 6 + 6 + 6 = 18이므로 세 번째 컬럼은 다음 줄로 내려갑니다. 한 줄에 3개를 나란히 배치하고 싶다면 아래처럼 작성해야 합니다.


<div class="row">
  <div class="col-4">A</div>
  <div class="col-4">B</div>
  <div class="col-4">C</div>
</div>

4 + 4 + 4 = 12가 되므로 한 줄에 3개가 나란히 배치됩니다.


8. 모바일에서 너무 좁게 보이는 경우

PC에서는 괜찮지만 모바일에서 카드나 컬럼이 너무 좁게 보이는 경우가 있습니다. 이때는 고정 컬럼만 사용하고 있지 않은지 확인해야 합니다.

모바일에서 불편할 수 있는 예


<div class="row">
  <div class="col-4">카드 1</div>
  <div class="col-4">카드 2</div>
  <div class="col-4">카드 3</div>
</div>

col-4는 모든 화면 크기에서 4칸을 차지합니다. 즉 모바일에서도 한 줄에 3개가 들어가므로 카드가 매우 좁아질 수 있습니다.

반응형으로 개선한 예


<div class="row g-3">
  <div class="col-12 col-md-4">카드 1</div>
  <div class="col-12 col-md-4">카드 2</div>
  <div class="col-12 col-md-4">카드 3</div>
</div>

이 구조는 모바일에서는 한 줄에 1개, md 이상에서는 한 줄에 3개가 배치됩니다. 처음에는 col-12 col-md-4 같은 패턴을 자주 사용하면 좋습니다.


9. 간격이 너무 붙거나 너무 벌어진 경우

요소 사이 간격이 이상하다면 margin, padding, gutter를 구분해서 확인해야 합니다.

클래스 역할
m-3 바깥 여백 전체
p-3 안쪽 여백 전체
mb-3 아래쪽 바깥 여백
g-3 row 안의 컬럼 간격

카드 사이 간격을 만들고 싶다면 각 카드에 margin을 주기보다 row에 g 클래스를 사용하는 편이 깔끔합니다.


<div class="row g-4">
  <div class="col-md-4">카드 1</div>
  <div class="col-md-4">카드 2</div>
  <div class="col-md-4">카드 3</div>
</div>

g-4는 컬럼 사이의 가로, 세로 간격을 함께 조절합니다.


10. 이미지가 영역 밖으로 튀어나오는 경우

이미지가 카드나 본문 영역 밖으로 튀어나온다면 img-fluid를 확인해야 합니다.

문제가 생길 수 있는 예


<img src="large-image.jpg" alt="큰 이미지">

개선한 예


<img src="large-image.jpg" class="img-fluid" alt="큰 이미지">

img-fluid는 이미지가 부모 요소의 너비를 넘지 않도록 도와줍니다. 카드 이미지의 비율이 제각각이라면 ratio와 object-fit-cover를 함께 사용할 수도 있습니다.


<div class="ratio ratio-16x9">
  <img src="sample.jpg" class="object-fit-cover" alt="이미지">
</div>

11. Table이 모바일에서 깨지는 경우

표는 열이 많으면 모바일 화면에서 쉽게 깨집니다. 이때는 table-responsive로 감싸는 것이 좋습니다.


<div class="table-responsive">
  <table class="table table-striped table-hover">
    <thead>
      <tr>
        <th>번호</th>
        <th>이름</th>
        <th>이메일</th>
        <th>가입일</th>
        <th>상태</th>
      </tr>
    </thead>

    <tbody>
      <tr>
        <td>1</td>
        <td>홍길동</td>
        <td>hong@example.com</td>
        <td>2026-07-03</td>
        <td>활성</td>
      </tr>
    </tbody>
  </table>
</div>

table-responsive는 작은 화면에서 표를 가로 스크롤로 볼 수 있게 해줍니다. 데이터가 많은 관리자 화면이나 게시판 목록에서 유용합니다.


12. z-index 때문에 컴포넌트가 가려지는 경우

Dropdown, Modal, Tooltip, Popover 같은 컴포넌트가 다른 요소 뒤에 가려지는 경우가 있습니다. 이때는 z-index 문제일 가능성이 있습니다.

특히 직접 작성한 CSS에서 position과 z-index를 강하게 지정한 경우 Bootstrap 컴포넌트와 충돌할 수 있습니다.


.custom-header {
  position: relative;
  z-index: 9999;
}

이런 식으로 너무 큰 z-index를 주면 Modal이나 Dropdown이 의도와 다르게 가려질 수 있습니다. z-index는 꼭 필요한 곳에만 사용하고, 값도 무작정 크게 주지 않는 것이 좋습니다.


13. 직접 작성한 CSS가 Bootstrap을 덮어쓰는 경우

Bootstrap 클래스가 제대로 작동하지 않는 것처럼 보일 때, 사실은 직접 작성한 CSS가 우선 적용되고 있을 수 있습니다.


.card {
  padding: 0;
  border: none;
}

위처럼 Bootstrap에서 이미 사용하는 클래스 이름을 직접 덮어쓰면 전체 카드 스타일이 예상과 다르게 바뀔 수 있습니다.

가능하면 Bootstrap 기본 클래스 이름을 그대로 재정의하기보다, 별도의 사용자 정의 클래스를 추가하는 것이 안전합니다.


.custom-card {
  padding: 24px;
  border-radius: 16px;
}

<div class="card custom-card">
  ...
</div>

이렇게 하면 Bootstrap의 기본 구조를 유지하면서 필요한 부분만 추가로 조절할 수 있습니다.


14. 개발자 도구로 확인하기

레이아웃이 깨졌을 때는 브라우저 개발자 도구를 적극적으로 사용해야 합니다. 크롬 기준으로 F12 또는 마우스 오른쪽 클릭 후 검사 메뉴를 사용할 수 있습니다.

  • Elements 탭에서 HTML 구조 확인
  • Styles 영역에서 어떤 CSS가 적용되는지 확인
  • Computed 영역에서 최종 계산된 스타일 확인
  • Console 탭에서 JavaScript 오류 확인
  • Network 탭에서 CSS, JS 파일이 제대로 로드되었는지 확인

특히 Bootstrap 파일이 404로 뜨거나, Console에 JavaScript 오류가 있다면 컴포넌트가 제대로 동작하지 않을 수 있습니다.


15. 문제 해결 순서

Bootstrap 화면이 깨졌을 때는 아래 순서로 확인하면 효율적입니다.

  1. CSS와 JavaScript 연결 상태를 확인한다.
  2. viewport meta 태그가 있는지 확인한다.
  3. container → row → col 구조를 확인한다.
  4. 컬럼 합이 12를 넘는지 확인한다.
  5. 모바일 화면에서 반응형 클래스가 적절한지 확인한다.
  6. 직접 작성한 CSS가 Bootstrap을 덮어쓰는지 확인한다.
  7. 개발자 도구에서 실제 적용된 스타일을 확인한다.

이 순서대로 보면 대부분의 레이아웃 문제를 빠르게 찾을 수 있습니다. 처음부터 모든 코드를 고치려고 하기보다, 원인을 하나씩 좁혀가는 것이 중요합니다.


16. 자주 발생하는 문제 정리

문제 상황 확인할 부분 해결 방법
스타일이 전혀 적용되지 않음 Bootstrap CSS 연결 link 태그 확인
Dropdown, Modal이 작동하지 않음 Bootstrap JS 연결 bundle script 추가
모바일 화면이 이상함 viewport meta viewport 태그 추가
컬럼 배치가 어긋남 row, col 구조 container → row → col 구조 유지
카드가 너무 붙어 있음 gutter row에 g-3, g-4 추가
이미지가 튀어나옴 img-fluid 이미지에 img-fluid 추가
표가 모바일에서 깨짐 table-responsive table을 table-responsive로 감싸기

17. 정리

  • Bootstrap 화면이 깨지면 CSS, JS 연결부터 확인한다.
  • 동작형 컴포넌트는 Bootstrap JavaScript가 필요하다.
  • 그리드는 container → row → col 구조를 지키는 것이 중요하다.
  • 모바일 화면에서는 col-12, col-md-4 같은 반응형 클래스를 활용한다.
  • 이미지는 img-fluid, 표는 table-responsive를 사용하면 깨짐을 줄일 수 있다.
  • 직접 작성한 CSS가 Bootstrap 기본 스타일을 덮어쓰는지 확인해야 한다.
  • 개발자 도구로 실제 적용된 스타일과 오류를 확인하는 습관이 중요하다.

이번 글에서는 Bootstrap을 사용할 때 자주 발생하는 레이아웃 깨짐과 디버깅 방법을 정리했습니다. 문제가 생겼을 때는 클래스를 무작정 추가하기보다, 연결 상태, 구조, 반응형 클래스, 사용자 CSS 순서로 차근차근 확인하는 것이 좋습니다.

다음 글에서는 Bootstrap 프로젝트를 마무리하면서 자주 쓰는 패턴과 전체 시리즈 핵심 내용을 최종 정리해보겠습니다.