A foundational overview of how to build color-adaptive, responsive, and accessible <button>
components.
در این پست میخواهم نظرات خود را در مورد نحوه ساخت یک عنصر <button>
سازگار با رنگ، پاسخگو و قابل دسترسی به اشتراک بگذارم. نسخه ی نمایشی را امتحان کنید و منبع را مشاهده کنید
اگر ویدیو را ترجیح می دهید، در اینجا یک نسخه YouTube از این پست وجود دارد:
نمای کلی
عنصر <button>
برای تعامل با کاربر ساخته شده است. رویداد click
آن از صفحه کلید، ماوس، لمس، صدا و موارد دیگر با قوانین هوشمند در مورد زمانبندی آن آغاز میشود. همچنین دارای برخی از سبک های پیش فرض در هر مرورگر است، بنابراین می توانید مستقیماً بدون هیچ گونه سفارشی سازی از آنها استفاده کنید. از color-scheme
برای انتخاب دکمه های روشن و تیره ارائه شده توسط مرورگر نیز استفاده کنید.
همچنین انواع مختلفی از دکمه ها وجود دارد که هر کدام در کدپن قبلی نشان داده شده اند. یک <button>
بدون نوع با قرار گرفتن در یک <form>
سازگار می شود و به نوع ارسال تغییر می کند.
<!-- 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">
در چالش رابط کاربری گرافیکی این ماه، هر دکمه دارای سبکهایی است که به تمایز بصری هدفشان کمک میکند. دکمههای بازنشانی دارای رنگهای هشداردهنده هستند زیرا مخرب هستند، و دکمههای ارسال متن لهجه آبی را دریافت میکنند تا کمی بیشتر از دکمههای معمولی تبلیغ شوند.
دکمهها همچنین دارای کلاسهای شبه برای CSS هستند که برای استایلسازی استفاده میشود. These classes provide CSS hooks into customizing the feel of the button: :hover
for when a mouse is over the button, :active
for when a mouse or keyboard is pressing, and :focus
or :focus-visible
for assisting in assistive technology styling.
button:hover {}
button:active {}
button:focus {}
button:focus-visible {}
نشانه گذاری
علاوه بر انواع دکمه های ارائه شده توسط مشخصات HTML، یک دکمه با یک نماد و یک دکمه با کلاس سفارشی btn-custom
اضافه کرده ام.
<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">
سپس برای تست، هر دکمه در داخل یک فرم قرار می گیرد. به این ترتیب میتوانم مطمئن شوم که استایلها بهطور مناسب برای دکمه پیشفرض بهروزرسانی میشوند، که مانند یک دکمه ارسال عمل میکند. من همچنین استراتژی نماد را از SVG درون خطی به SVG ماسک شده تغییر میدهم تا مطمئن شوم که هر دو به یک اندازه خوب کار میکنند.
<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>
ماتریس ترکیبات در این مرحله بسیار زیاد است. بین انواع دکمهها، شبه کلاسها و قرار گرفتن در یک فرم یا خارج از آن، بیش از 20 ترکیب از دکمهها وجود دارد. این چیز خوبی است که CSS می تواند به ما کمک کند تا هر یک از آنها را به وضوح بیان کنیم!
دسترسی
عناصر دکمه به طور طبیعی در دسترس هستند اما چند پیشرفت رایج وجود دارد.
ماوس را نگه دارید و با هم فوکوس کنید
من دوست دارم :hover
و :focus
با انتخابگر شبه عملکردی :is()
گروه بندی کنم. این کمک می کند تا اطمینان حاصل کنم که رابط های من همیشه سبک های صفحه کلید و فناوری کمکی را در نظر می گیرند.
button:is(:hover, :focus) {
…
}
حلقه فوکوس تعاملی
من دوست دارم حلقه فوکوس را برای کاربران صفحه کلید و فناوری کمکی متحرک کنم. من این کار را با متحرک کردن طرح کلی از دکمه به میزان 5 پیکسل انجام می دهم، اما فقط زمانی که دکمه فعال نیست. این یک جلوه ایجاد می کند که باعث می شود حلقه فوکوس با فشار دادن به اندازه دکمه کوچک شود.
:where(button, input):where(:not(:active)):focus-visible {
outline-offset: 5px;
}
تضمین کنتراست رنگی گذرا
حداقل چهار ترکیب رنگ مختلف در روشن و تاریک وجود دارد که باید کنتراست رنگ را در نظر گرفت: دکمه، دکمه ارسال، دکمه تنظیم مجدد و دکمه غیرفعال. VisBug در اینجا برای بررسی و نمایش تمام امتیازات آنها به طور همزمان استفاده می شود:
پنهان کردن نمادها از افرادی که نمی توانند ببینند
هنگام ایجاد یک دکمه نماد، آیکون باید پشتیبانی بصری از متن دکمه ارائه دهد. این همچنین به این معنی است که نماد برای کسی که بینایی دارد ارزشمند نیست. خوشبختانه مرورگر راهی برای مخفی کردن موارد از فناوری صفحهخوان ارائه میکند تا افرادی که بینایی خود را از دست دادهاند با تصاویر دکمههای تزئینی اذیت نشوند:
<button>
<svg … aria-hidden="true">...</svg>
Icon Button
</button>
سبک ها
در این بخش بعدی، ابتدا یک سیستم ویژگی سفارشی برای مدیریت سبک های تطبیقی دکمه ایجاد می کنم. با آن ویژگی های سفارشی می توانم شروع به انتخاب عناصر و سفارشی کردن ظاهر آنها کنم.
یک استراتژی دارایی سفارشی تطبیقی
استراتژی ویژگی سفارشی مورد استفاده در این چالش رابط کاربری گرافیکی بسیار شبیه به استراتژی مورد استفاده در ساخت یک طرح رنگ است. برای یک سیستم رنگ روشن و تیره تطبیقی، یک ویژگی سفارشی برای هر تم تعریف و نامگذاری می شود. سپس یک ویژگی سفارشی برای نگهداری مقدار فعلی موضوع استفاده می شود و به یک ویژگی CSS اختصاص داده می شود. بعداً، ویژگی سفارشی منفرد را می توان به مقدار دیگری به روز کرد، سپس سبک دکمه را به روز کرد.
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);
}
}
چیزی که من دوست دارم این است که مضامین روشن و تاریک بیانی و واضح هستند. The indirection and abstraction are offloaded into the --_bg
custom property, which is now the only "reactive" property; --_bg-light
و --_bg-dark
ثابت هستند. همچنین خواندن این موضوع واضح است که تم روشن، تم پیشفرض است و تاریک فقط به صورت مشروط اعمال میشود.
آماده شدن برای سازگاری طراحی
انتخابگر مشترک
انتخابگر زیر برای هدف قرار دادن انواع مختلف دکمه ها استفاده می شود و در ابتدا کمی طاقت فرسا است. :where()
استفاده می شود، بنابراین سفارشی کردن دکمه نیازی به هیچ خاصیت خاصی ندارد. دکمه ها اغلب برای سناریوهای جایگزین تطبیق داده می شوند و انتخابگر :where()
تضمین می کند که این کار آسان است. در داخل :where()
هر نوع دکمه انتخاب می شود، از جمله دکمه ::file-selector-button
که نمی تواند در داخل :is()
یا :where()
استفاده شود.
: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);
رنگ متن دکمه
رنگهای متن دکمهها سفید یا سیاه نیستند، آنها نسخههای تیره یا روشنشده --_accent
با استفاده از hsl()
و چسبیدن به hue 210
هستند:
--_text-light: hsl(210 10% 30%);
--_text-dark: hsl(210 5% 95%);
--_text: var(--_text-light);
رنگ پس زمینه دکمه
پسزمینههای دکمهها از الگوی hsl()
یکسانی پیروی میکنند، به جز دکمههای تم روشن – این دکمهها روی سفید تنظیم شدهاند تا سطح آنها نزدیک به کاربر یا در مقابل سطوح دیگر ظاهر شوند:
--_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);
بالشتک دکمه ای
فاصله گذاری در اطراف متن در دکمه با استفاده از واحد ch
انجام می شود، طول نسبی به اندازه فونت. زمانی که دکمههای بزرگ میتوانند font-size
و مقیاسهای دکمهها را به طور متناسب افزایش دهند، بسیار مهم میشود:
--_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);
جلوه هایلایت شناور دکمه
این ویژگی ها یک ویژگی اندازه برای انتقال در تعامل ایجاد می کنند و رنگ برجسته از سیستم رنگ تطبیقی پیروی می کند. نحوه تعامل اینها را بعداً در این پست پوشش خواهیم داد، اما در نهایت از اینها برای جلوه box-shadow
استفاده می شود:
--_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 var(--_border-light);
--_ink-shadow-dark: 0 1px 0 hsl(210 11% 15%);
--_ink-shadow: var(--_ink-shadow-light);
نماد دکمه
آیکون ها به لطف واحد طول نسبی ch
دوباره به اندازه دو کاراکتر هستند که به مقیاس آیکون متناسب با متن دکمه کمک می کند. رنگ نماد به --_accent-color
برای یک رنگ تطبیقی و درون تم تکیه دارد.
--_icon-size: 2ch;
--_icon-color: var(--_accent);
سایه دکمه
برای اینکه سایه ها به خوبی با نور و تاریکی سازگار شوند، باید رنگ و کدورت خود را تغییر دهند. سایههای تم روشن زمانی بهترین هستند که ظریف باشند و به سمت رنگ سطحی که روی آن قرار میگیرند، رنگآمیزی داشته باشند. سایههای تم تیره باید تیرهتر و اشباعتر باشند تا بتوانند رنگهای سطح تیرهتر را پوشش دهند.
--_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%));
علاوه بر این، برای اینکه دکمه ها ظاهری سه بعدی داشته باشند، یک کادر سایه 1px
این توهم را ایجاد می کند:
--_shadow-depth-light: 0 1px var(--_border-light);
--_shadow-depth-dark: 0 1px 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);
همه خواص با هم در انتخابگر
: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); }
اقتباس از تم تاریک
ارزش الگوی پایههای استاتیک -light
و -dark
زمانی مشخص میشود که پایههای تم تیره تنظیم شوند:
@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);
}
}
این نه تنها به خوبی خوانده میشود، بلکه مصرفکنندگان این دکمههای سفارشی میتوانند با اطمینان از تطبیق مناسب با اولویتهای کاربر، از لوازم خالی استفاده کنند.
کاهش سازگاری حرکتی
اگر حرکت با این کاربر بازدیدکننده خوب است، --_transition
به var(--_transition-motion-ok)
اختصاص دهید:
@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);
}
}
چند سبک مشترک
دکمهها و ورودیها باید فونتهایشان را برای inherit
تنظیم کنند تا با بقیه فونتهای صفحه مطابقت داشته باشند. در غیر این صورت آنها توسط مرورگر استایل می شوند. این در مورد letter-spacing
نیز صدق می کند. با تنظیم line-height
روی 1.5
اندازه کادر حروف را تنظیم میکند تا به متن کمی فاصله در بالا و پایین بدهد:
: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);
}
دکمه های یک ظاهر طراحی شده
تنظیم انتخابگر
input[type="file"]
بخش دکمه ورودی نیست، شبه عنصر ::file-selector-button
است، بنابراین من input[type="file"]
از لیست حذف کردم:
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"],
input[type="file"]
),
:where(input[type="file"])::file-selector-button {
}
تنظیمات مکان نما و لمس
ابتدا مکان نما را به سبک pointer
استایل می دهم، که به دکمه کمک می کند تا به کاربران ماوس نشان دهد که تعاملی است. سپس touch-action: manipulation
برای اینکه کلیکها نیازی به صبر کردن و مشاهده یک کلیک دوبار بالقوه نداشته باشید، که باعث میشود دکمهها سریعتر احساس شوند:
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
cursor: pointer;
touch-action: manipulation;
}
رنگ ها و حاشیه ها
سپس اندازه فونت، پسزمینه، متن و رنگهای حاشیه را با استفاده از برخی از ویژگیهای سفارشی تطبیقی که قبلاً ایجاد شدهاند، سفارشی میکنم:
: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);
}
سایه ها
دکمه ها دارای تکنیک های بسیار خوبی هستند. text-shadow
با نور و تاریکی سازگار است و ظاهر ظریف دلپذیری از متن دکمه که به خوبی در بالای پسزمینه قرار دارد ایجاد میکند. برای box-shadow
، سه سایه اختصاص داده شده است. اولی، --_shadow-2
، یک سایه جعبه معمولی است. سایه دوم ترفندی برای چشم است که باعث می شود دکمه کمی به سمت بالا به نظر برسد. آخرین سایه برای هایلایت شناور است، در ابتدا با اندازه 0، اما بعداً اندازه ای به آن داده می شود و تغییر می کند تا به نظر برسد که از دکمه بزرگ می شود.
: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);
}
طرح بندی
من به دکمه یک طرح فلکس باکس دادم، به ویژه یک طرح بندی inline-flex
که با محتوای آن مطابقت دارد. سپس متن را در مرکز قرار می دهم و کودکان را به صورت عمودی و افقی در مرکز قرار می دهم. این به آیکون ها و سایر عناصر دکمه کمک می کند تا به درستی تراز شوند.
: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;
}
فاصله گذاری
برای فاصله بین دکمهها، gap
برای جلوگیری از لمس خواهر و برادر و ویژگیهای منطقی برای لایهبندی استفاده کردم، بنابراین فاصله دکمهها برای همه طرحبندیهای متن کار میکند.
: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);
}
UX لمس و ماوس
این بخش بعدی بیشتر برای کاربران لمسی در دستگاه های تلفن همراه است. اولین ویژگی، user-select
، برای همه کاربران است. از برجسته کردن متن روی متن دکمه جلوگیری می کند. این بیشتر در دستگاه های لمسی زمانی قابل توجه است که دکمه ای را فشار داده و نگه دارید و سیستم عامل متن دکمه را برجسته می کند.
من به طور کلی دریافتم که این تجربه کاربری با دکمهها در برنامههای داخلی نیست، بنابراین با تنظیم user-select
روی هیچ، آن را غیرفعال میکنم. رنگهای برجسته ضربه بزنید ( -webkit-tap-highlight-color
) و منوهای زمینه سیستم عامل ( -webkit-touch-callout
) دیگر ویژگیهای دکمههای بسیار وب محور هستند که با انتظارات کاربر دکمههای عمومی همسو نیستند، بنابراین آنها را به عنوان حذف میکنم. خوب
: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;
}
انتقال ها
متغیر تطبیقی --_transition
به ویژگی transition اختصاص داده می شود:
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
…
transition: var(--_transition);
}
پس از شناور، در حالی که کاربر به طور فعال فشار نمی دهد، اندازه برجسته سایه را تنظیم کنید تا ظاهر فوکوس خوبی به آن ببخشید که به نظر می رسد از داخل دکمه رشد می کند:
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
):where(:not(:active):hover) {
--_highlight-size: .5rem;
}
پس از فوکوس، افست خطوط فوکوس را از روی دکمه افزایش دهید، همچنین ظاهر فوکوس خوبی به آن می دهید که به نظر می رسد از داخل دکمه رشد می کند:
:where(button, input):where(:not(:active)):focus-visible {
outline-offset: 5px;
}
نمادها
برای مدیریت نمادها، انتخابگر یک انتخابگر :where()
برای فرزندان مستقیم SVG یا عناصر با ویژگی سفارشی data-icon
دارد. اندازه نماد با ویژگی سفارشی با استفاده از خصوصیات منطقی درون خطی و بلوک تنظیم می شود. رنگ Stroke تنظیم شده است، و همچنین یک drop-shadow
برای مطابقت با text-shadow
تنظیم شده است. flex-shrink
روی 0
تنظیم شده است، بنابراین نماد هرگز فشرده نمی شود. در نهایت، نمادهای خطدار را انتخاب میکنم و آن سبکها را در اینجا با fill: none
و سرپوشهای خط round
و پیوندهای خط اختصاص میدهم:
: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;
}
سفارشی کردن دکمه های ارسال
من میخواستم دکمههای ارسال کمی ظاهری ارتقا یافته داشته باشند، و با تبدیل کردن رنگ متن دکمهها به رنگ تاکیدی به این امر دست یافتم:
:where(
[type="submit"],
form button:not([type],[disabled])
) {
--_text: var(--_accent);
}
دکمه های تنظیم مجدد را سفارشی کنید
من میخواستم دکمههای تنظیم مجدد چند علامت هشدار داخلی داشته باشند تا کاربران را از رفتار مخرب بالقوه آنها آگاه کند. من همچنین انتخاب کردم که دکمه تم روشن را با لهجه های قرمز بیشتری نسبت به تم تیره انتخاب کنم. سفارشیسازی با تغییر رنگ زیر روشن یا تیره مناسب انجام میشود و دکمه سبک را بهروزرسانی میکند:
: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%);
}
من همچنین فکر کردم که خوب است رنگ طرح فوکوس با لهجه قرمز مطابقت داشته باشد. رنگ متن قرمز تیره را با قرمز روشن تطبیق می دهد. من رنگ طرح کلی را با کلمه کلیدی currentColor
مطابقت می دهم:
:where([type="reset"]):focus-visible {
outline-color: currentColor;
}
دکمه های غیرفعال را سفارشی کنید
بسیار معمول است که دکمههای غیرفعال کنتراست رنگی ضعیفی در طول تلاش برای مهار کردن دکمه غیرفعال داشته باشند، بنابراین کمتر فعال به نظر میرسد. من هر مجموعه رنگی را آزمایش کردم و مطمئن شدم که آنها قبول میشوند، و مقدار سبکی HSL را تا زمانی که امتیاز در DevTools یا VisBug تصویب شود، نشان دادم.
: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);
}
سفارشی کردن دکمه های ورودی فایل
دکمه ورودی فایل یک ظرف برای یک دهانه و یک دکمه است. CSS می تواند به محفظه ورودی و همچنین دکمه تو در تو استایل دهد، اما نه به دهانه. The container is given max-inline-size
so it won't grow larger than it needs to, while inline-size: 100%
will allow itself to shrink and fit containers smaller than it is. رنگ پسزمینه روی رنگی تطبیقی تنظیم میشود که تیرهتر از سطوح دیگر است، بنابراین پشت دکمه انتخابگر فایل به نظر میرسد.
:where(input[type="file"]) {
inline-size: 100%;
max-inline-size: max-content;
background-color: var(--_input-well);
}
دکمه انتخاب فایل و دکمههای نوع ورودی بهطور خاص appearance: none
برای حذف سبکهای ارائهشده توسط مرورگر که توسط دیگر سبکهای دکمه بازنویسی نشدهاند، وجود ندارد.
:where(input[type="button"]),
:where(input[type="file"])::file-selector-button {
appearance: none;
}
در نهایت، حاشیه به inline-end
دکمه اضافه می شود تا متن دهانه از دکمه دور شود و مقداری فضا ایجاد شود.
:where(input[type="file"])::file-selector-button {
margin-inline-end: var(--_padding-inline);
}
استثناهای تم تاریک ویژه
من به دکمههای اکشن اولیه پسزمینه تیرهتری برای متنهای با کنتراست بالاتر دادم و ظاهری کمی بیشتر به آنها دادم.
@media (prefers-color-scheme: dark) {
:where(
[type="submit"],
[type="reset"],
[disabled],
form button:not([type="button"])
) {
--_bg: var(--_input-well);
}
}
ایجاد انواع
برای سرگرمی، و به دلیل کاربردی بودن، تصمیم گرفتم نشان دهم که چگونه می توان چند نوع آن را ایجاد کرد. یکی از انواع بسیار پر جنب و جوش است، شبیه به ظاهر دکمه های اصلی. یک نوع دیگر بزرگ است. آخرین نوع دارای یک نماد پر از گرادیان است.
دکمه پر جنب و جوش
برای دستیابی به این سبک دکمه، پایههای پایه را مستقیماً با رنگهای آبی بازنویسی کردم. در حالی که این سریع و آسان بود، لوازم تطبیقی را حذف می کند و در تم های روشن و تاریک یکسان به نظر می رسد.
.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%);
}
دکمه بزرگ
این سبک از دکمه با تغییر ویژگی سفارشی --_size
به دست می آید. بالشتک و سایر عناصر فضایی نسبت به این اندازه هستند و متناسب با اندازه جدید مقیاس می شوند.
.btn-large {
--_size: 1.5rem;
}
دکمه آیکون
این افکت آیکون ربطی به سبک دکمههای ما ندارد، اما نشان میدهد که چگونه میتوان آن را تنها با چند ویژگی CSS به دست آورد، و چگونه دکمهها آیکونهایی را که SVG درون خطی نیستند، کنترل میکند.
[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));
}
نتیجه گیری
حالا که می دانید من چگونه این کار را انجام دادم، چگونه این کار را انجام می دهید‽🙂
بیایید رویکردهایمان را متنوع کنیم و همه راههای ساخت در وب را بیاموزیم.
یک نسخه نمایشی ایجاد کنید، پیوندها را برای من توییت کنید ، و من آن را به بخش ریمیکس های انجمن در زیر اضافه می کنم!
ریمیکس های انجمن
هنوز چیزی برای دیدن اینجا وجود ندارد.
منابع
- کد منبع در Github