Bootstrap 5 ile modal pencere açmak için sayfaya .modal sınıflı bir kapsayıcı, içine .modal-dialog ve .modal-content katmanlarını koyarsınız; bir butona data-bs-toggle="modal" ve data-bs-target="#kimlik" verdiğinizde Bootstrap JavaScript dosyası pencereyi sizin yerinize açar, arka plan karartmasını ekler, sayfa kaydırmasını kilitler ve Esc tuşuyla kapatmayı yönetir. Tek satır JavaScript yazmadan çalışan bir diyalog elde edersiniz; daha fazla denetim gerektiğinde new bootstrap.Modal() ile aynı pencereyi koddan yönetebilirsiniz.

Bu yazıda modalın zorunlu HTML iskeletini, kapanmayan (static) arka planı, uzun içerik için kaydırılabilir gövdeyi, dikey ortalamayı, boyut ve tam ekran sınıflarını, tetikleyen butona göre içerik değiştirmeyi, iki modal arasında geçişi ve JavaScript seçenekleri, yöntemleri ve olaylarını belgeye dayanarak anlatıyoruz. Yazı Bootstrap 5.0 belgelerine ve v5.0.2 kaynak koduna dayanır; daha yeni 5.x sürümleri ek özellikler getirmiş olabilir, kullandığınız sürüm için getbootstrap.com adresindeki güncel belgeye bakın. Bootstrap konularının tamamı için Bootstrap öğrenme rehberine göz atabilirsiniz.

Temel modal iskeleti ve canlı örnek

Bir modal üç katmandan oluşur. En dışta .modal kapsayıcısı, onun içinde genişliği ve kenar boşluğunu belirleyen .modal-dialog, en içte ise kenarlık, arka plan rengi ve köşe yuvarlaklığı taşıyan .modal-content bulunur. İçerik katmanını .modal-header, .modal-body ve isteğe bağlı .modal-footer parçalarına bölersiniz. Belge, iç boşluk (padding) gövdeden geldiği için .modal-body öğesini zorunlu sayar ve kullanıcıya her zaman açık bir kapatma yolu sunmanızı ister; başlıktaki kapatma butonu bunun en yaygın biçimidir.

Aşağıdaki örnekte buton, data-bs-target ile modalın id değerini gösterir. Modal kapsayıcısındaki .fade sınıfı açılış animasyonunu sağlar, tabindex="-1" pencerenin odak alabilmesine yarar, aria-labelledby ise ekran okuyuculara pencere başlığını bildirir. Kapatma işini data-bs-dismiss="modal" özniteliğini taşıyan her buton görür:

html
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#ornekModal">
  Modalı aç
</button>

<div class="modal fade" id="ornekModal" tabindex="-1" aria-labelledby="ornekModalBaslik" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="ornekModalBaslik">Siparişi onayla</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Kapat"></button>
      </div>
      <div class="modal-body">
        <p>Sepetinizdeki 3 ürün için siparişi onaylıyor musunuz?</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Vazgeç</button>
        <button type="button" class="btn btn-primary">Onayla</button>
      </div>
    </div>
  </div>
</div>

Butona tıklandığında Bootstrap modalı gösterir, arkasına .modal-backdrop sınıflı yarı saydam bir katman ekler ve bu katmana tıklanınca pencereyi kapatır. Derlenmiş CSS dosyasında arka plan katmanı siyah renkte ve .show durumunda 0.5 opaklıkla tanımlıdır. Pencere kapandığında, onu açan buton hâlâ görünürse odak bu butona geri verilir; bu davranış Bootstrap v5.0.2 kaynak kodu: modal.js dosyasındaki tıklama işleyicisinde yer alır ve klavye kullanıcılarının sayfada kaybolmasını önler.

Erişilebilirlik için belge, .modal öğesine başlığı gösteren aria-labelledby eklemenizi ve isterseniz pencerenin açıklamasını aria-describedby ile vermenizi önerir. role="dialog" eklemeniz gerekmez; kaynak kod, pencere gösterilirken role="dialog" ve aria-modal özniteliklerini kendisi ekler, kapanırken kaldırır ve yerine aria-hidden koyar. ARIA rollerinin genel anlamı için ARIA rol ve öznitelikleri yazısına bakabilirsiniz.

Static backdrop: dışarı tıklayınca kapanmayan modal

Varsayılan davranışta karartılmış arka plana tıklamak veya Esc tuşuna basmak modalı kapatır. Kullanıcının bir seçim yapmadan pencereden çıkmasını istemediğiniz durumlarda, örneğin bir sözleşme onayında, data-bs-backdrop="static" verirsiniz. Esc tuşunu da devre dışı bırakmak için yanına data-bs-keyboard="false" eklenir. Belgedeki örnek bu iki özniteliği birlikte kullanır:

