popover global özniteliği, herhangi bir HTML öğesini popover yani açılır katman hâline getirir. Kısa cevap şudur: açılacak öğeye popover ve bir id verirsiniz, açacak düğmeye de popovertarget özniteliğiyle bu kimliği yazarsınız. Hiç JavaScript yazmadan düğme katmanı açar, ikinci basışta kapatır; dışarı tıklamak ya da Esc tuşuna basmak da katmanı kapatır.

Bu yazıda auto, manual ve hint değerlerinin farkını, popovertargetaction ile göster/gizle/aç-kapat seçimini, command öznitelikleriyle aynı işi yapmayı, iç içe popoverları ve tarayıcının otomatik kurduğu erişilebilirlik ilişkilerini anlatıyoruz. Modal pencere gerekiyorsa dialog etiketi daha uygun olabilir; ikisinin farkını yazının sonunda bir tabloda topladık.

En basit popover örneği

html
<button popovertarget="duyuru">Duyuruyu göster</button>

<div id="duyuru" popover>Bakım çalışması bu gece 02.00 ile 04.00 arasında yapılacak.</div>

Bu kodda <div>, popover özniteliği nedeniyle başlangıçta display: none ile gizlidir. Düğmeye basıldığında katman açılır. Açık popover tarayıcının "top layer" adı verilen en üst katmanında, diğer tüm öğelerin üstünde gösterilir; bu yüzden üst öğelerin position ya da overflow ayarlarından etkilenmez. Bir kapsayıcının taşan kısmı kesilse bile popover kesilmez.

Popover açmanın iki yolu vardır: popovertarget taşıyan bir <button> ya da <input type="button"> öğesi, veya JavaScript ile showPopover() çağrısı. popover bir global öznitelik olduğu için <div>, <section>, <dialog> ya da başka bir öğeye eklenebilir; ama öğeyi seçerken içeriğin anlamına uygun etiketi kullanmak yine önemlidir.

popover değerleri: auto, manual ve hint

popover değerleri: auto, manual ve hint: auto (varsayılan), manual, hint

Öznitelik üç değerden birini alır. Değersiz yazmak (popover) ya da boş değer vermek (popover=""), popover="auto" ile aynıdır.

DeğerLight dismissDiğer popoverlara etkisiTipik kullanım
auto (varsayılan)Var: dışarı tıklama, EscAçılınca diğer auto popoverları kapatır (iç içe olanlar hariç)Menü, açılır panel
manualYokHiçbirini kapatmaz, birden çok manual aynı anda açık kalabilirBildirim, sürekli görünmesi gereken panel
hintVar, kapatma isteklerine yanıt verirauto popoverları kapatmaz; atası olmayan diğer hint popoverları kapatırÜzerine gelince ya da odakta çıkan ipucu

auto popoverlarda genel kural ekranda aynı anda tek bir auto popover bulunmasıdır: ikinciyi açmak ilkini gizler. İstisna iç içe popoverlardır; bir popover başka bir popoverın içinden açılırsa üstteki kapanmaz. manual popoverlar ise yalnızca açıkça gösterilip gizlenir; bunun için ya göster/gizle/aç-kapat düğmeleri ya da JavaScript gerekir. Bu sayede birden fazla bağımsız manual popoverı aynı anda ekranda tutabilirsiniz. hint değeri daha yenidir; Tarayıcı desteği için MDN uyumluluk tablosuna bakın.

Light dismiss ne demek?

"Light dismiss", kullanıcının katmanı ayrı bir kapat düğmesine basmadan, hafif bir hareketle kapatabilmesidir. auto popover için bu hareketler katmanın dışına tıklamak, başka bir popover açmak ve masaüstünde Esc gibi tarayıcıya özgü mekanizmalardır. Menü ve açılır listelerde kullanıcı bu davranışa alışkındır. Ancak kullanıcının yanlışlıkla kapatmasını istemediğiniz içerikte, örneğin uzun bir form panelinde, manual daha güvenlidir.

Aynı kavram dialog öğesinde closedby="any" değeriyle de karşınıza çıkar; MDN bu değerin auto popoverların light dismiss davranışına eşdeğer olduğunu belirtir.

popovertarget ve popovertargetaction

