Yükleme çubuğu bileşeni oluşturma

<progress> öğesiyle renge uyarlanabilir ve erişilebilir bir yükleme çubuğunun nasıl oluşturulacağına dair temel bir genel bakış.

Bu gönderide, uyumlu bir renge uyarlanabilir ve renge dayalı bir model oluşturma <progress> öğesi bulunan erişilebilir yükleme çubuğu. Şunu deneyin: demo'yu ziyaret edin ve kaynak!

Chrome'da açık ve koyu, belirsiz, artan ve tamamlandı.

Video kullanmayı tercih ederseniz bu gönderinin YouTube versiyonunu kullanabilirsiniz:

Genel Bakış

İlgili içeriği oluşturmak için kullanılan <progress> öğesi, kullanıcılara etkinliğin tamamlandığına dair görsel ve sesli geri bildirim sağlar. Bu görsel geri bildirim; bir form boyunca ilerleme, indirme veya yükleme bilgisinin görüntülenmesine, hatta dosyanın İlerleme tutarı bilinmiyor ancak çalışma hâlâ etkin.

Bu GUI Yarışması Mevcut HTML <progress> öğesini kullanarak erişilebilirlikle ilgili daha az çaba harcayabilirsiniz. İlgili içeriği oluşturmak için kullanılan renklerin ve düzenlerin, yerleşik öğe için özelleştirme sınırlarını zorlayarak bileşeni modernleştirir ve tasarım sistemlerine daha iyi sığmasını sağlar.

Her tarayıcıda açık ve koyu renkli sekmeler, 
    uyarlanabilir simgeye yukarıdan aşağıya genel bakış: 
    Safari, Firefox, Chrome.
Firefox, Safari, iOS Safari ve diğer platformlarda Açık ve koyu düzendeki Chrome ile Android Chrome.

Brüt kar

<progress> öğesini bir <label> dolaylı ilişki özelliklerini atlayıp dolaylı ilişkilidir. Ayrıca, yükleme durumundan etkilenen bir üst öğeyi de etiketledim. Bu nedenle, bu bilgileri kullanıcıya geri iletebiliyor.

<progress></progress>

value yoksa öğenin ilerleme durumu belirsiz olarak tanımlar. max özelliği varsayılan olarak 1 değerine ayarlanır. Bu nedenle, ilerleme durumu 0 ile 1 arasındadır. max ayarlanıyor değeri 0-100 olarak ayarlar. 0 aralığında kalmayı seçtim ve 1 sınır değerini içerir.Böylece ilerleme değerleri %0, 5 veya %50'ye çevrilir.

Etiketle sarmalanmış ilerleme durumu

Dolaylı bir ilişkide, ilerleme öğesi şuna benzer bir etiketle sarmalanır:

<label>Loading progress<progress></progress></label>

Demomda ekran okuyucular için etiket eklemeyi seçtim . Bu işlem, etiket metni bir <span> içinde sarmalanır ve bazı stiller uygulanır. bunu ekrandan uzaklaştıracak şekilde,

<label>
  <span class="sr-only">Loading progress</span>
  <progress></progress>
</label>

WebAIM'den aşağıdaki CSS ile:

.sr-only {
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(50%);
  height: 1px;
  width: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
}

Yalnızca ekran hazır öğesini gösteren geliştirici araçlarının ekran görüntüsü.

Yükleme işleminin ilerlemesinden etkilenen alan

İyi bir vizyonunuz varsa ilerleme göstergesini kolayca ilişkilendirebilirsiniz. ancak görme engelli kullanıcılar için farklı, alakalı çok açık. Bunu iyileştirmek için aria-busy özelliğini, yükleme tamamlandığında değişecek olan en üstteki öğeye atayın. Ayrıca, ilerleme durumu ve yükleme bölgesi arasında bir ilişki belirtin. şununla: aria-describedby.

<main id="loading-zone" aria-busy="true">
  …
  <progress aria-describedby="loading-zone"></progress>
</main>

JavaScript'ten, görevin başında aria-busy seçeneğini true olarak ayarlayın ve false tamamlandı.

Aria özelliği eklemeleri

Bir <progress> öğesinin örtülü rolü progressbar, müstehcen yaptım tarayıcılarla daha verimli şekilde çalışabilir. Ek olarak Öğeyi açıkça bilinmeyen duruma getirmek için indeterminate. öğe gözlemlendiğinden daha net bir şekilde value ayarlanmamıştır.

