Bu sene Safari’nin arayı kapatmak için yaptığı atılımı yazmakla geçecek herhalde. Daha önce diğer popüler tarayıcılarda var olan ancak Safari’nin geri kalması nedeniyle uygulamalarda tercih etmediğimiz özellikleri artık Safari’nin desteğiyle hayata geçirmeye başlayabiliriz.

Bu özelliklerden birisi overscroll-behavior özelliğidir. Artık Safari desteği geldiğine göre rahat rahat kullanabiliriz.

overscroll-behavior özelliği bir scroll alanının sınırına ulaştıktan sonra nasıl hareket etmesi gerektiğini belirlediğimiz CSS özelliğidir. Scroll bitti üst elemanın scrollundan devam et veya scroll bitti üst elemanın scrolluna dokunma.

Örneklerden anlamak daha kolay.

Soldaki örnek normal davranışı gösterir. Soldaki örneği scroll yapıp içeriğin sonuna geldikten sonra hala scroll yapmaya devam edersek üst eleman (body) scrollundan devam eder. Sağdaki örnekte ise, içeriğin sonuna geldiğimizde faremiz içeriğin üzerinde olduğu müddetçe üst elemanın scrolluna dokunmayacaktır.

Bu özelliği ilk duyduğumda çok sevinmiştim. Tam da ihtiyacım olan bir zamanda görmüştüm çünkü. Önceki şirketimde sayfanın sağ alt köşesinde bir sohbet alanı olacak ve kullanıclar buradan birbirleriyle mesajlaşacak diye bir işimiz vardı. Ancak şöyle bir sorunumuz oluşmuştu: Başlangıçta biz mesajlaşma alanının en altına atıyorduk ve kullanıcı scroll edince üst elemanın scroll ediyordu ve bu kullanıcının odağını bozuyordu. Bundan kurtulamak isterken bunu tek satır CSS ile yapabileceğimi öğrenmek beni sevindirecektik ki Safari desteğinin olmaması üzdü. Biz o zaman bu işi javascript ile halletmiştik.

Diğer bir yaşadığım sorunda açılan modal içindeki scroll bitince alttaki içeriğin scroll etmeye devam etmesi sorunuydu. Aradan çok zaman geçtiği için o zaman nasıl çözdüğümüzü hatırlayamadım ama Safari’ye çok kızdığımı hatırlıyorum.

Safari desteği sonrası tarayıcı destek oranı 95%’lere ulaşacaktır.

Kalın sağlıcakla.

Kaynaklar

Bu konuya ilgim ilk olarak “responsive mi? adaptive mi?” konusunu tartışırken geldi. Bir menümüz var ve bunu responsive yaparsak menüyü masaüstünde hover ile mobilde ise tıklama ile çözmemiz lazım ve bu ayrımı yakalamak için javascript kullanmalıyız diye bir negatif yönünden bahsedildi. (Negatiflik, javascript kaynaklarını geç yüklenmesi ve bundan ötürü ilk açılırken menünün aktifleşmesinin gecikmesi) Yeni gelen medya sorgularıyla bunu CSS ile yapmanın mümkün olacağını söyledim.

Daha sonra bunu nasıl yaparım diye bir örnek yapmaya karar verdim. Örnek ve yazı böylece çıktı.

Medya sorgularının 4. seviyesiyle birlikte hover, any-hover, pointer ve any-pointer tanımları geldi. Biz bu tanımları kullanarak örneğimizi yapacağız.

Burada normal responsive kodlamadan farklı olarak fare ile tıklama yapanların kodu ile dokunmatik araçlardaki kodlar ayrı birer medya bloku içinde yazmamız gerekiyor. Bunun sebebi birisi için yazdığımız kodun diğerini etkilemesini engellemek.

Kodumuzu iki bölüme ayıracağız;

Dokumantik araçlarda yani mobilde;

/* dokunmatik menü */
@media (hover: none) {
  ul li ul {
    position:absolute;
    transform: translateX(-300px);
    transition:transform .2s ease-in-out;
    border-bottom: 1px solid black;
  }
  
  .menuAC:checked + ul {
    transform: translateX(0);
    height:auto;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    background: white;
  }
}

@media (hover: none) ile dokunmatik araçlara uygula diyoruz. Sonrası bildiğmiz tıklama ile menü açma kodumuz.

Mobil menü

Masaüstü araçlar için;

/* Desktop menu */
@media(hover: hover) and (pointer: fine) {
  ul li ul {
    position:absolute;
    display: none;
  }
  
  ul li ul li {
    display: block;
  }
  
  ul li:hover ul {
    top: 30px;
    left: 0;
    display: block;
  }
}

@media(hover: hover) and (pointer: fine) kodu ile bu alandaki kodların sadece hover ile çalışan araçlarda çalışmasını sağlıyoruz. Sonrasındaki kod bildiğimiz hover ile açılır menü kodu.

Tarayıcı desteği de gayet iyi.

Tarayıcı Desteği

Chrome explorer Firefox
+ - +

Mobil Tarayıcılar

Chrome Mobil Safari Samsung Internet
+ + +

