Düğme bileşeni oluşturma

Renk uyumlu, duyarlı ve erişilebilir <button> bileşenlerinin nasıl oluşturulacağına dair temel bir genel bakış.

Bu yayında, renge duyarlı, duyarlı ve erişilebilir bir <button> öğesi oluşturma hakkındaki düşüncelerimi paylaşmak istiyorum. Demoyu deneyin ve kaynağı görüntüleyin.

Açık ve koyu temalarda düğmelerle klavye ve fare aracılığıyla etkileşim kurulur.

Videoyu tercih ediyorsanız bu yayının YouTube sürümünü burada bulabilirsiniz:

Genel Bakış

Tarayıcı desteği

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Kaynak

<button> öğesi, kullanıcı etkileşimi için tasarlanmıştır. click etkinliği, zamanlamayla ilgili akıllı kurallar ile klavye, fare, dokunma, ses ve daha birçok kaynaktan tetiklenebilir. Ayrıca her tarayıcıda bazı varsayılan stiller bulunur. Bu stilleri herhangi bir özelleştirme yapmadan doğrudan kullanabilirsiniz. Tarayıcı tarafından sağlanan açık ve koyu düğmeleri de etkinleştirmek için color-scheme simgesini kullanın.

Ayrıca, önceki Codepen yerleşiminde gösterilen farklı düğme türleri de vardır. Türü olmayan bir <button>, gönder türüne dönüşerek <form> içinde olmaya uyum sağlar.

<!-- buttons -->
<button></button>
<button type="submit"></button>
<button type="button"></button>
<button type="reset"></button>

<!-- button state -->
<button disabled></button>

<!-- input buttons -->
<input type="button" />
<input type="file">

Bu ayki GUI Challenge'da her düğme, amacını görsel olarak ayırt etmeye yardımcı olacak stiller alacak. Sıfırlama düğmeleri, yıkıcı oldukları için uyarı renklerine sahip olur ve gönder düğmeleri, normal düğmelere kıyasla biraz daha öne çıkarılmış görünmeleri için mavi vurgu metnine sahip olur.

Simge düğmeleri ve özelleştirilmiş düğmeler için güzel eklemeler içeren, tüm düğme türlerinin nihai setinin önizlemesi.
Tüm düğme türlerinin nihai grubunun önizlemesi. Simge düğmeleri ve özelleştirilmiş düğmeler için güzel eklemeler ile formda değil, form dışında gösterilmektedir.

Düğmeler, CSS'nin stil oluşturmak için kullanabileceği sözde sınıflara da sahiptir. Bu sınıflar, düğmenin hissini özelleştirmek için CSS kancaları sağlar: :hover fare düğmenin üzerindeyken, :active fare veya klavye basıldığında ve :focus veya :focus-visible yardımcı teknoloji stilinde yardımcı olmak için.

button:hover {}
button:active {}
button:focus {}
button:focus-visible {}
Koyu temadaki tüm düğme türlerinin nihai setinin önizlemesi.
Koyu temadaki tüm düğme türlerinin nihai grubunun önizlemesi

Brüt kar

HTML spesifikasyonu tarafından sağlanan düğme türlerine ek olarak, simge içeren bir düğme ve özel sınıf btn-custom içeren bir düğme ekledim.

<button>Default</button>
<input type="button" value="<input>"/>
<button>
  <svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true">
    <path d="..." />
  </svg>
  Icon
</button>
<button type="submit">Submit</button>
<button type="button">Type Button</button>
<button type="reset">Reset</button>
<button disabled>Disabled</button>
<button class="btn-custom">Custom</button>
<input type="file">

Ardından, test için her düğme bir formun içine yerleştirilir. Bu sayede, gönder düğmesi gibi davranan varsayılan düğme için stillerin uygun şekilde güncellendiğinden emin olabilirim. Ayrıca, her ikisinin de eşit derecede iyi çalıştığından emin olmak için simge stratejisini satır içi SVG'den maskelenmiş SVG'ye geçiriyorum.