html
<div class="modal fade" id="onayModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="onayModalBaslik" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="onayModalBaslik">Kullanım koşulları</h5>
      </div>
      <div class="modal-body">
        <p>Devam etmek için koşulları kabul etmeniz gerekiyor.</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Reddet</button>
        <button type="button" class="btn btn-primary" data-bs-dismiss="modal">Kabul ediyorum</button>
      </div>
    </div>
  </div>
</div>

Static modda kullanıcı dışarı tıkladığında ya da klavye seçeneği kapalıyken Esc tuşuna bastığında pencere kapanmaz; bunun yerine hidePrevented.bs.modal olayı tetiklenir. Kaynak kod bu sırada modala kısa süreliğine modal-static sınıfını ekler; derlenmiş CSS bu sınıf varken diyaloğu scale(1.02) ile hafifçe büyütür, böylece kullanıcı pencerenin kapanmadığını görsel olarak fark eder. Static bir modalda mutlaka bir kapatma ya da karar butonu bulundurun, aksi hâlde kullanıcı pencereden çıkamaz.

Uzun içerik, kaydırılabilir gövde ve dikey ortalama

Modalın içeriği ekran yüksekliğini aştığında pencere sayfadan bağımsız olarak kendi içinde kayar; bu, .modal öğesinin overflow-y: auto kuralından gelir ve bütün pencere (başlık ve alt bilgi dahil) birlikte kayar. Başlığın ve alt bilginin sabit kalıp yalnızca gövdenin kaymasını istiyorsanız .modal-dialog öğesine .modal-dialog-scrollable sınıfını eklersiniz. Derlenmiş CSS bu sınıfla diyaloğa ekran yüksekliğinden kenar payı düşülmüş bir yükseklik verir ve .modal-body için overflow-y: auto tanımlar.

Pencerenin ekranın üst kısmında değil dikey olarak ortada durması için .modal-dialog-centered kullanılır. Bu sınıf diyaloğu flex kapsayıcıya çevirir ve align-items: center ile içeriği ortalar. İki sınıf birlikte de kullanılabilir:

html
<!-- Dikey ortalanmış modal -->
<div class="modal-dialog modal-dialog-centered">
  <div class="modal-content">...</div>
</div>

<!-- Dikey ortalanmış ve gövdesi kaydırılabilir modal -->
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
  <div class="modal-content">...</div>
</div>

Modal açıkken içeriğin yüksekliği değişirse, örneğin bir bölüm genişletildiğinde ya da sonradan veri yüklendiğinde, belge myModal.handleUpdate() çağırmanızı söyler. Bu yöntem bir kaydırma çubuğu ortaya çıktığında pencerenin konumunu yeniden ayarlar.

Modal gövdesinde ızgara kullanmak da mümkündür. Belge, .modal-body içine bir .container-fluid yerleştirip ardından normal .row ve .col-* sınıflarını kullanmanızı önerir. Izgara sisteminin kendisi için Bootstrap grid sistemi yazısına bakabilirsiniz.

Tetikleyen butona göre modal içeriğini değiştirmek

Aynı modalı açan birden fazla buton olduğunda içeriği her seferinde baştan yazmanıza gerek yoktur. show.bs.modal olayının nesnesinde relatedTarget özelliği bulunur ve pencere bir tıklamayla açıldıysa bu özellik tıklanan öğeyi verir. Butonlara kendi data-bs-* özniteliğinizi koyup olay içinde okuyarak başlığı ya da form alanlarını güncellersiniz. Belgedeki örneği uyarladık:

html
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#mesajModal" data-bs-alici="Ayşe">Ayşe'ye yaz</button>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#mesajModal" data-bs-alici="Mehmet">Mehmet'e yaz</button>

<div class="modal fade" id="mesajModal" tabindex="-1" aria-labelledby="mesajModalBaslik" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="mesajModalBaslik">Yeni mesaj</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Kapat"></button>
      </div>
      <div class="modal-body">
        <form>
          <div class="mb-3">
            <label for="alici-adi" class="col-form-label">Alıcı:</label>
            <input type="text" class="form-control" id="alici-adi">
          </div>
          <div class="mb-3">
            <label for="mesaj-metni" class="col-form-label">Mesaj:</label>
            <textarea class="form-control" id="mesaj-metni"></textarea>
          </div>
        </form>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Kapat</button>
        <button type="button" class="btn btn-primary">Gönder</button>
      </div>
    </div>
  </div>
</div>
javascript
var mesajModal = document.getElementById('mesajModal')
mesajModal.addEventListener('show.bs.modal', function (event) {
  // Modali acan buton
  var button = event.relatedTarget
  var alici = button.getAttribute('data-bs-alici')

  mesajModal.querySelector('.modal-title').textContent = alici + ' icin yeni mesaj'
  mesajModal.querySelector('.modal-body input').value = alici
})

