Düğme bileşeni oluşturma

Renk uyarlamalı, duyarlı ve erişilebilir <button> bileşenler oluşturma hakkında temel bilgiler.

Bu yayında, renge uyarlanabilir, duyarlı ve erişilebilir bir <button> öğesi oluşturma konusundaki 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.

Video tercih ediyorsanız bu yayının YouTube versiyonunu aşağıda bulabilirsiniz:

Genel Bakış

Browser Support

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

Source

<button> öğesi, kullanıcı etkileşimi için oluşturulmuştur. Klavye, fare, dokunma, ses ve daha fazlasından click etkinlik tetikleyicileri ve zamanlamasıyla ilgili akıllı kurallar içerir. 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, her biri önceki Codepen yerleştirmesinde gösterilen farklı düğme türleri de vardır. Tür içermeyen bir <button>, <form> içinde olmaya uyum sağlayarak gönderim türüne dönüşür.

<!-- 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 (GUI Yarışması), her düğmeye amacını görsel olarak ayırt etmeye yardımcı olacak stiller uygulanacak. Sıfırlama düğmeleri, yıkıcı oldukları için uyarı renklerine sahip olacak. Gönderme düğmelerinde ise normal düğmelere kıyasla biraz daha belirgin görünmeleri için mavi vurgu metni kullanılacak.

Tüm düğme türlerinin son halinin önizlemesi. Formda ve formda olmayan şekilde gösterilir. Simge düğmeler ve özelleştirilmiş düğmeler için güzel eklemeler içerir.
Tüm düğme türlerinin nihai kümesinin formda ve formda olmayan bir şekilde gösterildiği önizleme, simge düğmeleri ve özelleştirilmiş düğmeler için güzel eklemelerle

Düğmelerde, CSS'nin stil oluşturmak için kullanabileceği sözde sınıflar da bulunur. Bu sınıflar, düğmenin görünümünü özelleştirmek için CSS kancaları sağlar: :hover fare düğmenin üzerindeyken, :active fare veya klavye basarken ve :focus ya da :focus-visible yardımcı teknoloji stilini desteklemek için kullanılır.

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

Brüt kar

HTML spesifikasyonunda sağlanan düğme türlerine ek olarak, simge içeren bir düğme ve özel sınıflı bir düğme btn-custom 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 şekilde, gönder düğmesi gibi davranan varsayılan düğme için stillerin uygun şekilde güncellenmesini sağlayabilirim. 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 değiştiriyorum.

<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>

Bu noktada kombinasyon matrisi oldukça karmaşık bir hal alır. Düğme türleri, sözde sınıflar ve formda olup olmama durumu arasında 20'den fazla düğme kombinasyonu vardır. CSS, bunların her birini net bir şekilde ifade etmemize yardımcı olur.

Erişilebilirlik

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

Birlikte fareyle üzerine gelme ve odaklanma

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

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

Etkileşimli odak halkası

Klavye ve yardımcı teknoloji kullanıcıları için odak halkasını animasyonlu hale getirmek istiyorum. I accomplish this by animating the outline away from the button by 5px, but only when the button is not active. Bu, odak halkasının düğme boyutuna geri küçülmesini sağlayan bir efekt oluşturur.

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

Renk kontrastının yeterli olmasını sağlama

Açık ve koyu renkler arasında, renk kontrastı açısından 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ışı düğme. VisBug, tüm puanları aynı anda incelemek ve göstermek için kullanılır:

Görme engelli kullanıcılardan simgeleri gizleme

Simge düğmesi oluştururken simge, düğme metnine görsel destek sağlamalıdır. Bu nedenle, görme kaybı olan kişiler için simgenin değeri yoktur. Neyse ki tarayıcı, öğeleri ekran okuyucu teknolojisinden gizleme olanağı sunuyor. Böylece görme kaybı olan kullanıcılar, dekoratif düğme resimlerinden rahatsız olmuyor:

<button>
  <svg … aria-hidden="true">...</svg>
  Icon Button
</button>
Chrome Geliştirici Araçları&#39;nda düğmenin erişilebilirlik ağacı gösteriliyor. Ağaç, aria-hidden özelliği true olarak ayarlandığı için düğme resmini yoksayıyor.
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 yoksayıyor.

Stiller

Bu sonraki bölümde, öncelikle düğmenin uyarlanabilir stillerini yönetmek için özel bir özellik sistemi oluşturuyorum. Bu özel özelliklerle öğeleri seçip görünümlerini özelleştirmeye başlayabilirim.

Uyarlanabilir özel özellik stratejisi

