Düğme bileşeni oluşturma

Renk uyarlanabilir, duyarlı ve erişilebilir <button> bileşenleri oluşturmaya ilişkin temel bir genel bakış.

Bu yayında, renge uyarlanabilir, duyarlı ve erişilebilir bir <button> öğesinin nasıl oluşturulacağıyla ilgili düşüncelerimi paylaşmak istiyorum. Demoyu deneyin ve kaynağı görüntüleyin

Açık ve koyu temalarda düğmeler, klavye ve fare aracılığıyla etkileşimde bulunur.

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

Genel bakış

Tarayıcı Desteği

  • 1
  • 12
  • 1
  • ≤4

Kaynak

<button> öğesi kullanıcı etkileşimi için oluşturulmuştur. click etkinliği klavye, fare, dokunma, ses ve daha pek çok yöntemle tetiklenir ve zamanlamayla ilgili akıllı kurallar bulunur. Ayrıca her tarayıcıda bazı varsayılan stiller bulunduğundan bunları herhangi bir özelleştirme olmadan doğrudan kullanabilirsiniz. Tarayıcı tarafından sağlanan açık ve koyu renkli düğmeleri de etkinleştirmek için color-scheme aracını kullanın.

Ayrıca, her biri önceki Codepen yerleştirmesinde gösterilen farklı düğme türleri vardır. Türü olmayan <button>, gönderme türüne geçerek <form> içinde olmaya uyarlanı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 Yarışmasında, her düğmenin amacını görsel olarak farklılaştırmasına yardımcı olacak stiller sunulacak. Sıfırlama düğmeleri, yıkıcı olduğundan uyarı renkleri içerir. Gönder düğmeleri ise normal düğmelere kıyasla biraz daha tanıtılmış olarak mavi vurgu metnine sahip olur.

Tüm düğme türlerinin son setinin, simge düğmeleri ve özelleştirilmiş düğmeler için hoş eklemelerle birlikte bir form içinde değil, bir formda gösterildiği bir önizleme.
Simge düğmeleri ve özelleştirilmiş düğmeler için hoş eklemeler içeren, formda değil de bir formda gösterilen ve tüm düğme türlerinin son grubunun önizlemesi

Düğmelerde CSS'nin stil için kullandığı sözde sınıflar da bulunur. Bu sınıflar, düğmenin dokunuşunu özelleştirmek için CSS kancaları sağlar: Düğmenin fareyle üzerine geldiğinde :hover, fare veya klavyeye basıldığında kullanmak için :active ve yardımcı teknoloji stiline yardımcı olması için :focus ya da :focus-visible.

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

Markup

HTML spesifikasyonunun sağladığı düğme türlerine ek olarak, simge içeren bir düğme ve btn-custom özel sınıfına sahip 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">

Daha sonra, her bir düğme, test amacıyla bir formun içine yerleştirilir. Bu şekilde, gönder düğmesi olarak çalışan varsayılan düğme için stillerin uygun şekilde güncellenmesini sağlayabilirim. Ayrıca, her ikisinin de eşit derecede iyi çalışmasını sağlamak için simge stratejisini satır içi SVG'den maskeli 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 bu noktada oldukça zorlayıcıdır. Düğme türleri, sözde sınıflar ve bir biçimin içinde veya dışında 20'den fazla düğme kombinasyonu bulunur. CSS'nin her birini açıkça ifade etmemize yardımcı olması güzel.

Erişilebilirlik

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

Birlikte üzerine gelin ve odaklanın

:hover ve :focus öğelerini :is() işlevsel sözde seçici ile gruplandırmayı seviyorum. Bu, arayüzlerimin her zaman klavye ve yardımcı teknoloji stillerini değerlendirmesini sağlıyor.

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

Etkileşimli odak halkası

Odak halkasını klavye ve yardımcı teknoloji kullanıcıları için canlandırmak istiyorum. Ben bunu yalnızca düğme etkin değilken düğmeden dış çizgiyi 5 piksel çevirerek yapıyorum. Bu, basıldığında odak halkasının düğme boyutuna geri küçülmesine neden olan bir efekt oluşturur.

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

Renk kontrastının geçirilmesini sağlama

Renk kontrastı açısından dikkat edilmesi gereken, açık ve koyu renklerde 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ılan düğme. Tüm puanlarını tek seferde incelemek ve göstermek için VisBug burada kullanılır:

Görmeyen kişilerden simgeler gizleniyor