<label>
  Loading 
  <progress 
    indeterminate 
    role="progressbar" 
    aria-describedby="loading-zone"
    tabindex="-1"
  >unknown</progress>
</label>

Tekliflerinizi otomatikleştirmek ve optimize etmek için tabindex="-1" JavaScript'ten odaklanılabilir hale getirmek için. Bu adım, ekran okuyucu teknolojisinden yararlanabilirsiniz. Çünkü ilerlemeye, ilerlemeye güncellenen ilerlemenin ne kadarına ulaştığı, kullanıcıya duyurulur.

Stiller

İlerleme öğesi, stil olarak biraz karmaşıktır. Yerleşik HTML öğelerin, seçilmesi zor olabilen ve çoğu zaman .

Düzen

Düzen stilleri, ilerleme durumunda bir miktar esneklik sağlamak üzere tasarlanmıştır. öğenin boyutuna ve etiket konumuna göre değişiklik gösterir. Özel tamamlama durumu, yararlı ancak zorunlu olmayan bir ek görsel işaret olmalıdır.

<progress> Düzen

İlerleme öğesinin genişliği değiştirilmeden bırakılır, böylece küçülüp büyüyebilir. tasarım için gereken alanla birlikte. Yerleşik stiller, appearance ve border, none olarak ayarlanıyor. Bu işlem, öğenin her tarayıcının tarayıcı ayarları için kendi stilleri olduğundan, öğesine dokunun.

progress {
  --_track-size: min(10px, 1ex);
  --_radius: 1e3px;

  /*  reset  */
  appearance: none;
  border: none;

  position: relative;
  height: var(--_track-size);
  border-radius: var(--_radius);
  overflow: hidden;
}

_radius için 1e3px değeri bilimsel sayı kullanır bir ifadenin büyük bir sayı olduğundan border-radius her zaman yuvarlanır. Eşdeğerdir: 1000px Amacım bunu kullanmaya yetecek büyüklükte bir değer kullanmak Ayarlayıp unutabiliyorum (yazmak da 1000px yazmaktan daha kısa). Aynı zamanda kolayca büyütebilirsiniz: 3'ü 4 olarak değiştirin. Sonra 1e4px 10000px ile eşdeğerdir.

overflow: hidden kullanılıyor ve tartışmalı bir stil içeriyor. Birkaç hafta border-radius değerlerini dolgu öğelerini takip edebilir ve izleyebilir Ama bu aynı zamanda projedeki ilerlemenin öğenin dışında kalabilir. Bu özel ilerleme durumu için başka bir iterasyon öğesi overflow: hidden olmadan da yapılabilir ve bazı veya daha iyi tamamlanma durumları için fırsatlar sunar.

İşlem tamamlandı

CSS seçiciler, buradaki işin zor kısmını, maksimum değeri değerle karşılaştırarak yapar ve eşleşirse ilerleme tamamlanır. İşlem tamamlandığında, yapay bir öğe oluşturulur ve ilerleme öğesinin sonuna eklenir. Bu öğe, sonuna güzel bir görsel ipucu sağlar.

progress:not([max])[value="1"]::before,
progress[max="100"][value="100"]::before {
  content: "";
  
  position: absolute;
  inset-block: 0;
  inset-inline: auto 0;
  display: flex;
  align-items: center;
  padding-inline-end: max(calc(var(--_track-size) / 4), 3px);

  color: white;
  font-size: calc(var(--_track-size) / 1.25);
}

Yükleme çubuğunun% 100 olarak gösterildiği ve sonunda bir onay işareti gösterilen ekran görüntüsü.

Renk

Tarayıcı, ilerleme öğesi için kendi renklerini getirir ve yalnızca bir CSS mülküyle açık ve koyu renkli olabilir. Bunu, bazı güvenlik önlemleriyle özel seçicileri kullanabilirsiniz.

Açık ve koyu tarayıcı stilleri

Sitenizde koyu ve açık renkli uyarlanabilir <progress> öğesini etkinleştirmek için: Yalnızca color-scheme yeterlidir.

progress {
  color-scheme: light dark;
}

Tek mülk ilerleme durumu dolgulu rengi

Bir <progress> öğesinin tonunu ayarlamak için accent-color işlevini kullanın.