<form>
  <button>Default</button>
  <input type="button" value="<input>"/>
  <button>Icon <span data-icon="cloud"></span></button>
  <button type="submit">Submit</button>
  <button type="button">Type Button</button>
  <button type="reset">Reset</button>
  <button disabled>Disabled</button>
  <button class="btn-custom btn-large" type="button">Large Custom</button>
  <input type="file">
</form>

Kombinasyon matrisi şu anda oldukça zorlayıcı. Düğme türleri, sözde sınıflar ve form içinde veya dışında olma durumuyla birlikte 20'den fazla düğme kombinasyonu vardır. CSS'nin bunların her birini net bir şekilde ifade etmemize yardımcı olması iyi bir şey.

Erişilebilirlik

Düğme öğeleri doğal olarak erişilebilirdir ancak birkaç yaygın geliştirme vardır.

Fareyle üzerine gelme ve odaklanma

:hover ve :focus öğelerini :is() işlevsel sözde seçiciyle birlikte gruplandırmak istiyorum. Bu, arayüzlerimin her zaman klavye ve yardımcı teknoloji stillerini dikkate almasını sağlar.

button:is(:hover, :focus) {
  
}
Demo deneyin.

Etkileşimli odak halkası

Klavye ve yardımcı teknoloji kullanıcıları için odak halkasının animasyonunu etkinleştirmek istiyorum. Bunu, yalnızca düğme etkin olmadığında dış çizgiyi düğmeden 5 piksel uzaklaştırarak animasyonlu olarak gerçekleştiriyorum. Bu, odaklanma halkasının basıldığında düğme boyutuna geri çekilmesini sağlayan bir efekt oluşturur.

:where(button, input):where(:not(:active)):focus-visible {
  outline-offset: 5px;
}

Renk kontrastının uygun olduğundan emin olma

Açık ve koyu renklerde, renk kontrastının dikkate alınması gereken en az dört farklı renk kombinasyonu vardır: düğme, gönder düğmesi, sıfırla düğmesi ve devre dışı bırakılmış düğme. VisBug, tüm puanları aynı anda incelemek ve göstermek için burada kullanılır:

Simgelerin, göremeyen kullanıcılara gösterilmesini engelleme

Simge düğmesi oluştururken simge, düğme metnine görsel destek sağlamalıdır. Bu, simgenin görme engelli kullanıcılar için de yararlı olmadığı anlamına gelir. Neyse ki tarayıcı, ekran okuyucu teknolojisinden öğeleri gizleme olanağı sunar. Böylece, görme kaybı olan kullanıcılar dekoratif düğme resimleriyle uğraşmaz:

<button>
  <svg … aria-hidden="true">...</svg>
  Icon Button
</button>
Düğmenin erişilebilirlik ağacını gösteren Chrome Geliştirici Araçları. Ağ, aria-hidden özelliği true olarak ayarlandığı için düğme resmini yoksayar.
Düğmenin erişilebilirlik ağacını gösteren Chrome Geliştirici Araçları. Ağaç, aria-hidden özelliği true olarak ayarlandığı için düğme resmini yoksayar

Stiller

Bir sonraki bölümde, önce düğmenin uyarlanabilir stillerini yönetmek için özel bir mülk sistemi oluşturuyorum. Bu özel özellikler sayesinde öğeleri seçmeye ve görünümlerini özelleştirmeye başlayabilirim.

Uyarlanabilir özel mülk stratejisi

Bu GUI yarışmasında kullanılan özel mülk stratejisi, renk şeması oluşturma bölümünde kullanılan stratejiye çok benzer. Uyarlanabilir açık ve koyu renk sistemi için her temaya özel bir özellik tanımlanır ve buna göre adlandırılır. Ardından, temanın mevcut değerini tutmak için tek bir özel özellik kullanılır ve bu özellik bir CSS özelliğine atanır. Daha sonra tek özel mülk farklı bir değerle güncellenebilir ve ardından düğme stili güncellenebilir.

button {
  --_bg-light: white;
  --_bg-dark: black;
  --_bg: var(--_bg-light);

  background-color: var(--_bg);
}

@media (prefers-color-scheme: dark) {
  button {
    --_bg: var(--_bg-dark);
  }
}