Bu GUI Challenge'da 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 tema için özel bir özellik tanımlanır ve buna göre adlandırılır. Ardından, temanın geçerli 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 özellik farklı bir değerle güncellenebilir ve ardından düğme stili güncellenir.

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 bildirimsel ve net olması hoşuma gidiyor. Dolaylılık ve soyutlama, artık tek "reaktif" özellik olan --_bg özel özelliğine aktarılıyor. --_bg-light ve --_bg-dark statiktir. Açık temanın varsayılan tema olduğu ve koyu temanın yalnızca koşullu olarak uygulandığı da açıkça belirtiliyor.

Tasarım tutarlılığına hazırlanma

Paylaşılan seçici

Aşağıdaki seçici, çeşitli düğme türlerinin tümünü hedeflemek için kullanılır ve ilk başta biraz kafa karıştırıcı olabilir. :where() kullanıldığından düğmeyi özelleştirmek için belirli bir özellik gerekmez. Düğmeler genellikle alternatif senaryolara uyarlanır ve :where() seçici, görevin kolay olmasını sağlar. :where() içinde, ::file-selector-button dahil olmak üzere her düğme türü seçilir. ::file-selector-button, :is() veya :where() içinde kullanılamaz.

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

Tüm özel özellikler bu seçicinin kapsamına alınır. Tüm özel mülkleri inceleme zamanı! Bu düğmede kullanılan birkaç özel özellik var. Her grubu açıklayacağım ve bölümün sonunda koyu renkli ve azaltılmış hareketli içeriklerle ilgili bağlamları paylaşacağım.

Düğme vurgu rengi

Gönderme düğmeleri ve simgeleri, renk katmak için idealdir:

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

Düğme metni rengi

Düğme metni renkleri beyaz veya siyah değil, --_accent renginin hsl() kullanılarak koyulaştırılmış veya açıklaştırılmış versiyonlarıdır ve 210 renk 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() deseniyle oluşturulur. Açık tema düğmeleri, yüzeylerinin kullanıcıya yakın veya diğer yüzeylerin önünde görünmesi için beyaz renkte 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. Dosya girişinin arka planı için kullanışlı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öreceli bir uzunluk olan ch birimi kullanılarak yapılır. Bu durum, büyük düğmelerin font-size değerini kolayca artırabildiği ve düğme ölçeklerinin orantılı olarak değiştiği durumlarda kritik önem kazanır:

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

Düğme kenarlığı

Düğme kenarlığı yarıçapı, dosya girişinin diğer düğmelerle eşleşebilmesi için özel bir özelliğe yerleştirilir. Kenarlık renkleri, belirlenen uyarlanabilir renk sistemine uygundur:

--_border-radius: .5ch;

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

Düğme üzerine gelindiğinde vurgu efekti

Bu özellikler, etkileşimde geçiş için bir boyut özelliği oluşturur ve vurgu rengi, uyarlanabilir renk sistemini takip eder. Bu öğelerin nasıl etkileşime girdiğini bu yayının ilerleyen bölümlerinde ele alacağız. Ancak bu öğeler, sonuç olarak box-shadow efekti 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 metni gölgesi

Her düğmede ince bir metin gölgesi stili bulunur. Bu sayede metin, düğmenin üzerinde yer alır. Böylece okunabilirlik artar ve sunuma şık bir görünüm kazandırılır.

--_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

Simge, göreceli uzunluk ch birimi sayesinde iki karakter boyutundadır. Bu birim, simgenin düğme metniyle orantılı olarak ölçeklenmesine yardımcı olur. Simge rengi, uyarlanabilir ve tema içinde bir renk için --_accent-color özelliğini kullanır.

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

Düğme gölgesi

Gölgelerin açık ve koyu moda doğru şekilde uyum sağlaması için hem renklerini hem de opaklıklarını değiştirmeleri gerekir. Açık tema gölgeleri, ince ve kapladıkları yüzey rengine doğru tonlandığında en iyi sonucu verir. Koyu tema gölgelerinin, daha koyu yüzey renklerinin üzerine yerleştirilebilmesi 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 hafif bir 3D görünümü vermek için 1px box-shadow özelliğiyle bu yanılsama oluşturulur:

--_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 renklerin desenini izleyerek tasarım sistemi seçeneklerini tutmak için 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

Bir seçicideki tüm özel özellikler

: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ı

-light ve -dark statik özellikler deseninin değeri, koyu tema özellikleri ayarlandığında 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 iyi bir okuma deneyimi sunmakla kalmaz, aynı zamanda bu özel düğmeleri kullanan tüketicilerin, kullanıcı tercihlerine uygun şekilde uyarlanacaklarından emin olarak temel özellikleri kullanmalarını sağlar.