progress {
  accent-color: rebeccapurple;
}

Parça arka plan renginin, kullandığınız renk ayarına bağlı olarak açıktan koyuya dönüştüğünü accent-color Tarayıcı, kontrastın uygun olmasını sağlıyor: Oldukça düzenli.

Tamamen özel açık ve koyu renkler

<progress> öğesinde, biri kanal rengi için olmak üzere iki özel özellik ayarlayın diğeri de parkur ilerleme rengi için. İç mekan prefers-color-scheme ortam sorgusu için yeni renk değerleri sağlar ve ilerleme durumunu izler.

progress {
  --_track: hsl(228 100% 90%);
  --_progress: hsl(228 100% 50%);
}

@media (prefers-color-scheme: dark) {
  progress {
    --_track: hsl(228 20% 30%);
    --_progress: hsl(228 100% 75%);
  }
}

Odak stilleri

Daha önce öğeye, programlı bir şekilde yapılabilmesi için negatif sekme dizini vermiştik emin olabilirsiniz. Tekliflerinizi otomatikleştirmek ve optimize etmek için :focus-visible - daha akıllı odaklama halkası stilini etkinleştirmek için odağı özelleştirin. Bu şekilde fare tıklama ve odaklama, odak halkasını göstermez ancak klavye tıklamaları gösterir. İlgili içeriği oluşturmak için kullanılan YouTube videosu bu konuyu daha ayrıntılı şekilde ele alır ve incelenmeye değer.

progress:focus-visible {
  outline-color: var(--_progress);
  outline-offset: 5px;
}

Yükleme çubuğunun etrafında odak halkası olan ekran görüntüsü. Renklerin tümü eşleşiyor.

Tarayıcılarda özel stiller

Her biri bir <progress> öğesinin gösterir. İlerleme öğesinin kullanımı tek bir etikettir, ancak sözde CSS seçicileri aracılığıyla açığa çıkan birkaç alt öğe. Chrome Geliştirici Araçları ayarı etkinleştirirseniz bu öğeler size gösterilir:

  1. Sayfanızı sağ tıklayın ve Öğeyi İncele'yi seçerek Geliştirici Araçları'nı açın.
  2. Geliştirici Araçları penceresinin sağ üst köşesindeki Ayarlar dişli simgesini tıklayın.
  3. Elements başlığının altında Kullanıcı aracısı gölgesini göster"i bulup etkinleştirin DOM onay kutusunu işaretleyin.

Kullanıcı aracısı gölge DOM&#39;sinin gösterilmesinin Geliştirici Araçları&#39;nda nerede etkinleştirileceğini gösteren ekran görüntüsü.

Safari ve Chromium stilleri

Safari ve Chromium gibi WebKit tabanlı tarayıcılar açığa çıkıyor Bir alt kümeye izin veren ::-webkit-progress-bar ve ::-webkit-progress-value Kullanılacak CSS. Şimdilik özel özellikleri kullanarak background-color özelliğini ayarlayın bu modeller açık ve koyu renklere uyum sağlar.

/*  Safari/Chromium  */
progress[value]::-webkit-progress-bar {
  background-color: var(--_track);
}

progress[value]::-webkit-progress-value {
  background-color: var(--_progress);
}

İlerleme öğesinin iç öğelerini gösteren ekran görüntüsü.

Firefox stilleri

Firefox,::-moz-progress-bar <progress> öğesi. Bu aynı zamanda parçanın tonunu doğrudan ayarlayamadığımız anlamına da gelir.

/*  Firefox  */
progress[value]::-moz-progress-bar {
  background-color: var(--_progress);
}

Firefox&#39;un ve ilerleme öğesi bölümlerinin nerede bulunduğunun ekran görüntüsü.

Safari, iOS Safari ve Safari&#39;nin bulunduğu Hata Ayıklama Köşesinin ekran görüntüsü 
  Firefox, Chrome ve Android üzerindeki Chrome&#39;un tümünde çalışan olarak gösterilen yükleme çubuğu vardır.

iOS Safari'de Firefox'ta accent-color olarak ayarlanmış bir parkur rengi olduğuna dikkat edin açık mavi bir parkuru vardır. Koyu modda da aynı durum geçerlidir: Firefox'ta koyu renkli bir izleme vardır ancak değil ve Webkit tabanlı tarayıcılarda çalışır.