Kaynaklar

Bu makaleyi Safari (15.4) tarayıcısının dialog elementi desteği gelmesi sonrası yazmaya karar verdim. Genel olarak bir işi standartlarla yapabiliyorsam onu tercih ederim. Bu konuda en müzdarip olduğum element <select> elementidir. Tasarımcıların birçok farklı düşüncelerine karşı select elementine bizim müdahale edeceğimiz yerler kısıtlıdır. Her ne kadar ısrar etsek te tasarıma uymak için özel select kütüphanelerine yönelmek zorunda kalıyoruz. Benzer durum dialog/modal/popup için de geçerli. Tabi uzun süre bu işi yapacak bir HTML elementi olmadığı için normal olarak başka yollarla bu işi çözdük.

<dialog> elementi modal ve pop-up olarak adlandırdığımız yapıları kolayca ve bir HTML elementi olarak kodlamamıza olanak sağlar.

En basit hali aşağıdaki gibidir.

<dialog>
  <h3>Konum bilginizi almak için izin istiyoruz</h3>
  <p>Bizimle konumunuzu paylaşır mısınız?</p>
  <div class="actions">
    <button>Tamam</button>
    <button>Kapat</button>
  </div>
</dialog>

Başlangıç durumunda bu içerik sayfada görüntülenmez. Eğer sayfa ilk açılışında görünür olmasını istiyorsak

<dialog open>
...
</dialog>

Sadece open özniteliğini eklemek yeterli oluyor.

Js ile açma kapama

Evet yukarıdaki kodu ekledik. Peki bu modal’ı nasıl açıp kapatacağız. Tabi ki basit iki javascript metoduyla

const openModal = document.querySelector('.open-model');
const closeModal = document.querySelector('.close-modal');
const locationModal = document.getElementById('location-modal');

openModal.addEventListener('click', () => {
  locationModal.showModal();
});

closeModal.addEventListener('click', () => {
  locationModal.close();
});

showModal() ve close() metodlarıyla açma kapa işini kolayca yapabiliyoruz.

showModal() yerine show() metodunu kullanırsak içerik modal olarak değil normak içerik olarak ta sayfa içinde açtırabiliyoruz.

Stil tanımları

<dialog> elementi normal bir HTML elementi gibi stillendirilebilir. Başlangıçta siyah bir kenar çizgisi, içeriğe göre genişlik ve backdrop olmadan gelir. Biz bu tanımları yaparak istediğimiz gibi modal stilleri kodlayabilriz.

dialog::backdrop {
  background: rgba(0,0,0, .5);
}

::backdrop sözde sınıfı yardımıyla modal arkasını istediğimiz gibi stillendirebiliyoruz.

dialog[open] {
  display: flex;
  flex-direction: column;
  animation: lastik .15s cubic-bezier(0, 1.8, 1, 1.8);
}

Yukarıdaki tanımla da modal açılırken istediğimiz animasyonu verebiliyoruz.

Form içeren dialog elementi

Modal içinde form alanlarını kullandığında formun method kısmına method="dialog" tanımlanarak formun gönderildiği durumlarda modal’ında kapanması sağlanır. Form değerini modal’a returnValue olarak geri döner.

closeModal.addEventListener('click', () => {
  locationModal.close();
  outputBox.value = locationModal.returnValue + " modal kapandı - " + (new Date()).toString();
});

Tüm yukardaı anlattıklarımız bir örnek ile uygularsak.

Sonuç

Her zaman standartta olan ögeleri kullanmak bize avantaj sağlar. Tabi gereksinimler bazen farklı yollara itebilir bizi.

Genel olarak <dialog> elementinin artıları

  • Her zaman içeriğin üstünde olacaktır. z-index değeri 99999 olan div’den bile üstte
  • Klavyede hazır tanımlıdır. Enter ile açılır, esc ile kapanır
  • Farklı araçlarda erişebilirlik açısından önemli artıları vardır.
  • Kullanıcı tercihlerine sadık kalır. Karanlık mod durumları mesela
  • Özel stil tanımlarına izin verir.
  • İçeriğinde form kullanılması durumu için farklı davranış desteği vardır.
  • Kullanım basitliği vardır.

Gördüğüm tek negatif yöne

  • Genel modal deneyimlerimizde yapmak istediğimiz backdrop’a tıklayınca modal’ın kapanması durumunu yapamıyoruz. Bu durum kullanıcı deneyimi için bir ihtiyaç mıdır? Tartışılır. Bu konuda Ercüment Laçın bir çözüm gönderdi gayet güzel. Teşekkür edip kodunu paylaşıyorum.
 locationModal.addEventListener("click", event => {
    const rect = locationModal.getBoundingClientRect();
    if (event.clientY < rect.top || event.clientY > rect.bottom ||
        event.clientX < rect.left || event.clientX > rect.right) {
        locationModal.close();
    };
});

Tarayıcı Desteği

Chrome explorer Firefox
+ - +

Mobil Tarayıcılar

Chrome Mobil Safari Samsung Internet
+ + +

Kaynaklar