내용으로 건너뛰기 문서 내비게이션으로 건너뛰기
// Offcanvas

몇 가지의 클래스와 JavaScript 플러그인을 사용해 네비게이션이나 쇼핑카트 등에 유용한 숨겨진 사이드바를 사용할 수 있습니다.

작동 원리

오프캔버스는 JavaScript로 뷰포트의 왼쪽, 오른쪽, 혹은 아래쪽에서 표시되는 사이드바 컴포넌트입니다. 버튼이나 앵커는 토글하는 특정 요소에 붙여지는 트리거로 사용되며 data 속성은 JavaScript를 호출하기 위해 사용됩니다.

  • 오프캔버스는 모달과 같이 JavaScript 코드를 일부 공유하고 있습니다. 개념적으로는 아주 비슷하지만 이들은 다른 플러그인입니다.
  • 마찬가지로, 오프캔버승의 스타일과 치수를 위한 source Sass 변수의 일부는 모달 변수로부터 상속받고 있습니다.
  • 오프캔버스를 표시하면 기본적으로 배경이 포함되어져 있어 그것을 클릭하면 오프캔버스가 사라집니다.
  • 모달과 마찬가지로 오프캔버스는 한번에 1개밖에 표시할 수 없습니다.

주의! CSS에 의한 애니메이션 사용을 고려한다면 .offcanvas 요소의 margin이나 translate를 사용할 수 없습니다. 대신, 이 클래스를 독립된 포장 요소 감싸서 사용해 주세요.

이 컴포넌트의 애니메이션 효과는 prefers-reduced-motion 미디어 쿼리에 따라 다릅니다. 접근성 문서의 모션 감소 문단을 참고하세요.

예시

오프캔버스 컴포넌트

다음은 기본적으로 표시되는(.offcanvas.show에 의해) 오프캔버스의 예시입니다. 오프캔버스에는 닫기 버튼이 있는 헤더와 초기 padding을 위한 옵션의 body클래스가 지원됩니다. 가능한 오프캔버스의 헤더에 닫기 액션을 포함시키거나 명시적인 닫기 액션을 제공할 것을 권장합니다.

Offcanvas
Content for the offcanvas goes here. You can place just about any Bootstrap component or custom elements here.
<div class="offcanvas offcanvas-start" tabindex="-1" id="offcanvas" aria-labelledby="offcanvasLabel">
  <div class="offcanvas-header">
    <h5 class="offcanvas-title" id="offcanvasLabel">Offcanvas</h5>
    <button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
  </div>
  <div class="offcanvas-body">
    Content for the offcanvas goes here. You can place just about any Bootstrap component or custom elements here.
  </div>
</div>

라이브 데모

아래의 버튼을 클릭하면 .offcanvas 클래스를 갖고 있는 요소의 .show 클래스를 토글하는 JavaScript로 오프캔버스를 표시/숨김하는 것을 확인할 수 있습니다.

  • .offcanvas 콘텐츠를 숨김 (기본)
  • .offcanvas.show 콘텐츠를 표시

href 속성으로 링크를, data-bs-target 속성으로 버튼을 사용할 수 있습니다. 어느 경우든 data-bs-toggle="offcanvas"가 필요합니다.

Link with href
Offcanvas
Some text as placeholder. In real life you can have the elements you have chosen. Like, text, images, lists, etc.
<a class="btn btn-primary" data-bs-toggle="offcanvas" href="#offcanvasExample" role="button" aria-controls="offcanvasExample">
  Link with href
</a>
<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasExample" aria-controls="offcanvasExample">
  Button with data-bs-target
</button>

<div class="offcanvas offcanvas-start" tabindex="-1" id="offcanvasExample" aria-labelledby="offcanvasExampleLabel">
  <div class="offcanvas-header">
    <h5 class="offcanvas-title" id="offcanvasExampleLabel">Offcanvas</h5>
    <button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
  </div>
  <div class="offcanvas-body">
    <div>
      Some text as placeholder. In real life you can have the elements you have chosen. Like, text, images, lists, etc.
    </div>
    <div class="dropdown mt-3">
      <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown">
        Dropdown button
      </button>
      <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
        <li><a class="dropdown-item" href="#">Action</a></li>
        <li><a class="dropdown-item" href="#">Another action</a></li>
        <li><a class="dropdown-item" href="#">Something else here</a></li>
      </ul>
    </div>
  </div>
</div>

배치

오프캔버스 컴포넌트의 기본 배치는 없으므로 아래 제어자 클래스 중 하나를 추가해야 합니다:

  • .offcanvas-start는 오프캔버스를 뷰포트의 왼쪽에 배치합니다 (위의 예시로 확인)
  • .offcanvas-end는 오프캔버스를 뷰포트의 오른쪽에 배치합니다.
  • .offcanvas-top은 뷰포트의 맨 위에 오프캔버스를 배치합니다.
  • .offcanvas-bottom은 뷰포트의 맨 아래에 오프캔버스를 배치합니다.

위, 오른쪽, 아래에서 나오는 오프캔버스를 아래의 예시에서 확인해 보세요.