Bir simge düğmesi oluştururken simge, düğme metni için görsel destek sağlamalıdır. Bu aynı zamanda simgenin, görme kaybı olan biri için değerli olmadığı anlamına da gelir. Neyse ki tarayıcı, öğeleri ekran okuyucu teknolojisinden gizleyerek görme kaybı yaşayan kişilerin dekoratif düğme resimleriyle ilgilenmelerini önleyebiliyor:

<button>
  <svg … aria-hidden="true">...</svg>
  Icon Button
</button>
Düğme için 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.
Düğme için 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, düğmenin uyarlanabilir stillerini yönetmek için özel bir özellik sistemi kuracağım. Bu özel özelliklerle öğeleri seçmeye ve görünümlerini özelleştirmeye başlayabilirim.

Uyarlanabilir özel mülk stratejisi

Bu GUI Meydan Okuması'nda kullanılan özel mülk stratejisi, renk şeması oluşturmak için kullanılan stratejiye çok benzer. Uyarlanabilir açık ve koyu renk sisteminde, her tema için özel bir özellik tanımlanır ve buna göre adlandırılır. Daha sonra temanın mevcut değerini barındırmak için tek bir özel özellik kullanılır ve bir CSS mülküne 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);
  }
}

En sevdiğim yanı, açık ve koyu temaların açıklayıcı ve net olmasıdır. Dolaylı ve soyutlama, artık tek "reaktif" özellik olan --_bg özel özelliğine aktarılır; --_bg-light ve --_bg-dark ise 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ığı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 başta biraz kafa karıştırıcıdır. :where() kullanıldığı için düğmenin özelleştirilmesi belirli bir durum gerektirmez. Düğmeler genellikle alternatif senaryolara uyarlanır ve :where() seçici, görevlerin kolay olmasını sağlar. :where() içinde, her bir düğme türü seçilir. ::file-selector-button düğmesi de dahil olmak üzere, :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 içinde yer alır. Şimdi tüm özel özellikleri inceleyin. Bu düğmede kullanılan birçok özel özellik vardır. Her bir grubu ilerledikçe anlatacağım, sonra da bölümün sonunda karanlık ve azaltılmış bağlamları paylaşacağım.

Düğme vurgu rengi

Gönder düğmeleri ve simgeleri, kendinizi daha iyi göstermek için harika bir yerdir:

--_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 ve 210 tonuna bağlı olarak --_accent ürününün daha koyu veya açık renkli versiyonları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 dışında aynı hsl() desenini izler. Bu düğmeler, yüzeylerinin kullanıcıya yakın bir yerde veya diğer yüzeylerin önünde görünmesini sağlamak için beyaza ayarlanır:

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

Düğme arka planı iyi durumda

Bu arka plan rengi, bir yüzeyin diğer yüzeylerin arkasında görünmesini sağlamak içindir ve dosya girişinin arka planı açısından 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 boyutuyla göreli bir uzunluk olan ch birimi kullanılarak yapılır. Bu durum, büyük düğmeler font-size ve düğme ölçeğini orantılı olarak artırabildiğinde kritik hale gelir:

--_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 özellikte saklanıyor. Kenarlık renkleri, yerleşik uyarlanabilir renk sistemine uyar:

--_border-radius: .5ch;

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

Düğmenin fareyle üzerine gelindiğinde vurgulama efekti

Bu özellikler, etkileşim üzerine geçiş için bir boyut özelliği oluşturur ve vurgu rengi uyarlanabilir renk sistemini izler. Bunların nasıl etkileşime geçtiğini bu yazının ilerleyen bölümlerinde ele alacağız. Ancak son olarak, bunların box-shadow etkisi için kullanılması:

--_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, metnin düğmenin üzerine yerleştirilmesine yardımcı olarak okunabilirliği iyileştirir ve sunuma güzel bir zenginlik katar.

--_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 büyüklüğünde olur. Bu da simgenin düğme metniyle orantılı olarak ölçeklenmesine yardımcı olur. Simge rengi, uyarlanabilir ve tema içi renk için --_accent-color üzerinde etkili olur.

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

Düğme gölgesi

Gölgelerin ışığa ve koyuluğa düzgün bir şekilde uyum sağlaması için hem renklerini hem de opaklıklarını değiştirmeleri gerekir. Açık tema gölgeleri, üzerine bindirilen yüzey rengine doğru incelikli ve tonlamalı olmaları durumunda en iyi sonucu verir. Yüzey renklerinin daha koyu renkli olması için koyu tema gölgelerinin 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 güçlü özelliklerle iki derin gölge 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 bir görünüm vermek için 1px kutu gölgesi illüzyon oluşturur:

--_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 renk desenini izleyerek, tasarım sistemi seçeneklerini saptamak için iki statik özellik oluştururum:

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

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 özellikleri ayarlandığında -light ve -dark statik özellik deseninin 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 hem yazıları iyi okuyor hem de bu özel düğmeleri kullananlar, kullanıcı tercihlerine uyum sağlayacaklarından emin bir şekilde çıplak öğeleri kullanabiliyor.

Azaltılmış hareket uyarlamaları

Ziyaret eden bu kullanıcı için hareket uygunsa --_transition özelliğini var(--_transition-motion-ok) adlı kullanıcıya 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şecek şekilde inherit değerine ayarlanması gerekir. Aksi takdirde stil tarayıcı tarafından belirlenir. Bu, letter-spacing için de geçerlidir. line-height değerini 1.5 olarak ayarlamak, metne yukarıda ve altında biraz boşluk bırakmak için sinemaskop 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ü.

Düğmelerin stil özelliklerini ayarlama

Seçici düzenlemesi

input[type="file"] seçicisi, girişin düğme parçası olmadığı için ::file-selector-button sözde öğesi olduğu için listeden input[type="file"] öğesini çı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 ayarları

İlk olarak imleci, pointer stiline göre biçimlendiriyorum. Bu stil, düğmenin fare kullanıcılarına etkileşimli olduğunu belirtmesine yardımcı olur. Daha sonra, tıklamaların beklemek ve olası bir çift tıklamayı gözlemlemek zorunda kalmamasını sağlamak için touch-action: manipulation ekliyorum. Böylece düğmeler daha hızlı görünür:

: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şturduğumuz uyarlanabilir özel özelliklerden bazılarını kullanarak yazı tipi boyutunu, arka plan, metin 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üğmelere harika teknikler uygulanmıştır. text-shadow açık ve koyu renklere uyarlanabilir. Bu sayede, arka planın üzerinde güzel bir şekilde duran düğme metninin hoş ve hoş bir görünümünü oluşturur. box-shadow için üç gölge atanır. Birincisi (--_shadow-2), normal bir kutu gölgesidir. İkinci gölge, düğmenin biraz yukarıdaymış gibi görünmesini sağlayan, göze çarpmayan bir gölgedir. Son gölge, başlangıçta 0 boyutunda olacak şekilde fareyle üzerine gelme vurgulama içindir, ancak daha sonra bir boyut verilecek ve düğmeden büyüyeceği için geçişi yapılacaktı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 bir flexbox düzeni, özellikle de içeriğine uyacak bir inline-flex düzeni verdim. Daha sonra, metni ortalıyorum ve alt öğeleri dikey ve yatay olarak ortaya hizalıyorum. Bu, simgelerin ve diğer düğme öğelerinin düzgün bir şekilde hizalanmasına yardımcı olur.

: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ıklarında, kardeş öğelerin dokunmasını engellemek için gap ve dolgu için mantıksal özellikleri kullandım. Böylece düğme aralığı tüm metin düzenlerinde çalışır.

: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 sonraki bölüm çoğunlukla mobil cihazlarda dokunmatik kullanıcılar içindir. İlk user-select özelliği tüm kullanıcılar içindir; düğme metnini vurgulayan metinler olmasını engeller. Bu durum, genellikle dokunmatik cihazlarda bir düğmeye dokunup basılı tutulduğunda ve işletim sistemi düğme metnini vurguladığında fark edilebilir.

Genellikle bunun yerleşik uygulamalardaki düğmelerle ilgili kullanıcı deneyimi olmadığını anladım. Bu yüzden, user-select öğesini yok şeklinde ayarlayarak devre dışı bırakıyorum. Vurgu renklerine dokunun (-webkit-tap-highlight-color) ve işletim sistemi içerik menüleri (-webkit-touch-callout) Genel düğmelerin kullanıcı beklentileriyle pek uyumlu olmayan web merkezli diğer düğme özellikleridir. Bu nedenle düğmelerin kullanımıyla tam olarak uyuşmayan diğer düğme özellikleridir.

: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 bastırmadığında, fareyle üzerine gelindiğinde düğmenin içinden çıkacak hoş bir odak görünümü sağlamak için gölge vurgu boyutunu ayarlayın:

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

Odaklanıldığında, odak dış çizgisinin düğmeden uzaklığını artırın. Bu sayede, düğmenin içinden güzel bir odak görünümü de elde edebilirsiniz.

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

Simgeler