İndirgenmiş hareket uyarlamaları

Bu ziyaretçi kullanıcı için hareket izleme uygunsa --_transition öğesini var(--_transition-motion-ok) öğesine 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ı tipleri, sayfanın geri kalanındaki yazı tipleriyle eşleşecek şekilde inherit olarak ayarlanmalıdır. Aksi takdirde, tarayıcı tarafından stillendirilirler. Bu durum letter-spacing için de geçerlidir. line-height ayarını 1.5 olarak belirlemek, metnin üstünde ve altında biraz boşluk bırakmak için mektup kutusu boyutunu ayarlar:

: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 sonraki düğmeleri gösteren ekran görüntüsü.

Stil düğmeleri

Seçici ayarı

Seçici input[type="file"], girişin düğme kısmı değil, sözde öğe ::file-selector-button olduğu için input[type="file"] öğesini listeden kaldırdı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 ayarlamaları

Öncelikle imleci pointer stiline göre şekillendiriyorum. Bu stil, fare kullanıcılarına düğmenin etkileşimli olduğunu belirtmeye yardımcı oluyor. Ardından, tıklamaların beklemesine ve olası bir çift tıklamayı gözlemlemesine gerek kalmaması için touch-action: manipulation ekliyorum. Böylece düğmeler daha hızlı yanıt veriyor:

: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ıklar

Ardından, daha önce oluşturulan bazı uyarlanabilir özel özellikleri kullanarak yazı tipi boyutunu, arka planı, metni ve kenarlık 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 sonraki düğmeleri gösteren ekran görüntüsü.

Gölgeler

Düğmelerde bazı harika teknikler uygulanmıştır. text-shadow, açık ve koyu renklerle uyumlu olup arka planın üzerinde hoş bir görünüm oluşturan düğme metni sağlar. box-shadow için üç gölge atanır. Birincisi, --_shadow-2, normal bir kutu gölgesidir. İkinci gölge, düğmeyi biraz eğimli göstermek için kullanılan bir göz yanıltma tekniğidir. Son gölge, fareyle üzerine gelindiğinde vurgulama içindir. Başlangıçta boyutu 0'dır ancak daha sonra boyut verilir ve düğmeden büyüyormuş gibi görünmesi için 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 sonraki düğmeleri gösteren ekran görüntüsü.

Düzen

Düğmeye flexbox düzeni verdim. Özellikle içeriğine uyacak bir inline-flex düzeni. Ardından metni ortalıyor ve çocukları dikey ve yatay olarak merkeze hizalıyorum. 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 sonraki düğmeleri gösteren ekran görüntüsü.

Boşluk

Düğme aralığı için kardeş öğelerin birbirine değmesini önlemek amacıyla gap, düğme aralığının tüm metin düzenlerinde çalışması için de dolgu olarak 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 sonraki düğmeleri gösteren ekran görüntüsü.

Dokunma ve fare kullanıcı deneyimi

Bu bölüm daha çok mobil cihazlarda dokunma özelliğini kullananlar içindir. İlk özellik olan user-select tüm kullanıcılar içindir ve düğme metninin vurgulanmasını önler. Bu durum, özellikle dokunmatik cihazlarda bir düğmeye dokunulup basılı tutulduğunda ve işletim sistemi düğme metnini vurguladığında fark edilir.

Genel olarak, yerleşik uygulamalardaki düğmelerde bu kullanıcı deneyiminin olmadığını gördüğüm için user-select değerini none olarak ayarlayarak bu özelliği devre dışı bırakıyorum. Vurgu renklerine (-webkit-tap-highlight-color) dokunma ve işletim sistemi bağlam menüleri (-webkit-touch-callout) de genel düğme kullanıcı beklentileriyle uyumlu olmayan, web odaklı diğer düğme özellikleridir. Bu nedenle bunları da 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 vurgusunun boyutunu, düğmenin içinden büyüyormuş gibi görünmesini sağlayacak şekilde ayarlayın:

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

Odaklanma sırasında, odaklanma ana hattının düğmeden uzaklığını artırarak düğmeye, içinden büyüyormuş gibi görünen hoş bir odaklanma görünümü verin:

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

Simgeler