Açık ve koyu temaların açıklayıcı ve net olması hoşuma gitti. Yönlendirme ve soyutlama, artık tek "reaktif" mülk olan --_bg özel mülküne aktarılır. --_bg-light ve --_bg-dark statiktir. Açık temanın varsayılan tema olduğunu ve koyu temanın yalnızca koşullu olarak uygulandığını da açıkça belirtmişsiniz.

Tasarım tutarlılığı için hazırlanma

Ortak seçici

Aşağıdaki seçici, tüm düğme türlerini hedeflemek için kullanılır ve ilk başta biraz karmaşık görünebilir. :where() kullanılır, bu nedenle düğmeyi özelleştirmek için özel bir işlem gerekmez. Düğmeler genellikle alternatif senaryolar için uyarlanır ve :where() seçici, görevin kolay olmasını sağlar. :where() içinde, :is() veya :where() içinde kullanılamayan ::file-selector-button dahil olmak üzere her düğme türü seçilidir.

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"],
  input[type="file"]
),
:where(input[type="file"])::file-selector-button {
  
}

Tüm özel mülkler bu seçicinin kapsamına alınır. Tüm özel mülkleri incelemenin zamanı geldi. Bu düğmede oldukça fazla özel özellik kullanılmıştır. Her grubu anlatırken ilerleyeceğiz ve bölümün sonunda karanlık ve azaltılmış hareket bağlamlarını paylaşacağız.

Düğme vurgu rengi

Gönder düğmeleri ve simgelerde renkleri öne çıkarabilirsiniz:

--_accent-light: hsl(210 100% 40%);
--_accent-dark: hsl(210 50% 70%);
--_accent: var(--_accent-light);

Düğme metni rengi

Düğme metin renkleri beyaz veya siyah değildir. hsl() kullanılarak --_accent renginin koyulaştırılmış veya aydınlatılmış sürümleridir ve 210 tonuna bağlıdır:

--_text-light: hsl(210 10% 30%);
--_text-dark: hsl(210 5% 95%);
--_text: var(--_text-light);

Düğme arka plan rengi

Düğme arka planları, açık tema düğmeleri hariç aynı hsl() desenini kullanır. Açık tema düğmeleri, kullanıcıya yakın veya diğer yüzeylerin önünde görünmeleri için beyaz olarak ayarlanır:

--_bg-light: hsl(0 0% 100%);
--_bg-dark: hsl(210 9% 31%);
--_bg: var(--_bg-light);

Düğme arka planı

Bu arka plan rengi, bir yüzeyin diğer yüzeylerin arkasında görünmesini sağlamak için kullanılır ve dosya girişinin arka planı için yararlıdır:

--_input-well-light: hsl(210 16% 87%);
--_input-well-dark: hsl(204 10% 10%);
--_input-well: var(--_input-well-light);

Düğme dolgusu

Düğmedeki metnin etrafındaki boşluk, yazı tipi boyutuna göre göreli bir uzunluk olan ch birimi kullanılarak ayarlanır. Büyük düğmeler font-size ve düğme ölçeklerini orantılı olarak artırdığında bu durum kritik hale gelir:

--_padding-inline: 1.75ch;
--_padding-block: .75ch;

Düğme kenarı

Dosya girişinin diğer düğmelerle eşleşebilmesi için düğme kenarlığı yarıçapı özel bir mülke yerleştirilir. Kenarlık renkleri, belirlenmiş uyarlanabilir renk sistemini izler:

--_border-radius: .5ch;

--_border-light: hsl(210 14% 89%);
--_border-dark: var(--_bg-dark);
--_border: var(--_border-light);

Fareyle düğmenin üzerine geldiğinizde vurgu efekti

Bu mülkler, etkileşimde geçiş için bir boyut özelliği oluşturur ve vurgu rengi, uyarlanabilir renk sistemini izler. Bu öğelerin nasıl etkileşime girdiğini bu makalenin ilerleyen bölümlerinde ele alacağız. Ancak bu öğeler temel olarak box-shadow etkisi için kullanılır:

--_highlight-size: 0;

--_highlight-light: hsl(210 10% 71% / 25%);
--_highlight-dark: hsl(210 10% 5% / 25%);
--_highlight: var(--_highlight-light);