Burada data-bs-alici Bootstrap’in tanıdığı bir seçenek değildir; yalnızca sizin okuduğunuz bir veri özniteliğidir. Belge bu noktada gerekirse olayın içinde sunucuya bir istek yapıp içeriği yanıt geldikten sonra güncelleyebileceğinizi de belirtir. Modalı JavaScript ile açarken de relatedTarget verebilirsiniz: myModal.show(butonOgesi) çağrısında verdiğiniz öğe olay nesnesinde aynı özellikle görünür. Form alanlarının stilleri için Bootstrap form-control yazısına bakabilirsiniz.

İki modal arasında geçiş

Aynı anda iki modal açık tutamazsınız, fakat birinden diğerine geçebilirsiniz. Örneğin giriş penceresinden “şifremi unuttum” penceresine geçmek için ilk modalın içindeki butona hem data-bs-toggle="modal" ile ikinci pencerenin hedefini hem de data-bs-dismiss="modal" verirsiniz. Belge bu yöntemin yalnızca iki ayrı modal arasında geçiş yaptığını, ikisini birlikte açmadığını özellikle vurgular:

html
<div class="modal fade" id="girisModal" aria-hidden="true" aria-labelledby="girisModalBaslik" tabindex="-1">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="girisModalBaslik">Giriş yap</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Kapat"></button>
      </div>
      <div class="modal-body">Giriş formu burada yer alır.</div>
      <div class="modal-footer">
        <button class="btn btn-link" data-bs-target="#sifreModal" data-bs-toggle="modal" data-bs-dismiss="modal">Şifremi unuttum</button>
      </div>
    </div>
  </div>
</div>
<div class="modal fade" id="sifreModal" aria-hidden="true" aria-labelledby="sifreModalBaslik" tabindex="-1">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="sifreModalBaslik">Şifre sıfırlama</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Kapat"></button>
      </div>
      <div class="modal-body">E-posta adresinizi girin.</div>
      <div class="modal-footer">
        <button class="btn btn-primary" data-bs-target="#girisModal" data-bs-toggle="modal" data-bs-dismiss="modal">Girişe dön</button>
      </div>
    </div>
  </div>
</div>
<a class="btn btn-primary" data-bs-toggle="modal" href="#girisModal" role="button">Giriş penceresini aç</a>

Son satırdaki bağlantı, hedefi data-bs-target yerine href="#girisModal" ile verir; belge iki yöntemi de kabul eder. Bağlantı ile tetiklendiğinde Bootstrap varsayılan bağlantı davranışını engeller, böylece adres çubuğuna #girisModal eklenmez ve sayfa zıplamaz.

JavaScript ile modal: seçenekler, yöntemler ve olaylar

JavaScript ile modal: seçenekler, yöntemler ve olaylar: backdrop, keyboard, focus

Veri öznitelikleri yeterli olmadığında modalı kodla oluşturursunuz. Yapıcı, birinci argüman olarak modal öğesini, ikinci argüman olarak isteğe bağlı bir seçenek nesnesini alır. Seçenekleri veri özniteliğiyle de verebilirsiniz; seçenek adının başına data-bs- eklenir, data-bs-backdrop gibi. Kaynak koddaki Default nesnesi ve belge aynı üç seçeneği listeler:

SeçenekTürVarsayılanNe yapar
backdropboolean veya statictrueArka plan katmanını ekler; static verilirse dışarı tıklamak modalı kapatmaz
keyboardbooleantrueEsc tuşuna basıldığında modalı kapatır
focusbooleantrueBaşlatıldığında odağı modala taşır
javascript
var myModal = new bootstrap.Modal(document.getElementById('myModal'), {
  keyboard: false
})

myModal.show()
myModal.hide()
myModal.toggle()
myModal.handleUpdate()
myModal.dispose()

// Ogeye bagli ornegi almak
var modal = bootstrap.Modal.getInstance(document.getElementById('myModal'))
// Yoksa olusturarak almak
var modal2 = bootstrap.Modal.getOrCreateInstance(document.querySelector('#myModal'))

show(), hide() ve toggle() yöntemleri eşzamansızdır: geçiş başlar başlamaz çağırana döner, animasyonun bitmesini beklemez. Ayrıca geçiş sürerken yapılan yeni bir çağrı yok sayılır; kaynak kodda show(), pencere zaten açıksa ya da bir geçiş sürüyorsa hiçbir şey yapmadan döner. Animasyon bittikten sonra bir iş yapmanız gerekiyorsa ilgili olayı dinlersiniz. dispose() öğe üzerinde saklanan örnek verisini siler; getInstance() öğeye bağlı örneği verir, getOrCreateInstance() ise örnek yoksa yenisini oluşturur.

