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.
  • Kenar: 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 etkinleştirmek için color-scheme düğmesini de kullanabilirsiniz.

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üğmeye, amaçların görsel olarak ayırt edilmesine yardımcı olacak stiller sunulacaktır. 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 şekilde, stillerin gönder düğmesi gibi çalışan varsayılan düğme için 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 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 iyileştirme vardır.

Fareyle üzerine gelme ve odaklanma

:hover ve :focus öğelerini :is() işlevsel sözde seçicisiyle birlikte gruplandırmayı seviyorum. 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ı

Odak halkasını klavye ve yardımcı teknoloji kullanıcıları için animasyonla göstermek 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 değerli 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 özelliklerle öğ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. Daha sonra temanın geçerli değerini korumak için tek bir özel mülk kullanılır ve bu mülk bir CSS mülküne 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. Ayrıca, açık temanın varsayılan tema olduğu ve koyu temanın yalnızca koşullu olarak uygulandığı da açıktır.

Tasarım tutarlılığı için hazırlık

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 her düğme türü seçilir. Bu düğme türü :is() veya :where() içinde kullanılamayan ::file-selector-button dahil.

: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

Açık tema düğmeleri dışında, düğme arka planları aynı hsl() desenini izler. Düğmeler beyaz olarak ayarlandığı için yüzeyleri kullanıcıya yakın veya diğer yüzeylerin önünde görünü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 kenarlığı

Düğme kenarlık yarıçapı, dosya girişinin diğer düğmelerle eşleşebilmesi için özel bir özelliğe sabitlenir. 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 etkileşimlerin nasıl işlediğini bu yayının ilerleyen kısımlarında ele alacağız, ancak nihai olarak bunlar 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 metni gölgesi

Her düğmenin ince bir metin gölgesi stili vardır. Bu şekilde metin düğmenin üzerinde olacak, daha rahat okunacak ve sunumun daha güzel görünmesini sağlar.

--_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 koyu renklere uygun şekilde uyum sağlaması için hem renk hem de opaklıklarını değiştirmesi 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, daha koyu yüzey renklerini üst üste bindirebilmesi 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 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

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ı

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);
  }
}

Böylece hem yazıları iyi okuyabilirler hem de bu özel düğmeleri kullananlar, kullanıcı tercihlerine uygun olacaklarından emin olmak için çıplak donanımları güvenle kullanabilir.

Azaltılmış hareket adaptasyonları

Ziyaret eden bu kullanıcı harekette değilse var(--_transition-motion-ok) kullanıcısına --_transition 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, sayfa yazı tiplerinin geri kalanıyla eşleşmesi için inherit olarak ayarlanması gerekir. Aksi takdirde, stil özellikleri tarayıcı tarafından belirlenir. 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 ayarlaması

input[type="file"] seçicisi girişin düğme parçası değil, ::file-selector-button sözde öğesidir. Bu nedenle input[type="file"] öğesini 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üğmelere bazı etkili 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 gelme vurgulaması içindir. Başlangıçta 0 boyutundadır, ancak daha sonra bir boyut verilir ve düğmeden büyüyecek şekilde geçiş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. Daha sonra metni ortalıyorum ve alt öğeleri ortaya dikey ve yatay olarak 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 sonra düğmeleri gösteren ekran görüntüsü.

Boşluk

Düğme aralığı için, kardeşlerin birbirine dokunmasını ö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 düğmenin içinden büyüyormuş gibi görünen güzel bir odaklanma görünümü verecek şekilde ayarlayın:

: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, simgeleri işlemek için doğrudan SVG alt öğeleri veya data-icon özel özelliğine sahip öğeler için ek bir :where() seçiciye 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ştir

Sıfırlama düğmelerinde, kullanıcıları olası zarar verici davranışları konusunda uyaracak yerleşik uyarı işaretleri bulunmasını istiyordum. Ayrıca, açık tema düğmesi için koyu temadan daha fazla kırmızı vurgu stili seçmeyi tercih ettim. Özelleştirme, alttaki uygun açık veya koyu renk 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ış ç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ış çizgi rengini currentColor anahtar kelimesiyle eşleştiriyorum:

: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 başarılı olduklarını gördük.

: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

Hem eğlenmek hem de pratik olması için birkaç varyant oluşturmayı göstermeyi seçtim. Bir varyant, genellikle birincil düğmelerinkine benzer şekilde çok canlıdır. Başka bir varyant büyük. 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? 🙂

Gelin, yaklaşımlarımızı çeşitlendirelim ve web'de içerik 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