Animasyon

Tarayıcı yerleşik sözde seçicilerle çalışırken, çoğu zaman izin verilen CSS özellikleri kümesi.

Animasyonlar doldu

Dosyaya inline-size / ilerleme öğesi Chromium'da çalışır ancak Safari'de çalışmaz. Firefox da ::-moz-progress-bar öğesinde bir geçiş özelliği kullanmamalıdır.

/*  Chromium Only 😢  */
progress[value]::-webkit-progress-value {
  background-color: var(--_progress);
  transition: inline-size .25s ease-out;
}

:indeterminate durumu canlandırılıyor

Burada animasyon sağlayabilmek için daha yaratıcı oluyorum. Sözde öğe oluşturulan bir gradyan oluşturulur ve animasyonu arkaya üç tarayıcı için de geçerlidir.

Özel özellikler

Özel özellikler birçok alanda çok işe yarar, ancak benim favorilerimden biri sihirli görünen bir CSS değerine ad vermek. Takip etmek, karmaşık linear-gradient ama güzel bir adla. Amacı ve kullanım alanları net bir şekilde anlaşılabilir.

progress {
  --_indeterminate-track: linear-gradient(to right,
    var(--_track) 45%,
    var(--_progress) 0%,
    var(--_progress) 55%,
    var(--_track) 0%
  );
  --_indeterminate-track-size: 225% 100%;
  --_indeterminate-track-animation: progress-loading 2s infinite ease;
}

Özel özellikler de kodun DAR durumda kalmasına yardımcı olur. Çünkü bir kez daha tarayıcıya özel seçicileri gruplayın.

Animasyon kareleri

Hedef, ileri geri hareket eden sonsuz bir animasyon. Başlangıç ve bitiş animasyon kareleri CSS'de ayarlanır. Yalnızca bir animasyon karesi gerekir (ortadaki animasyon karesi) başladığı yere geri dönen bir animasyon oluşturmak için 50% tekrar deneyin!

@keyframes progress-loading {
  50% {
    background-position: left; 
  }
}

Her tarayıcıyı hedefleme

Her tarayıcı, <progress> üzerinde sözde öğe oluşturulmasına izin vermez öğesinin kendisine ait olan veya ilerleme çubuğunun animasyona izin verdiğinden emin olun. Diğer tarayıcılar desteği izini yapay bir öğeden çok canlandırmak için, gerçek olmayan öğelerden animasyon çubuklarına dönüştürüyor.

Chromium sözde öğe

Chromium, şu sözde öğeye izin verir: ::after örtülecek bir konumla kullanılıyor için geçerlidir. Belirsiz özel özellikler kullanılır ve geri ile çok iyi sonuç veriyor.

progress:indeterminate::after {
  content: "";
  inset: 0;
  position: absolute;
  background: var(--_indeterminate-track);
  background-size: var(--_indeterminate-track-size);
  background-position: right; 
  animation: var(--_indeterminate-track-animation);
}
Safari ilerleme çubuğu

Safari için özel özellikler ve bir animasyon sözde öğe ilerleme çubuğu:

progress:indeterminate::-webkit-progress-bar {
  background: var(--_indeterminate-track);
  background-size: var(--_indeterminate-track-size);
  background-position: right; 
  animation: var(--_indeterminate-track-animation);
}
Firefox ilerleme çubuğu

Firefox için özel özellikler ve animasyon, aynı zamanda sözde öğe ilerleme çubuğu:

progress:indeterminate::-moz-progress-bar {
  background: var(--_indeterminate-track);
  background-size: var(--_indeterminate-track-size);
  background-position: right; 
  animation: var(--_indeterminate-track-animation);
}

JavaScript

JavaScript, <progress> öğesiyle ilgili önemli bir rol oynar. Kontrol eder öğeye gönderilen değeri değiştirir ve öğede yeterli bilginin doküman oluşturabilirsiniz.

const state = {
  val: null
}

Demoda ilerlemeyi kontrol etmek için düğmeler vardır; state.val güncellemesi yapıyorlar ve ardından DOM.

document.querySelector('#complete').addEventListener('click', e => {
  state.val = 1
  setProgress()
})

setProgress()