Düğme metin gölgesi

Her düğmenin ince bir metin gölge stili vardır. Bu sayede metin düğmenin üzerine oturur, okunabilirliği artırır ve sunumunuza hoş bir cila katmanı ekler.

--_ink-shadow-light: 0 1px 0 var(--_border-light);
--_ink-shadow-dark: 0 1px 0 hsl(210 11% 15%);
--_ink-shadow: var(--_ink-shadow-light);

Düğme simgesi

Simgeler, yine göreli uzunluk ch birimi sayesinde iki karakter boyutundadır. Bu, simgenin düğme metnine orantılı olarak ölçeklenmesine yardımcı olur. Simge rengi, uyarlanabilir ve tema içi bir renk için --_accent-color'e dayanır.

--_icon-size: 2ch;
--_icon-color: var(--_accent);

Düğme gölgesi

Gölgelerin açık ve koyuya uygun şekilde ayarlanması için hem renklerinin hem de şeffaflıklarının değiştirilmesi gerekir. Açık tema gölgeleri, ince ve üzerine bindirdikleri yüzeyin rengine doğru renklendirildiğinde en iyi sonucu verir. Koyu tema gölgelerinin, koyu yüzey renklerinin üzerine binmesi için daha koyu ve daha doygun olması gerekir.

--_shadow-color-light: 220 3% 15%;
--_shadow-color-dark: 220 40% 2%;
--_shadow-color: var(--_shadow-color-light);

--_shadow-strength-light: 1%;
--_shadow-strength-dark: 25%;
--_shadow-strength: var(--_shadow-strength-light);

Uyarlanabilir renkler ve yoğunluklarla iki farklı gölge derinliği oluşturabilirim:

--_shadow-1: 0 1px 2px -1px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 9%));

--_shadow-2: 
  0 3px 5px -2px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 3%)),
  0 7px 14px -5px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 5%));

Ayrıca, düğmelere biraz 3D görünüm vermek için 1px box-shadow ile illüzyon oluşturabilirsiniz:

--_shadow-depth-light: 0 1px var(--_border-light);
--_shadow-depth-dark: 0 1px var(--_bg-dark);
--_shadow-depth: var(--_shadow-depth-light);

Düğme geçişleri

Uyarlanabilir renkler için kalıbı izleyerek tasarım sistemi seçeneklerini barındıracak iki statik özellik oluşturuyorum:

--_transition-motion-reduce: ;
--_transition-motion-ok:
  box-shadow 145ms ease,
  outline-offset 145ms ease
;
--_transition: var(--_transition-motion-reduce);

Seçicideki tüm mülkler

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"],
  input[type="file"]
),
:where(input[type="file"])::file-selector-button {
  --_accent-light: hsl(210 100% 40%);
  --_accent-dark: hsl(210 50% 70%);
  --_accent: var(--_accent-light);

--_text-light: hsl(210 10% 30%); --_text-dark: hsl(210 5% 95%); --_text: var(--_text-light);

--_bg-light: hsl(0 0% 100%); --_bg-dark: hsl(210 9% 31%); --_bg: var(--_bg-light);

--_input-well-light: hsl(210 16% 87%); --_input-well-dark: hsl(204 10% 10%); --_input-well: var(--_input-well-light);

--_padding-inline: 1.75ch; --_padding-block: .75ch;

--_border-radius: .5ch; --_border-light: hsl(210 14% 89%); --_border-dark: var(--_bg-dark); --_border: var(--_border-light);

--_highlight-size: 0; --_highlight-light: hsl(210 10% 71% / 25%); --_highlight-dark: hsl(210 10% 5% / 25%); --_highlight: var(--_highlight-light);

--_ink-shadow-light: 0 1px 0 hsl(210 14% 89%); --_ink-shadow-dark: 0 1px 0 hsl(210 11% 15%); --_ink-shadow: var(--_ink-shadow-light);

--_icon-size: 2ch; --_icon-color-light: var(--_accent-light); --_icon-color-dark: var(--_accent-dark); --_icon-color: var(--accent, var(--_icon-color-light));

--_shadow-color-light: 220 3% 15%; --_shadow-color-dark: 220 40% 2%; --_shadow-color: var(--_shadow-color-light); --_shadow-strength-light: 1%; --_shadow-strength-dark: 25%; --_shadow-strength: var(--_shadow-strength-light); --_shadow-1: 0 1px 2px -1px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 9%)); --_shadow-2: 0 3px 5px -2px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 3%)), 0 7px 14px -5px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 5%)) ;