Simgeleri işleme açısından, seçicide doğrudan SVG alt öğeleri veya data-icon özel özelliğine sahip öğeler için ek bir :where() seçici bulunur. Simge boyutu, satır içi ve blok mantıksal özellikleri kullanılarak özel özellikle ayarlanır. Fırça rengi ve text-shadow ile eşleşecek bir drop-shadow ayarlandı. flex-shrink, 0 olarak ayarlandığından simge hiçbir zaman sıkıştırılmaz. Son olarak, çizgili simgeleri seçiyorum ve burada bu stilleri fill: none ve round satır sınırları ve çizgi birleşimleriyle 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 öne çıkan bir görünüme sahip olmasını istedim. Bunu, düğmelerin metin rengini vurgu rengi yaparak başlattı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ştir

Sıfırlama düğmelerinde kullanıcıları, yıkıcı olabilecek davranışlarına karşı uyaracak yerleşik uyarı işaretleri bulundurmak istiyordum. Ayrıca açık tema düğmesini, koyu temadan daha çok kırmızı vurgularla şekillendirmeyi seçtim. Özelleştirme, uygun açık veya koyu temel rengin değiştirilmesiyle 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 noktasının dış çizgisinin kırmızı vurgusuyla eşleşmesinin de güzel olacağını düşündüm. Metin rengi, koyu kırmızıyı açık kırmızıya dönüştürür. Dış çizgi renginin currentColor anahtar kelimesiyle eşleşmesini sağlıyorum:

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

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

Devre dışı düğmeleri özelleştirin

Devre dışı bırakılan düğmelerin etkisini azaltarak düğmenin daha az etkin görünmesi için devre dışı bırakılan düğmelerin renk kontrastının zayıf olması sık karşılaşılan bir durumdur. Her bir renk grubunu test ettim ve Geliştirici Araçları veya VisBug'da geçen puana kadar HSL açıklık değerini döndürerek başarılı olduklarından 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 sonraki düğmeleri gösteren ekran görüntüsü.

Dosya giriş düğmelerini özelleştirme

Dosya giriş düğmesi, bir yayılma alanı ve düğme için bir kapsayıcıdır. CSS, giriş kapsayıcısını ve iç içe düğmeyi biraz biçimlendirebilir, ancak kapsamı biraz farklı kılacaktır. Kapsayıcıya max-inline-size verilir ve bu nedenle olması gerekenden daha büyük olmaz. Ancak inline-size: 100%, kapsayıcıları olduğundan daha küçük şekilde küçültüp sığdırmasına izin verir. Arka plan rengi, diğer yüzeylerden daha koyu olan uyarlanabilir bir renge ayarlandığında dosya seçici düğmesinin arkasına bakar.

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

Diğer düğme stilleri tarafından üzerine yazılmayan, tarayıcı tarafından sağlanan stillerin kaldırılması için dosya seçici düğmesi ve giriş türü düğmelerine özel olarak appearance: none verilmiştir.

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

Son olarak, kapsam metnini düğmeden uzağa itmek için düğmenin inline-end öğesine 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ü.

Özel koyu tema istisnaları

Yüksek kontrastlı metin için birincil işlem düğmelerine daha koyu bir arka plan verdim. Böylece biraz daha tanıtılmış bir görünüm elde ettim.

@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ğlenmek için ve pratik olduğu için birkaç varyantın nasıl oluşturulacağını göstermeyi seçtim. Varyantlardan biri, birincil düğmelerin genellikle görünmesine benzeyen çok canlı. Başka bir varyant büyük. Son varyant, gradyanla dolu bir simgeye sahiptir.

Canlı düğme

Bu düğme stilini elde etmek için taban malzemelerin üzerine doğrudan mavi renkleri yazdım. Bu işlem hızlı ve kolay bir işlem olsa da uyarlanabilir sahne unsurlarını kaldırıyor ve hem açık hem de koyu temalarda aynı görünüyor.

.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üğmeleri gibi çok canlı mavidir.

Büyük düğme

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

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

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

Simge düğmesi

Bu simge efektinin düğme stillerimizle hiçbir ilgisi yoktur, ancak bunu yalnızca birkaç CSS özelliğiyle nasıl uygulayacağınızı ve düğmenin satır içi SVG olmayan simgeleri ne kadar iyi işlediğini göstermektedir.

[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österiliyor.

Sonuç

Nasıl yaptığımı artık bildiğine göre siz de nasıl yapardınız? 🙂

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

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

Topluluk remiksleri

Henüz burada görülecek bir şey yok.

Kaynaklar