Bu işlev, kullanıcı arayüzü/kullanıcı deneyimi düzenlemesinin gerçekleştiği yerdir. Başlamak için setProgress() işlevi. state nesnesi, ilerleme öğesi ve <main> alt bölgesi.

const setProgress = () => {
  
}

<main> alt bölgesinde yükleme durumu ayarlanıyor

İlerlemenin tamamlanıp tamamlanmadığına bağlı olarak, ilgili <main> öğesinin aria-busy özellik:

const setProgress = () => {
  zone.setAttribute('aria-busy', state.val < 1)
}

Yükleme miktarı bilinmiyorsa özellikleri temizle

Değer bilinmiyorsa veya ayarlanmamışsa bu kullanımdaki null, value ve aria-valuenow özellikleri. Bu işlem, <progress> öğesini belirsiz hale getirir.

const setProgress = () => {
  zone.setAttribute('aria-busy', state.val < 1)

  if (state.val === null) {
    progress.removeAttribute('aria-valuenow')
    progress.removeAttribute('value')
    progress.focus()
    return
  }
}

JavaScript ondalık matematik sorunlarını düzeltme

İlerleme varsayılanı olan maksimum 1'e bağlı kalmayı seçtiğim için demoda artırma ve azaltma fonksiyonları ondalık matematik kullanır. JavaScript ve diğer her zaman çok iyi olmayabilir, öğrenin. Matematikteki fazlalığı kaldıracak bir roundDecimals() fonksiyonunu aşağıda bulabilirsiniz sonuç:

const roundDecimals = (val, places) =>
  +(Math.round(val + "e+" + places)  + "e-" + places)

Değeri yuvarlayarak sunulması ve okunaklı olması için:

const setProgress = () => {
  zone.setAttribute('aria-busy', state.val < 1)

  if (state.val === null) {
    progress.removeAttribute('aria-valuenow')
    progress.removeAttribute('value')
    progress.focus()
    return
  }

  const val = roundDecimals(state.val, 2)
  const valPercent = val * 100 + "%"
}

Ekran okuyucular ve tarayıcı durumu için değer ayarlama

Değer, DOM'de üç konumda kullanılır:

  1. <progress> öğesinin value özelliği.
  2. aria-valuenow özelliği.
  3. <progress> içindeki metin içeriği.
const setProgress = () => {
  zone.setAttribute('aria-busy', state.val < 1)

  if (state.val === null) {
    progress.removeAttribute('aria-valuenow')
    progress.removeAttribute('value')
    progress.focus()
    return
  }

  const val = roundDecimals(state.val, 2)
  const valPercent = val * 100 + "%"

  progress.value = val
  progress.setAttribute('aria-valuenow', valPercent)
  progress.innerText = valPercent
}

İlerlemeye odaklanma

Değerler güncellendikten sonra, gören kullanıcılar ilerlemenin değiştiğini görürler, ancak ekran okuyucu kullanıcılarına henüz değişiklik duyurusu yapılmadı. <progress> öğesi ve tarayıcı, güncellemeyi duyurur.

const setProgress = () => {
  zone.setAttribute('aria-busy', state.val < 1)

  if (state.val === null) {
    progress.removeAttribute('aria-valuenow')
    progress.removeAttribute('value')
    progress.focus()
    return
  }

  const val = roundDecimals(state.val, 2)
  const valPercent = val * 100 + "%"

  progress.value = val
  progress.setAttribute('aria-valuenow', valPercent)
  progress.innerText = valPercent

  progress.focus()
}

Mac OS Voice Over uygulamasının ekran görüntüsü 
  yükleme çubuğunun ilerleme durumunu kullanıcıya okumayı ifade eder.

Sonuç

Şimdi bunu nasıl yaptığımı öğrendiğinize göre siz nasıl ‽ 🙂

Bir şans daha verirsem kesinlikle birkaç değişiklik yapmak istiyorum. Mevcut bileşeni temizlemek için yer var ve <progress> öğesinin sözde sınıf tarzı sınırlamaları olmadan bir bileşen oluşturmayı denemek için yer olduğunu düşünüyorum. Keşfetmeye değer.

Gelin, yaklaşımlarımızı çeşitlendirelim ve web'de içerik geliştirmenin tüm yollarını öğrenelim.

Bir demo oluşturup beni tweet'le bağlantıları eklerim aşağıdaki topluluk remiksleri bölümüne gidin!

Topluluk remiksleri