--_shadow-depth-light: hsl(210 14% 89%); --_shadow-depth-dark: var(--_bg-dark); --_shadow-depth: var(--_shadow-depth-light);

--_transition-motion-reduce: ; --_transition-motion-ok: box-shadow 145ms ease, outline-offset 145ms ease ; --_transition: var(--_transition-motion-reduce); }

Varsayılan düğmeler açık ve koyu temada yan yana gösterilir.

Koyu tema uyarlamaları

Koyu tema öğeleri ayarlandığında -light ve -dark statik öğe kalıbının değeri netleşir:

@media (prefers-color-scheme: dark) {
  :where(
    button,
    input[type="button"],
    input[type="submit"],
    input[type="reset"],
    input[type="file"]
  ),
  :where(input[type="file"])::file-selector-button {
    --_bg: var(--_bg-dark);
    --_text: var(--_text-dark);
    --_border: var(--_border-dark);
    --_accent: var(--_accent-dark);
    --_highlight: var(--_highlight-dark);
    --_input-well: var(--_input-well-dark);
    --_ink-shadow: var(--_ink-shadow-dark);
    --_shadow-depth: var(--_shadow-depth-dark);
    --_shadow-color: var(--_shadow-color-dark);
    --_shadow-strength: var(--_shadow-strength-dark);
  }
}

Bu, yalnızca okunaklı olmakla kalmaz, bu özel düğmeleri kullanan tüketiciler de kullanıcı tercihlerine uygun şekilde uyarlanacağından emin olarak temel öğeleri kullanabilir.

Hareket azaltma uyarlamaları

Ziyaret eden kullanıcı hareketi kabul ediyorsa --_transitionvar(--_transition-motion-ok)'e atayın:

@media (prefers-reduced-motion: no-preference) {
  :where(
    button,
    input[type="button"],
    input[type="submit"],
    input[type="reset"],
    input[type="file"]
  ),
  :where(input[type="file"])::file-selector-button {
    --_transition: var(--_transition-motion-ok);
  }
}

Birkaç paylaşılan stil

Düğmelerin ve girişlerin yazı tiplerinin, sayfadaki diğer yazı tipleriyle eşleşecek şekilde inherit olarak ayarlanması gerekir. Aksi takdirde, tarayıcılar tarafından stilize edilirler. Bu durum letter-spacing için de geçerlidir. line-height değerini 1.5 olarak ayarladığınızda, harf kutusu boyutu metnin üst ve alt kısmında biraz boşluk olacak şekilde ayarlanır:

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"],
  input[type="file"]
),
:where(input[type="file"])::file-selector-button {
  /* …CSS variables */

  font: inherit;
  letter-spacing: inherit;
  line-height: 1.5;
  border-radius: var(--_border-radius);
}

Önceki stiller uygulandıktan sonra düğmeleri gösteren ekran görüntüsü.

Düğmelerin stilini değiştirme

Seçici ayarı

Seçici input[type="file"], girişin düğme kısmı değildir. Bu kısım, sözde öğe ::file-selector-button'dir. Bu nedenle input[type="file"]'ü listeden çıkardım:

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"],
  input[type="file"]
),
:where(input[type="file"])::file-selector-button {
  
}

İmleç ve dokunma düzenlemeleri

Öncelikle imleci pointer stilinde biçimlendiriyorum. Bu, düğmenin fare kullanıcılarına etkileşimli olduğunu göstermesine yardımcı olur. Ardından, tıklamaların beklemesi ve olası bir çift tıklamayı gözlemlemesi gerekmemesi için touch-action: manipulation ekleyerek düğmelerin daha hızlı görünmesini sağlarım:

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
  cursor: pointer;
  touch-action: manipulation;
}

Renkler ve kenarlık