Modal olaylarının tamamı .modal öğesinin kendisinde tetiklenir:

OlayNe zaman tetiklenir
show.bs.modalshow yöntemi çağrılır çağrılmaz; tıklamayla açıldıysa relatedTarget tıklanan öğedir
shown.bs.modalModal görünür olduğunda, CSS geçişleri bittikten sonra
hide.bs.modalhide yöntemi çağrılır çağrılmaz
hidden.bs.modalModal tamamen gizlendiğinde, geçişler bittikten sonra
hidePrevented.bs.modalArka plan static iken dışarı tıklandığında veya klavye kapalıyken Esc basıldığında

“show” ve “hide” gibi mastar biçimli olaylar preventDefault() desteği sunar. Örneğin form kaydedilmemişse hide.bs.modal içinde event.preventDefault() çağırarak pencerenin kapanmasını durdurabilirsiniz. Olay modelinin, getOrCreateInstance ve Default nesnesinin bütün bileşenlerde ortak çalışması Bootstrap JavaScript API yazısında anlatılır.

javascript
var formModal = document.getElementById('formModal')
formModal.addEventListener('hide.bs.modal', function (event) {
  if (formModal.querySelector('form').dataset.degisti === 'evet') {
    event.preventDefault() // kaydedilmemis degisiklik varken kapatma
  }
})

Sık yapılan hatalar

  • JavaScript dosyasını eklememek: Modal yalnızca CSS ile açılmaz. Sayfada bootstrap.bundle.min.js ya da bootstrap.min.js yüklü olmalıdır. Kurulum için CDN kurulum yazısına bakın.
  • v4 öznitelikleri: Bootstrap 4 kodundan kalan data-toggle="modal" ve data-target v5’te çalışmaz; doğru adlar data-bs-toggle ve data-bs-target’tır. Değişikliklerin listesi Bootstrap 4’ten 5’e geçiş yazısında yer alır.
  • Hedef ile kimliğin uyuşmaması: data-bs-target="#ornekModal" değeri modalın id değeriyle birebir aynı olmalı ve başında # bulunmalıdır.
  • Modalı sabit konumlu bir öğenin içine koymak: Sabit bir menü ya da kenar çubuğunun içine yerleştirilen modal üstte görünmeyebilir. Modalı belgenin üst düzeyine taşıyın.
  • İkinci modalı birincinin üstünde açmaya çalışmak: Bootstrap iç içe modal desteklemez. Geçiş gerekiyorsa yukarıdaki toggle yöntemini kullanın.
  • Aynı butona iki bileşen bağlamak: Belge bir öğede yalnızca tek bir veri özniteliği takımı kullanmanızı söyler; aynı butondan hem tooltip hem modal tetiklenemez. Tooltip için butonu bir kapsayıcıya sarın.
  • Geçiş bitmeden ikinci çağrı yapmak: hide() çağrısından hemen sonra show() çağırmak yok sayılabilir. Sıralı işlemleri hidden.bs.modal olayına bağlayın.

Bootstrap’in çalışmadığı genel durumların listesi için Bootstrap çalışmıyor yazısına de bakabilirsiniz.

Sık Sorulan Sorular

Bootstrap modalı jQuery olmadan açılır mı?

Evet. Bootstrap 5 jQuery bağımlılığını kaldırmıştır; modal veri öznitelikleriyle ya da new bootstrap.Modal() ile saf JavaScript üzerinden çalışır. Sayfada jQuery bulunursa Bootstrap bileşenleri ayrıca jQuery eklentisi olarak da kaydeder.

Modal dışına tıklayınca kapanmasını nasıl engellerim?

.modal öğesine data-bs-backdrop="static" verin ya da JavaScript ile backdrop: 'static' seçeneğini kullanın. Esc tuşunu da kapatmak için data-bs-keyboard="false" ekleyin.

Modalı sayfa yüklenince otomatik nasıl açarım?

Bunun için ayrı bir veri özniteliği yoktur. Sayfa yüklendikten sonra new bootstrap.Modal(document.getElementById('kimlik')).show() çağırmanız yeterlidir.

Modal içindeki inputa otomatik odak nasıl verilir?

autofocus modal içinde etkili olmaz. shown.bs.modal olayını dinleyip alanın focus() yöntemini çağırın.

Modal genişliğini nasıl ayarlarım?

.modal-dialog öğesine .modal-sm, .modal-lg veya .modal-xl ekleyin; tam ekran için .modal-fullscreen ya da kırılma noktalı -down sürümlerini kullanın. Farklı bir genişlik gerekiyorsa Sass değişkenlerini değiştirebilirsiniz.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: Bootstrap öğrenme rehberi · Bootstrap JavaScript API · Offcanvas yan menü · Toast bildirimleri · Tooltip ve popover · JavaScript öğrenme rehberi