popovertarget bir <button> ya da <input type="button"> öğesini popover denetim düğmesine çevirir ve değer olarak denetlenecek popoverın kimliğini alır. popovertargetaction ise düğmenin ne yapacağını seçer:

  • toggle: katman gizliyse gösterir, açıksa gizler. Öznitelik yazılmazsa varsayılan budur.
  • show: gizli katmanı gösterir; katman zaten açıksa hiçbir şey yapmaz.
  • hide: açık katmanı gizler; zaten gizliyse hiçbir şey yapmaz.
html
<button popovertarget="filtre" popovertargetaction="show">Filtreleri aç</button>

<section id="filtre" popover="manual" aria-labelledby="filtre-baslik">
  <h2 id="filtre-baslik">Filtreler</h2>
  <label><input type="checkbox" name="stok"> Yalnızca stokta olanlar</label>
  <input type="button" value="Kapat" popovertarget="filtre" popovertargetaction="hide">
</section>

Bu örnekte panel manual olduğu için dışarı tıklamak onu kapatmaz; kullanıcı panelde rahatça seçim yapabilir ve işi bitince "Kapat" düğmesine basar. Kapatma düğmesinin <input type="button"> olması, aynı özniteliklerin bu tür için de geçerli olduğunu gösterir. Onay kutularının ayrıntıları checkbox ve radio yazısında.

Tarayıcının otomatik kurduğu ilişkiler

Tarayıcının otomatik kurduğu ilişkiler

popovertarget ile düğme ve popover arasında ilişki kurmanın, yalnızca açıp kapatmanın ötesinde iki yararı vardır. Birincisi, tarayıcı popover ile onu açan düğme arasında örtük bir aria-details ve aria-expanded ilişkisi kurar ve popover açıldığında onu klavye odak sırasında mantıklı bir konuma yerleştirir. Böylece ekran okuyucu kullanıcıları düğmenin bir şeyi açtığını ve şu anda açık olup olmadığını öğrenir; klavye kullanıcıları da düğmeden sonra Tab ile katmanın içine geçebilir.

İkincisi, tarayıcı iki öğe arasında örtük bir çapa (anchor) bağlantısı oluşturur. Bu bağlantı popoverı düğmenin yanına konumlandırmayı CSS anchor positioning ile kolaylaştırır; konumlandırma ayrıntısı CSS konusudur. Bu iki yarar, düğme ile katman arasındaki bağı HTML içinde açıkça yazmanın somut karşılığıdır.

command ve commandfor ile popover denetimi

button öğesinin commandfor özniteliği, popovertarget özniteliğinin daha genel bir sürümüdür. Popoverlar için üç komut değeri vardır: show-popover (popovertargetaction="show" ve showPopover() karşılığı), hide-popover (hide ve hidePopover() karşılığı) ve toggle-popover (toggle ve togglePopover() karşılığı). Tarayıcı desteği için MDN uyumluluk tablosuna bakın.

html
<button commandfor="yardim" command="toggle-popover">Yardım</button>

<aside id="yardim" popover>
  <p>Şifreniz en az 12 karakter olmalıdır.</p>
  <button commandfor="yardim" command="hide-popover">Tamam</button>
</aside>

Bir sayfada iki yaklaşımı karıştırmak teknik olarak sorun değildir, ama tutarlılık için birini seçmek bakımı kolaylaştırır. command yaklaşımının avantajı, aynı öznitelik çiftiyle hem pencereleri (show-modal, close) hem popoverları denetleyebilmenizdir.

Adım adım örnek: hesap menüsü

Şimdi öğrendiklerimizi tek bir küçük bileşende birleştirelim. Amaç, sayfanın üst kısmındaki "Hesabım" düğmesine basınca birkaç bağlantı içeren bir menünün açılması, menü dışına tıklayınca ya da Esc ile kapanması ve klavyeyle rahatça kullanılabilmesidir.

html
<header>
  <nav aria-label="Hesap">
    <button popovertarget="hesap-menu">Hesabım</button>
    <div id="hesap-menu" popover>
      <ul>
        <li><a href="#siparisler">Siparişlerim</a></li>
        <li><a href="#adresler">Adreslerim</a></li>
        <li><a href="#cikis">Çıkış yap</a></li>
      </ul>
    </div>
  </nav>
</header>