Ardından, daha önce oluşturulan bazı uyarlanabilir özel özellikleri kullanarak yazı tipi boyutunu, arka planı, metni ve kenar çizgisi renklerini özelleştiriyorum:

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
  

  font-size: var(--_size, 1rem);
  font-weight: 700;
  background: var(--_bg);
  color: var(--_text);
  border: 2px solid var(--_border);
}

Önceki stiller uygulandıktan sonra düğmeleri gösteren ekran görüntüsü.

Gölgeler

Düğmelerde bazı harika teknikler uygulanmış. text-shadow, açık ve koyu renklere uyum sağlar. Böylece, arka planın üzerinde güzelce duran düğme metninin hoş ve zarif bir görünümü olur. box-shadow için üç gölge atanır. İlki (--_shadow-2), normal bir kutu gölgesidir. İkinci gölge, düğmenin biraz eğimli görünmesini sağlayan bir göz yanılsamasıdır. Son gölge, fareyle üzerine gelindiğinde beliren vurgu içindir. Başlangıçta 0 boyutundadır ancak daha sonra boyutu ayarlanır ve düğmeden büyüyormuş gibi görünecek şekilde geçiş yapılır.

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
  

  box-shadow: 
    var(--_shadow-2),
    var(--_shadow-depth),
    0 0 0 var(--_highlight-size) var(--_highlight)
  ;
  text-shadow: var(--_ink-shadow);
}

Önceki stiller uygulandıktan sonra düğmeleri gösteren ekran görüntüsü.

Düzen

Düğmeye flexbox düzeni, özellikle de içeriğine sığacak bir inline-flex düzeni verdim. Ardından metni ortalar ve alt öğeleri dikey ve yatay olarak ortaya hizalarım. Bu sayede simgeler ve diğer düğme öğeleri düzgün şekilde hizalanır.

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
  

  display: inline-flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}

Önceki stiller uygulandıktan sonra düğmeleri gösteren ekran görüntüsü.

Boşluk

Düğme aralığı için, kardeşlerin birbirine değmesini önlemek amacıyla gap kullandım ve düğme aralığının tüm metin düzenlerinde çalışabilmesi için dolgu için mantıksal özellikleri kullandım.

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
  

  gap: 1ch;
  padding-block: var(--_padding-block);
  padding-inline: var(--_padding-inline);
}

Önceki stiller uygulandıktan sonra düğmeleri gösteren ekran görüntüsü.

Dokunma ve fare kullanıcı deneyimi

Bu sonraki bölüm, çoğunlukla mobil cihazlarda dokunmatik ekran kullanan kullanıcılar içindir. İlk özellik olan user-select tüm kullanıcılar içindir ve metnin düğme metnini vurgulamasını engeller. Bu durum, çoğunlukla dokunmatik cihazlarda bir düğmeye dokunup basılı tutulduğunda ve işletim sistemi düğmenin metnini vurguladığında fark edilir.

Genellikle yerleşik uygulamalardaki düğmelerde bu kullanıcı deneyiminin olmadığını fark ettiğim için user-select değerini none olarak ayarlayarak devre dışı bırakıyorum. Vurgu renkleri (-webkit-tap-highlight-color) ve işletim sistemi bağlam menüleri (-webkit-touch-callout), web'e odaklı diğer düğme özellikleridir ve kullanıcıların düğmeyle ilgili genel beklentilerine uygun değildir. Bu nedenle, bu özellikleri de kaldırıyorum.

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
  

  user-select: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
}

Geçişler

Uyarlanabilir --_transition değişkeni transition özelliğine atanır:

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
  

  transition: var(--_transition);
}

Kullanıcı aktif olarak basmıyorken fareyle üzerine gelindiğinde, gölge vurgu boyutunu ayarlayarak düğmenin içinden büyüyormuş gibi görünen güzel bir odaklanma görünümü elde edin:

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
):where(:not(:active):hover) {
  --_highlight-size: .5rem;
}

Odaklandığında, odak ana hatlarının düğmeden uzaklığını artırın ve düğmenin içinden büyüyormuş gibi görünen güzel bir odak görünümü oluşturun:

:where(button, input):where(:not(:active)):focus-visible {
  outline-offset: 5px;
}