Offcanvas top
...
<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasTop" aria-controls="offcanvasTop">Toggle top offcanvas</button>

<div class="offcanvas offcanvas-top" tabindex="-1" id="offcanvasTop" aria-labelledby="offcanvasTopLabel">
  <div class="offcanvas-header">
    <h5 id="offcanvasTopLabel">Offcanvas top</h5>
    <button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
  </div>
  <div class="offcanvas-body">
    ...
  </div>
</div>
Offcanvas right
...
<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasRight" aria-controls="offcanvasRight">Toggle right offcanvas</button>

<div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasRight" aria-labelledby="offcanvasRightLabel">
  <div class="offcanvas-header">
    <h5 id="offcanvasRightLabel">Offcanvas right</h5>
    <button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
  </div>
  <div class="offcanvas-body">
    ...
  </div>
</div>
Offcanvas bottom
...
<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasBottom" aria-controls="offcanvasBottom">Toggle bottom offcanvas</button>

<div class="offcanvas offcanvas-bottom" tabindex="-1" id="offcanvasBottom" aria-labelledby="offcanvasBottomLabel">
  <div class="offcanvas-header">
    <h5 class="offcanvas-title" id="offcanvasBottomLabel">Offcanvas bottom</h5>
    <button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
  </div>
  <div class="offcanvas-body small">
    ...
  </div>
</div>

백드롭

오프캔버스와 그 배경이 표시될 때에는 <body> 요소의 스크롤은 비활성화됩니다. <body> 스크롤을 바꾸고 싶으면 data-bs-scroll 속성을, 배경의 스크롤을 바꾸고 싶으면 data-bs-backdrop 속성을 사용해 주세요.

Colored with scrolling

Try scrolling the rest of the page to see this option in action.

Offcanvas with backdrop

.....

Backdroped with scrolling

Try scrolling the rest of the page to see this option in action.

<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasScrolling" aria-controls="offcanvasScrolling">Enable body scrolling</button>
<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasWithBackdrop" aria-controls="offcanvasWithBackdrop">Enable backdrop (default)</button>
<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasWithBothOptions" aria-controls="offcanvasWithBothOptions">Enable both scrolling & backdrop</button>

<div class="offcanvas offcanvas-start" data-bs-scroll="true" data-bs-backdrop="false" tabindex="-1" id="offcanvasScrolling" aria-labelledby="offcanvasScrollingLabel">
  <div class="offcanvas-header">
    <h5 class="offcanvas-title" id="offcanvasScrollingLabel">Colored with scrolling</h5>
    <button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
  </div>
  <div class="offcanvas-body">
    <p>Try scrolling the rest of the page to see this option in action.</p>
  </div>
</div>
<div class="offcanvas offcanvas-start" tabindex="-1" id="offcanvasWithBackdrop" aria-labelledby="offcanvasWithBackdropLabel">
  <div class="offcanvas-header">
    <h5 class="offcanvas-title" id="offcanvasWithBackdropLabel">Offcanvas with backdrop</h5>
    <button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
  </div>
  <div class="offcanvas-body">
    <p>.....</p>
  </div>
</div>
<div class="offcanvas offcanvas-start" data-bs-scroll="true" tabindex="-1" id="offcanvasWithBothOptions" aria-labelledby="offcanvasWithBothOptionsLabel">
  <div class="offcanvas-header">
    <h5 class="offcanvas-title" id="offcanvasWithBothOptionsLabel">Backdroped with scrolling</h5>
    <button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
  </div>
  <div class="offcanvas-body">
    <p>Try scrolling the rest of the page to see this option in action.</p>
  </div>
</div>

접근성

개념적으로 오프캔버스 패널은 모달 dialog여서, 반드시 .offcanvasaria-labelledby="..."라는 오프캔버스의 타이틀을 참조하는 기술을 추가해 주세요. 덧붙여 role="dialog"는 이미 JavaScript로 추가되고 있기 때문에 따로 추가할 필요는 없습니다.

Sass

변수

$offcanvas-padding-y:               $modal-inner-padding;
$offcanvas-padding-x:               $modal-inner-padding;
$offcanvas-horizontal-width:        400px;
$offcanvas-vertical-height:         30vh;
$offcanvas-transition-duration:     .3s;
$offcanvas-border-color:            $modal-content-border-color;
$offcanvas-border-width:            $modal-content-border-width;
$offcanvas-title-line-height:       $modal-title-line-height;
$offcanvas-bg-color:                $modal-content-bg;
$offcanvas-color:                   $modal-content-color;
$offcanvas-box-shadow:              $modal-content-box-shadow-xs;
$offcanvas-backdrop-bg:             $modal-backdrop-bg;
$offcanvas-backdrop-opacity:        $modal-backdrop-opacity;

사용 방법