Adımları sırayla düşünelim. Birinci adımda menü kapsayıcısına değersiz popover yazdık; bu auto anlamına gelir ve light dismiss davranışını açar. İkinci adımda düğmeye popovertarget="hesap-menu" verdik; popovertargetaction yazmadığımız için düğme varsayılan olarak aç-kapat (toggle) işlevi görür. Üçüncü adımda tarayıcı, düğme ile menü arasında aria-expanded ilişkisini kendisi kurar; ekran okuyucu kullanıcısı menünün açık ya da kapalı olduğunu düğme üzerinden öğrenir. Dördüncü adımda menü açıldığında odak sırasına mantıklı bir yerde eklenir; kullanıcı düğmeden sonra Tab tuşuyla bağlantılara geçebilir.

Menüyü kullanırken başka bir auto popover açılırsa, örneğin sayfadaki bir dil seçici, bu menü kendiliğinden kapanır; iki açılır menünün üst üste binmesi böylece önlenir. Bağlantılar <nav> içinde olduğu için sayfanın gezinme bölgesi olarak da tanınır; bu konu semantik etiketler yazısında anlatılıyor. Menünün düğmenin hemen altında görünmesi ise CSS ile ayarlanır.

manual popover ile birden fazla bildirim

manual popoverlar birbirini kapatmadığı için, aynı anda ekranda kalması gereken iki bağımsız bilgi kutusu için uygundur. Aşağıdaki örnekte iki ayrı düğme iki ayrı katmanı açar; biri açıkken diğerini açmak ilkini kapatmaz. Her katmanın kendi kapatma düğmesi vardır, çünkü light dismiss yoktur.

html
<button popovertarget="kargo">Kargo durumu</button>
<button popovertarget="fatura">Fatura durumu</button>

<div id="kargo" popover="manual">
  <p>Paketiniz dağıtıma çıktı.</p>
  <button popovertarget="kargo" popovertargetaction="hide">Kapat</button>
</div>

<div id="fatura" popover="manual">
  <p>Faturanız e-posta adresinize gönderildi.</p>
  <button popovertarget="fatura" popovertargetaction="hide">Kapat</button>
</div>

İç içe popoverlar ve hint

MDN örneğinde bir menü popover="auto" ile açılır ve her menü maddesinin yanındaki bilgi düğmesi popover="hint" taşıyan ayrı bir katman açar. hint katmanı açılınca ana menü kapanmaz, ama açık olan diğer bilgi katmanı kapanır. Aşağıda aynı yapının kısaltılmış bir Türkçe uyarlaması var:

html
<button popovertarget="menu">Menüyü aç</button>

<div id="menu" popover="auto">
  <ul>
    <li><a href="#yeni-belge">Yeni belge</a> <button popovertarget="yeni-bilgi" aria-label="Yeni belge hakkında">?</button></li>
    <li><a href="#belge-ac">Belge aç</a> <button popovertarget="ac-bilgi" aria-label="Belge açma hakkında">?</button></li>
  </ul>
</div>

<div id="yeni-bilgi" popover="hint">Boş bir belge oluşturur.</div>
<div id="ac-bilgi" popover="hint">Kayıtlı bir belgeyi açar.</div>

MDN, hint popoverların genellikle tıklamayla değil, mouseover/mouseout ve focus/blur gibi olaylara bağlı JavaScript ile gösterilip gizlendiğini belirtir; bir düğmeye tıklayarak hint açmak, açık bir auto popoverın light dismiss ile kapanmasına yol açabilir. Yukarıdaki örnekte bilgi düğmeleri menünün içinde olduğu için menü açık kalır. Simge düğmelerine aria-label vermemizin nedeni, yalnızca "?" içeren bir düğmenin anlamlı bir erişilebilir ada sahip olmamasıdır; bkz. erişilebilir ad.

Üzerine gelince açılan katmanlar için <button> öğesinde interestfor özniteliği de tanımlıdır: değeri hedef öğenin kimliğidir ve hedef, kullanıcı düğmeye ilgi gösterdiğinde (üzerine gelme ya da odaklanma) gösterilir, ilgi kaybolunca gizlenir. Tarayıcı desteği için MDN uyumluluk tablosuna bakın.

JavaScript ile popover

Bildirimsel öznitelikler yetmediğinde HTMLElement yöntemleri kullanılır: showPopover(), hidePopover() ve togglePopover(). Örneğin bir kayıt işlemi bitince bildirim katmanını açmak için:

javascript
const bildirim = document.getElementById("kargo");
bildirim.showPopover();

Popover içindeki bir öğeye autofocus verirseniz, MDN tanımına göre odak sayfa yüklenirken değil, popover gösterildiğinde o öğeye gider. Bir popover içinde bu özniteliği yalnızca bir öğe taşımalıdır. Açık katmanı CSS tarafında seçmek için :popover-open sözde sınıfı, arka planı için ::backdrop kullanılır.

popover ile dialog arasındaki fark

popover ile dialog arasındaki fark: Sayfanın geri kalanı, Dışarı tıklayınca, Esc tuşu, Örtük ARIA bilgisi
Özellikpopover (auto)dialog + showModal()
Sayfanın geri kalanıKullanılabilir kalırInert olur, etkileşim engellenir
Dışarı tıklayıncaKapanırVarsayılan olarak kapanmaz (closedby="any" ile kapanır)
Esc tuşuKapatırKapatır
Örtük ARIA bilgisiDüğme ile aria-details ve aria-expanded ilişkisidialog rolü, aria-modal="true"
Gösterildiği yerTop layerTop layer

Kural basittir: kullanıcının devam etmeden önce bir şeye yanıt vermesi gerekiyorsa modal <dialog> kullanın. Kullanıcı sayfada gezinmeye devam ederken yanında duran bir menü, ipucu ya da panel gerekiyorsa popover yeterlidir. Modal olmayan bir pencere için ikisini birleştirip <dialog popover> yazmak da mümkündür.

Sık yapılan hatalar

  • popovertarget özniteliğini <a> ya da <div> öğesine yazmak. Öznitelik yalnızca <button> ve <input type="button"> üzerinde tanımlıdır.
  • Popovera id vermemek ya da popovertarget değerine #menu gibi bir seçici yazmak. Değer düz kimliktir.
  • manual popovera kapatma düğmesi koymamak. Light dismiss olmadığı için kullanıcı katmanı kapatamaz.
  • Aynı anda iki auto popoverın açık kalmasını beklemek. İç içe değillerse ikincisi ilkini kapatır; bunun için manual kullanın.
  • Popover açılınca arka planın kilitleneceğini sanmak. Popover modal değildir; engelleme için modal dialog gerekir.
  • Yalnızca simge içeren açma düğmelerine erişilebilir ad vermemek.

Sık Sorulan Sorular

popover için JavaScript gerekir mi?

Hayır. popover ve popovertarget öznitelikleri açma, kapatma ve light dismiss davranışını tek başına sağlar. JavaScript yalnızca katmanı bir olaydan sonra açmak gibi özel durumlarda gerekir.

popover ile title özniteliği aynı şey mi?

Hayır. title özniteliği tarayıcının kendi küçük ipucunu gösterir ve içine HTML yazılamaz. Popover ise düğme, bağlantı, liste gibi her türlü içeriği taşıyabilen gerçek bir öğedir.

Gizli popover ekran okuyucuda okunur mu?

Kapalı popover display: none ile gizlenir. MDN: aria-hidden sayfasına göre display: none ile gizlenen içerik erişilebilirlik ağacından da çıkar; bu yüzden kapalı katmana ayrıca aria-hidden eklemeniz gerekmez.

Popover açılınca odak nereye gider?

popovertarget ile açılan popover, MDN'ye göre klavye odak sırasında mantıklı bir konuma yerleştirilir; kullanıcı açma düğmesinden sonra Tab ile katmanın içine geçebilir. Odağın doğrudan katmandaki belirli bir öğeye gitmesini istiyorsanız o öğeye autofocus verin; öznitelik popover gösterildiğinde uygulanır.

hint değerini kullanmalı mıyım?

hint özellikle üzerine gelince ya da odakta açılan ipuçları için düşünülmüştür ve görece yeni bir değerdir. Tarayıcı desteği için MDN uyumluluk tablosuna bakın. Desteklenmeyen tarayıcılarda geçersiz değerlerin nasıl ele alınacağını kendi testlerinizle doğrulayın.

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: HTML öğrenme rehberi · dialog etiketi · button etiketi · details ve summary · erişilebilir ad · yeni HTML özellikleri