Simgeler

Seçici, simgelerle işlem yapmak için doğrudan SVG alt öğeleri veya data-icon özel özelliğine sahip öğeler için :where() seçicisine sahiptir. Simge boyutu, satır içi ve blok mantıksal özellikleri kullanılarak özel mülkle ayarlanır. text-shadow ile eşleşecek bir drop-shadow ve çizgi rengi ayarlanır. Simgenin hiçbir zaman sıkıştırılmaması için flex-shrink, 0 olarak ayarlanır. Son olarak, çizgili simgeler seçip bu stilleri fill: none ve round satır sonları ve satır birleştirmeleriyle burada atadım:

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
) > :where(svg, [data-icon]) {
  block-size: var(--_icon-size);
  inline-size: var(--_icon-size);
  stroke: var(--_icon-color);
  filter: drop-shadow(var(--_ink-shadow));

  flex-shrink: 0;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

Önceki stiller uygulandıktan sonra düğmeleri gösteren ekran görüntüsü.

Gönder düğmelerini özelleştirme

Gönder düğmelerinin biraz öne çıkan bir görünüme sahip olmasını istedim ve bunu düğmelerin metin rengini vurgu rengi yaparak başardım:

:where(
  [type="submit"], 
  form button:not([type],[disabled])
) {
  --_text: var(--_accent);
}

Önceki stiller uygulandıktan sonra düğmeleri gösteren ekran görüntüsü.

Sıfırlama düğmelerini özelleştirme

Sıfırlama düğmelerinde, kullanıcıları yıkıcı olabilecek davranışları konusunda uyaracak bazı yerleşik uyarı işaretleri olmasını istedim. Ayrıca açık tema düğmesini, koyu tema düğmesine kıyasla daha fazla kırmızı vurguyla biçimlendirdim. Özelleştirme, temeldeki uygun açık veya koyu rengi değiştirerek yapılır ve düğme stili günceller:

:where([type="reset"]) {
  --_border-light: hsl(0 100% 83%);
  --_highlight-light: hsl(0 100% 89% / 20%);
  --_text-light: hsl(0 80% 50%);
  --_text-dark: hsl(0 100% 89%);
}

Ayrıca, odak dış çizgisinin renginin kırmızı vurgu rengiyle eşleşmesinin iyi olacağını düşündüm. Metin rengi koyu kırmızıdan açık kırmızıya uyarlanır. Dış çizginin rengini currentColor anahtar kelimesiyle eşleşecek şekilde ayarlıyorum:

:where([type="reset"]):focus-visible {
  outline-color: currentColor;
}

Önceki stiller uygulandıktan sonra düğmeleri gösteren ekran görüntüsü.

Devre dışı bırakılmış düğmeleri özelleştirme

Devre dışı bırakılan düğmelerin, devre dışı bırakılan düğmenin daha az etkin görünmesi için düğmenin renginin azaltılmaya çalışılması sırasında renk kontrastının düşük olması çok yaygın bir durumdur. Her renk grubunu test ettim ve DevTools veya VisBug'da puan geçene kadar HSL açıklık değerini değiştirerek testleri geçtiklerinden emin oldum.

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
)[disabled] {
  --_bg: none;
  --_text-light: hsl(210 7% 40%);
  --_text-dark: hsl(210 11% 71%);

  cursor: not-allowed;
  box-shadow: var(--_shadow-1);
}

Önceki stiller uygulandıktan sonra düğmeleri gösteren ekran görüntüsü.

Dosya giriş düğmelerini özelleştirme

Dosya giriş düğmesi, bir span ve düğme kapsayıcısıdır. CSS, giriş kapsayıcısının yanı sıra iç içe yerleştirilmiş düğmeyi biraz biçimlendirebilir ancak span öğesini biçimlendiremez. Kapsayıcıya max-inline-size verilir, böylece gerekenden daha büyük olmaz. inline-size: 100% ise küçülmesine ve kendisinden daha küçük kapsayıcılara sığmasına olanak tanır. Arka plan rengi, diğer yüzeylerden daha koyu olan uyarlanabilir bir renge ayarlanır. Böylece dosya seçici düğmesinin arkasında görünür.