오프캔버스 플러그인에서는 몇 가지 클래스와 속성을 이용하여 힘든 처리를 합니다:

  • .offcanvas는 콘텐츠를 숨깁니다.
  • .offcanvas.show는 콘텐츠를 표시합니다.
  • .offcanvas-start는 왼쪽의 오프캔버스를 숨깁니다.
  • .offcanvas-end는 오른쪽의 오프캔버스를 숨깁니다.
  • .offcanvas-bottom은 아래쪽의 오프캔버스를 숨깁니다.

닫기 버튼에 data-bs-dismiss="offcanvas" 속성을 추가해 JavaScript 기능으로 감춥니다.

데이터 속성 사용하기

토글

요소에 data-bs-toggle="offcanvas"data-bs-target 또는 href를 추가하면 하나의 offcanvas 요소에 대한 제어가 자동으로 할당됩니다. data-bs-target 속성은 오프캔버스를 적용할 CSS 선택자를 허용합니다. offcanvas 요소에 offcanvas 클래스를 추가해야 합니다. 기본적으로 열리게 하려면 show 클래스를 추가하세요.

해제

해제는 아래와 같이 offcanvas 내에서 버튼의 data 속성을 사용하여 수행할 수 있습니다.

<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>

또는 아래와 같이 data-bs-target을 사용하여 offcanvas 외부의 버튼에서도 수행할 수 있습니다:

<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#my-offcanvas" aria-label="Close"></button>
모달을 해제하는 두 가지 방법을 모두 지원하지만 모달 외부에서 해제하는 것은 WAI-ARIA 모달 대화 디자인 패턴과 일치하지 않습니다. 문제가 생길 수도 있다는 점에 주의하세요.

JavaScript 사용하기

이처럼 수동으로 활성화 합니다:

var offcanvasElementList = [].slice.call(document.querySelectorAll('.offcanvas'))
var offcanvasList = offcanvasElementList.map(function (offcanvasEl) {
  return new bootstrap.Offcanvas(offcanvasEl)
})

옵션

data 속성 및 JavaScript로 옵션을 전달할 수 있습니다. data 속성의 경우, data-bs-backdrop=""처럼 data-bs-에 옵션명을 추가해 사용합니다.

Name Type Default Description
backdrop boolean true 오프캔버스가 열려 있는 동안, body에 배경을 적용합니다.
keyboard boolean true escape키가 눌려지면 오프캔버스를 닫습니다.
scroll boolean false 오프캔버스를 여는 동안 body 스크롤링을 허용합니다.

메소드

비동기 메서드 및 트렌지션

모든 API 메서드는 비동기이며 트렌지션을 시작합니다. 트렌지션은 시작되자마자 끝나기 전에 호출자에게 돌아갑니다. 또한 트렌지션 컴포넌트에 대한 메서드 호출은 무시됩니다.

자세한 내용은 JavaScript 문서를 참고하세요.

콘텐츠를 오프캔버스 요소로 액티브하게 합니다. 옵션의 object를 받습니다.

아래의 예시처럼 생성자를 사용해 오프캔버스의 인스턴스를 만들 수 있습니다:

var myOffcanvas = document.getElementById('myOffcanvas')
var bsOffcanvas = new bootstrap.Offcanvas(myOffcanvas)
Method Description
toggle 오프캔버스 요소의 표시 및 숨김을 바꿉니다. 실제로 표시 또는 숨김 되기 전의 오프캔버스 요소로 돌아갑니다 (즉, shown.bs.offcanvas 또는 hidden.bs.offcanvas 이벤트가 발생하기 전)
show 오프캔버스 요소를 표시합니다. 실제로 표시되기 전의 오프캔버스 요소로 돌아갑니다 (즉, shown.bs.offcanvas 이벤트가 발생하기 전).
hide 오프캔버스 요소를 숨깁니다. 실제로 숨겨지기전의 오픈캔버스 요소로 돌아갑니다. (즉, hidden.bs.offcanvas 이벤트가 발생하기 전).
getInstance DOM 요소와 연관된 오프캔버스 인스턴스를 얻기 위한 정적 메서드입니다.
getOrCreateInstance 정적 메서드를 사용하면 DOM 요소와 연결된 오프캔버스 인스턴스를 가져오거나 초기화되지 않은 경우 새 인스턴스를 만들 수 있습니다.

이벤트

Bootstrap의 오프캔버스 클래스는 오프캔버스 기능에 연결하기 위한 몇 가지 이벤트를 공개하고 있습니다.

Event type Description
show.bs.offcanvas 이 이벤트는 show 인스턴스 메서드가 호출되면 즉시 발생합니다.
shown.bs.offcanvas 이 이벤트는 오프캔버스 요소가 사용자에게 보일 때 발생합니다 (CSS 트랜지션이 완료될 때까지 기다립니다).
hide.bs.offcanvas 이 이벤트는 hide 메서드가 호출되면 즉시 발생합니다.
hidden.bs.offcanvas 이 이벤트는 오프캔버스 요소가 사용자로부터 없어졌을때 발생합니다 (CSS 트랜지션이 완료되기를 기다립니다).
var myOffcanvas = document.getElementById('myOffcanvas')
myOffcanvas.addEventListener('hidden.bs.offcanvas', function () {
  // do something...
})