Seçici, simgeleri işlemek için doğrudan SVG alt öğeleri veya data-icon özel özelliğine sahip öğeler için eklenmiş bir :where() seçiciye sahiptir. Simge boyutu, satır içi ve blok mantıksal özellikler kullanılarak özel özellik ile ayarlanır. Kontur rengi ve text-shadow ile eşleşecek bir drop-shadow ayarlanır. flex-shrink, 0 olarak ayarlandığından simge hiçbir zaman sıkıştırılmaz. Son olarak, çizgili simgeleri seçip fill: none ve round çizgi uçları ve çizgi birleşimleriyle bu stilleri atıyorum:

: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 sonraki düğmeleri gösteren ekran görüntüsü.

Gönder düğmelerini özelleştirme

Gönder düğmelerinin biraz daha belirgin görünmesini istiyordum. Bunu, düğmelerin metin rengini vurgu rengi yaparak sağladım:

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

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

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

Sıfırlama düğmelerinin, kullanıcıları olası yıkıcı davranışları konusunda uyarmak için bazı yerleşik uyarı işaretleri içermesini istiyordum. Ayrıca, açık tema düğmesini koyu temadan daha fazla kırmızı vurguyla şekillendirmeyi tercih ettim. Özelleştirme, uygun açık veya koyu arka plan rengi değiştirilerek 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ış çizgi renginin kırmızı vurguyla eşleşmesinin de hoş olacağını düşündüm. Metin rengi, koyu kırmızıdan açık kırmızıya dönüşür. Dış çizgi rengini, anahtar kelimeyle eşleşecek şekilde ayarlıyorum currentColor:

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

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

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

Devre dışı bırakılan düğmelerin daha az etkin görünmesi için devre dışı bırakılan düğmeyi bastırma girişimi sırasında renk kontrastının düşük olması çok yaygın bir durumdur. Her renk grubunu test ettim ve geçtiklerinden emin oldum. HSL parlaklık değerini, puan DevTools veya VisBug'da geçene kadar ayarladım.

: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 sonraki düğmeleri gösteren ekran görüntüsü.

Dosya giriş düğmelerini özelleştirme

Dosya girişi düğmesi, bir span ve bir düğme için kapsayıcıdır. CSS, giriş kapsayıcısını ve iç içe yerleştirilmiş düğmeyi biraz şekillendirebilir ancak span'i şekillendiremez. Kapsayıcıya max-inline-size değeri verildiğinden gerekenden daha büyük olmaz. inline-size: 100% ise küçülerek kendisinden küçük kapsayıcılara sığar. Arka plan rengi, diğer yüzeylerden daha koyu olan uyarlanabilir bir renge ayarlandığından 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, tarayıcı tarafından sağlanan ve diğer düğme stilleriyle geçersiz kılınmayan stilleri kaldırmak için özel olarak appearance: none verilmiştir.

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

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

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

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

Koyu temayla ilgili özel durumlar

Birincil işlem düğmelerine daha yüksek kontrastlı metin için daha koyu bir arka plan vererek biraz daha belirgin 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 sonraki düğmeleri gösteren ekran görüntüsü.

Varyant oluşturma

Eğlenceli ve pratik olduğu için birkaç varyant oluşturma yöntemini göstermeyi tercih ettim. Bir varyant, birincil düğmelerin görünümüne benzer şekilde çok canlıdır. Diğer varyant büyük. Son varyantta, renk geçişiyle doldurulmuş bir simge bulunur.

Canlı düğme

Bu düğme stilini elde etmek için temel özellikleri doğrudan mavi renklerle geçersiz kıldım. Bu yöntem hızlı ve kolay olsa da uyarlanabilir özellikler kaldırılır ve hem açık hem de koyu temada aynı görünüm elde edilir.

.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 renklerde gösterilir. Genellikle birincil işlem düğmelerinde kullanılan canlı bir mavi renktedir.

Büyük düğme

Bu düğme stili, --_size özel özelliği değiştirilerek elde edilir. Dolgu ve diğer boşluk öğeleri bu boyuta göre belirlenir ve yeni boyutla orantılı olarak ölçeklendirilir.

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

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

Simge düğmesi

Bu simge efektinin düğme stillerimizle hiçbir ilgisi yoktur ancak yalnızca birkaç CSS özelliğiyle nasıl elde edilebileceğini 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));
}

Simge içeren bir düğme, açık ve koyu temada gösteriliyor.

Sonuç

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

Yaklaşımlarımızı çeşitlendirelim ve web'de içerik oluşturmanın tüm yollarını öğrenelim.

Bir demo oluşturun, bağlantıları bana tweet atın. Ben de bu bağlantıları aşağıdaki topluluk remiksleri bölümüne ekleyeyim.

Topluluk remiksleri

Henüz burada gösterilecek bir şey yok.

Kaynaklar