:where(input[type="file"]) {
  inline-size: 100%;
  max-inline-size: max-content;
  background-color: var(--_input-well);
}

Dosya seçici düğmesi ve giriş türü düğmeleri, diğer düğme stilleri tarafından üzerine yazılmayan, tarayıcı tarafından sağlanan tüm stilleri kaldırmak için özel olarak appearance: noneverilir.

:where(input[type="button"]),
:where(input[type="file"])::file-selector-button {
  appearance: none;
}

Son olarak, span metnini düğmeden uzaklaştırarak boşluk oluşturmak için düğmenin inline-end özelliğine kenar boşluğu eklenir.

:where(input[type="file"])::file-selector-button {
  margin-inline-end: var(--_padding-inline);
}

Önceki stiller uygulandıktan sonra düğmeleri gösteren ekran görüntüsü.

Koyu temayla ilgili özel istisnalar

Birincil işlem düğmelerine, metinle daha yüksek kontrast elde etmek için daha koyu bir arka plan verdim. Böylece düğmelere biraz daha tanıtım amaçlı bir görünüm kazandırdım.

@media (prefers-color-scheme: dark) {
  :where(
    [type="submit"],
    [type="reset"],
    [disabled],
    form button:not([type="button"])
  ) {
    --_bg: var(--_input-well);
  }
}

Önceki stiller uygulandıktan sonra düğmeleri gösteren ekran görüntüsü.

Varyant oluşturma

Eğlenceli ve kullanışlı olduğu için birkaç varyantın nasıl oluşturulacağını göstermeyi tercih ettim. Bir varyant, birincil düğmelerin genellikle göründüğü gibi çok canlıdır. Diğer bir varyant da büyüktür. Son varyantta, renk geçişi dolgulu bir simge bulunur.

Canlı düğme

Bu düğme stilini elde etmek için temel öğeleri doğrudan mavi renklerle yazdım. Bu işlem hızlı ve kolay olsa da uyarlanabilir öğeleri kaldırır ve hem açık hem de koyu temalarda aynı görünür.

.btn-custom {
  --_bg: linear-gradient(hsl(228 94% 67%), hsl(228 81% 59%));
  --_border: hsl(228 89% 63%);
  --_text: hsl(228 89% 100%);
  --_ink-shadow: 0 1px 0 hsl(228 57% 50%);
  --_highlight: hsl(228 94% 67% / 20%);
}

Özel düğme açık ve koyu renkte gösterilir. Tipik birincil işlem düğmelerinde olduğu gibi çok canlı bir mavidir.

Büyük düğme

Bu düğme stili, --_size özel mülkü değiştirilerek elde edilir. Boşluk ve diğer alan öğeleri bu boyuta göredir ve yeni boyuta orantılı olarak ölçeklendirilir.

.btn-large {
  --_size: 1.5rem;
}

Özel düğmenin yanında yaklaşık 150 kat daha büyük bir büyük düğme gösterilir.

Simge düğmesi

Bu simge efektinin düğme stillerimizle hiçbir ilgisi yoktur ancak bu efekti yalnızca birkaç CSS özelliğiyle nasıl elde edeceğinizi ve düğmenin satır içi SVG olmayan simgeleri ne kadar iyi işlediğini gösterir.

[data-icon="cloud"] {
  --icon-cloud: url("https://api.iconify.design/mdi:apple-icloud.svg") center / contain no-repeat;

  -webkit-mask: var(--icon-cloud);
  mask: var(--icon-cloud);
  background: linear-gradient(to bottom, var(--_accent-dark), var(--_accent-light));
}

Açık ve koyu temalarda simge içeren bir düğme gösterilir.

Sonuç

Bunu nasıl yaptığımı öğrendiğinize göre, siz ne yapardınız? 🙂

Yaklaşımlarımızı çeşitlendirelim ve web'de uygulama geliştirmenin tüm yollarını öğrenelim.

Bir demo oluşturun, bağlantılarını bana tweetleyin. Ardından, aşağıdaki topluluk remiksleri bölümüne ekleyeceğim.

Topluluk remiksleri

Henüz gösterilecek bir şey yok.

Kaynaklar