یک نمای کلی از نحوه ایجاد یک جزء تنظیمات از لغزنده ها و چک باکس ها.
در این پست میخواهم فکری در مورد ساختن یک مؤلفه تنظیمات برای وب به اشتراک بگذارم که واکنشگرا باشد، از ورودیهای متعدد دستگاه پشتیبانی کند و در مرورگرها کار کند. نسخه ی نمایشی را امتحان کنید.
اگر ویدیو را ترجیح میدهید یا میخواهید یک پیشنمایش UI/UX از آنچه در حال ساختمان هستیم داشته باشید، در اینجا توضیح کوتاهتری در YouTube آورده شده است:
نمای کلی
من جنبه های این مؤلفه را به بخش های زیر تقسیم کرده ام:
طرح بندی ها
این اولین نسخه نمایشی چالش رابط کاربری گرافیکی است که تماماً CSS Grid است! در اینجا هر شبکه ای است که با Chrome DevTools برای شبکه هایلایت شده است:
فقط برای شکاف
رایج ترین چیدمان:
foo {
display: grid;
gap: var(--something);
}
من این طرح را "فقط برای شکاف" می نامم زیرا فقط از شبکه برای اضافه کردن شکاف بین بلوک ها استفاده می کند.
پنج طرحبندی از این استراتژی استفاده میکنند، در اینجا همه آنها نمایش داده میشوند:
عنصر fieldset
، که شامل هر گروه ورودی ( .fieldset-item
) است، از gap: 1px
برای ایجاد مرزهای مویی بین عناصر استفاده می کند. بدون راه حل مرزی مشکل!
.grid { display: grid; gap: 1px; background: var(--bg-surface-1); & > .fieldset-item { background: var(--bg-surface-2); } }
.grid { display: grid; & > .fieldset-item { background: var(--bg-surface-2); &:not(:last-child) { border-bottom: 1px solid var(--bg-surface-1); } } }
بسته بندی توری طبیعی
پیچیدهترین طرحبندی در نهایت طرح ماکرو بود، سیستم چیدمان منطقی بین <main>
و <form>
.
در مرکز قرار دادن محتوای بسته بندی
Flexbox و grid هر دو تواناییهایی را برای align-items
یا align-content
فراهم میکنند، و هنگام برخورد با عناصر بستهبندی، همترازیهای چیدمان content
فضا را بین کودکان بهعنوان یک گروه توزیع میکنند.
main {
display: grid;
gap: var(--space-xl);
place-content: center;
}
عنصر اصلی استفاده از place-content: center
کوتاهنویسی تراز وسط به طوری که کودکان به صورت عمودی و افقی در هر دو طرح بندی یک و دو ستون در مرکز قرار گیرند.
در ویدیوی بالا مشاهده کنید که چگونه "محتوا" در مرکز باقی می ماند، حتی اگر بسته بندی اتفاق افتاده باشد.
تنظیم خودکار Minmax را تکرار کنید
<form>
از یک طرح شبکه تطبیقی برای هر بخش استفاده می کند. این طرح بندی بر اساس فضای موجود از یک به دو ستون تغییر می کند.
form {
display: grid;
gap: var(--space-xl) var(--space-xxl);
grid-template-columns: repeat(auto-fit, minmax(min(10ch, 100%), 35ch));
align-items: flex-start;
max-width: 89vw;
}
این شبکه مقدار متفاوتی برای row-gap
(--space-xl) نسبت به column-gap
(--space-xxl) دارد تا آن لمس سفارشی را روی طرحبندی پاسخگو اعمال کند. وقتی ستونها روی هم قرار میگیرند، یک شکاف بزرگ میخواهیم، اما نه به اندازهای که در یک صفحه گسترده هستیم.
ویژگی grid-template-columns
از 3 تابع CSS استفاده می کند: repeat()
، minmax()
و min()
. Una Kravets یک پست وبلاگ طرح بندی عالی در مورد این دارد که آن را RAM می نامد.
اگر آن را با Una مقایسه کنید، 3 افزوده ویژه در چیدمان ما وجود دارد:
- تابع
min()
اضافی را پاس می کنیم. - ما
align-items: flex-start
. -
max-width: 89vw
وجود دارد.
تابع min()
اضافی به خوبی توسط Evan Minto در وبلاگ خود در پست Intrinsically Responsive CSS Grid با minmax() و min() توضیح داده شده است. توصیه می کنم آن را بخوانید. اصلاح تراز flex-start
برای حذف اثر کشش پیشفرض است، به طوری که فرزندان این طرحبندی نیازی به داشتن ارتفاعهای برابر نداشته باشند، آنها میتوانند ارتفاعهای طبیعی و ذاتی داشته باشند. ویدیوی یوتیوب یک تفکیک سریع از این تراز اضافه شده دارد.
max-width: 89vw
ارزش یک تفکیک کوچک در این پست را دارد. اجازه دهید طرح بندی را با و بدون سبک اعمال شده به شما نشان دهم:
چه اتفاقی می افتد؟ هنگامی که max-width
مشخص می شود، زمینه، اندازه صریح یا اندازه مشخص را برای الگوریتم چیدمان تنظیم auto-fit
فراهم می کند تا بداند چند تکرار می تواند در فضا قرار گیرد. در حالی که واضح به نظر می رسد که فضا "عرض کامل" است، با توجه به مشخصات شبکه CSS، اندازه مشخص یا حداکثر اندازه باید ارائه شود. من یک اندازه حداکثر ارائه کرده ام.
بنابراین، چرا 89vw
؟ چون برای چیدمان من "کار کرد". من و چند نفر دیگر از Chrome در حال بررسی این موضوع هستیم که چرا یک مقدار معقول تر، مانند 100vw
کافی نیست، و آیا این در واقع یک اشکال است.
فاصله گذاری
بیشتر هماهنگی این چیدمان از یک پالت محدود فاصله، به طور دقیق 7 است.
:root {
--space-xxs: .25rem;
--space-xs: .5rem;
--space-sm: 1rem;
--space-md: 1.5rem;
--space-lg: 2rem;
--space-xl: 3rem;
--space-xxl: 6rem;
}
استفاده از این جریان ها با گرید، CSS @nest و نحو سطح 5 رسانه @ بسیار خوب است. در اینجا یک مثال، مجموعه طرح بندی کاملاً <main>
از سبک ها آورده شده است.
main {
display: grid;
gap: var(--space-xl);
place-content: center;
padding: var(--space-sm);
@media (width >= 540px) {
& {
padding: var(--space-lg);
}
}
@media (width >= 800px) {
& {
padding: var(--space-xl);
}
}
}
شبکهای با محتوای متمرکز که بهطور پیشفرض بهطور متوسط (مانند تلفن همراه) پر شده است. اما با در دسترس قرار گرفتن فضای نمای بیشتر، با افزایش padding گسترش می یابد. CSS 2021 بسیار خوب به نظر می رسد!
طرح قبلی، "فقط برای شکاف" را به خاطر دارید؟ در اینجا یک نسخه کاملتر از نحوه ظاهر آنها در این مؤلفه آمده است:
header {
display: grid;
gap: var(--space-xxs);
}
section {
display: grid;
gap: var(--space-md);
}
رنگ
استفاده کنترل شده از رنگ به این طرح کمک کرد تا به عنوان رسا و در عین حال مینیمال برجسته شود. من این کار را به این صورت انجام می دهم:
:root {
--surface1: lch(10 0 0);
--surface2: lch(15 0 0);
--surface3: lch(20 0 0);
--surface4: lch(25 0 0);
--text1: lch(95 0 0);
--text2: lch(75 0 0);
}
من رنگهای سطح و متن خود را با اعداد نامگذاری میکنم، برخلاف نامهایی مانند surface-dark
و surface-darker
، زیرا در یک جستجوی رسانهای، آنها را ورق میزنم، و روشن و تیره معنیدار نخواهند بود.
من آنها را در یک درخواست رسانه ترجیحی مانند این برگردانم:
:root {
...
@media (prefers-color-scheme: light) {
& {
--surface1: lch(90 0 0);
--surface2: lch(100 0 0);
--surface3: lch(98 0 0);
--surface4: lch(85 0 0);
--text1: lch(20 0 0);
--text2: lch(40 0 0);
}
}
}
قبل از اینکه به جزئیات نحو رنگ بپردازیم، مهم است که نگاهی اجمالی به تصویر کلی و استراتژی داشته باشیم. اما، از آنجایی که من کمی از خودم جلو افتاده ام، اجازه دهید کمی پشتیبان بگیرم.
LCH
بدون اینکه خیلی عمیق به زمین تئوری رنگ بپردازیم، LCH یک نحو مبتنی بر انسان است، که به نحوه درک ما از رنگ توجه می کند، نه اینکه چگونه رنگ را با ریاضی اندازه گیری می کنیم (مانند 255). این به آن یک مزیت متمایز میدهد زیرا انسانها میتوانند آن را راحتتر بنویسند و سایر انسانها با این تنظیمات هماهنگ خواهند بود.

برای امروز، در این نسخه ی نمایشی، بیایید بر روی نحو و مقادیری که برای ایجاد روشن و تاریک ورق می زنم تمرکز کنیم. بیایید به 1 سطح و 1 رنگ متن نگاه کنیم:
:root {
--surface1: lch(10 0 0);
--text1: lch(95 0 0);
@media (prefers-color-scheme: light) {
& {
--surface1: lch(90 0 0);
--text1: lch(40 0 0);
}
}
}
--surface1: lch(10 0 0)
به 10%
روشنایی، 0 رنگ و 0 رنگ ترجمه می شود: یک خاکستری بی رنگ بسیار تیره. سپس، در جستجوی رسانه برای حالت نور، روشنایی با --surface1: lch(90 0 0);
به 90%
تغییر می کند. . و این اصل استراتژی است. فقط با تغییر سبکی بین 2 تم، حفظ نسبت کنتراست مورد نیاز طراحی یا آنچه که می تواند دسترسی را حفظ کند، شروع کنید.
امتیاز lch()
در اینجا این است که سبکی انسان محور است، و ما می توانیم در مورد تغییر %
نسبت به آن احساس خوبی داشته باشیم، این که از نظر ادراکی و پیوسته آن %
متفاوت خواهد بود. برای مثال hsl()
چندان قابل اعتماد نیست .
در صورت علاقه ، اطلاعات بیشتری در مورد فضاهای رنگی و lch()
وجود دارد. داره میاد!
CSS در حال حاضر به هیچ وجه نمی تواند به این رنگ ها دسترسی داشته باشد . اجازه دهید تکرار کنم: ما در اکثر مانیتورهای مدرن به یک سوم رنگ ها دسترسی نداریم. و اینها هر رنگی نیستند، بلکه زنده ترین رنگ هایی هستند که صفحه نمایش می تواند نمایش دهد . وب سایت های ما از بین رفته اند زیرا سخت افزار مانیتور سریعتر از مشخصات CSS و پیاده سازی مرورگر تکامل یافته است.
لیا ورو
کنترل های فرم تطبیقی با طرح رنگ
بسیاری از مرورگرها کنترل های تم تیره را ارسال می کنند، در حال حاضر Safari و Chromium، اما باید در CSS یا HTML مشخص کنید که طراحی شما از آنها استفاده می کند.
موارد فوق تأثیر ویژگی را از پانل Styles DevTools نشان می دهد. دمو از تگ HTML استفاده می کند که به نظر من به طور کلی مکان بهتری است:
<meta name="color-scheme" content="dark light">
در این مقاله color-scheme
توسط توماس اشتاینر همه چیز را در مورد آن بیاموزید. چیزهای بیشتری از ورودی های چک باکس تیره برای به دست آوردن وجود دارد!
CSS accent-color
اخیراً فعالیتهایی در مورد accent-color
روی عناصر فرم صورت گرفته است، که یک سبک CSS است که میتواند رنگ رنگ مورد استفاده در عنصر ورودی مرورگر را تغییر دهد. اطلاعات بیشتر در مورد آن را اینجا در GitHub بخوانید. من آن را در سبک های خود برای این جزء گنجانده ام. از آنجایی که مرورگرها از آن پشتیبانی میکنند، چک باکسهای من بیشتر با مضمون با رنگهای صورتی و بنفش ظاهر میشوند.
input[type="checkbox"] {
accent-color: var(--brand);
}
رنگ با گرادیان های ثابت و فوکوس درونی ظاهر می شود
رنگ ها زمانی که کم استفاده می شوند بیشتر ظاهر می شوند و یکی از راه هایی که من دوست دارم به آن برسم از طریق تعاملات رنگارنگ UI است.
لایههای زیادی از بازخورد و تعامل رابط کاربری در ویدیوی بالا وجود دارد که به شخصیت بخشیدن به تعامل کمک میکند:
- برجسته کردن زمینه
- ارائه بازخورد رابط کاربری در مورد «چقدر کامل» مقدار در محدوده است.
- ارائه بازخورد رابط کاربری مبنی بر اینکه یک فیلد ورودی را میپذیرد.
برای ارائه بازخورد زمانی که یک عنصر در حال تعامل با یک عنصر است، CSS از کلاس :focus-within
برای تغییر ظاهر عناصر مختلف استفاده می کند، بیایید .fieldset-item
را تجزیه کنیم، بسیار جالب است:
.fieldset-item {
...
&:focus-within {
background: var(--surface2);
& svg {
fill: white;
}
& picture {
clip-path: circle(50%);
background: var(--brand-bg-gradient) fixed;
}
}
}
هنگامی که یکی از فرزندان این عنصر دارای تمرکز- درون است:
- به پس زمینه
.fieldset-item
رنگ سطح کنتراست بالاتری نسبت داده می شود. -
svg
تودرتو برای کنتراست بالاتر به رنگ سفید پر شده است. -
clip-path
<picture>
به یک دایره کامل گسترش می یابد و پس زمینه با گرادیان ثابت روشن پر می شود.
محدوده سفارشی
با توجه به عنصر ورودی HTML زیر، به شما نشان خواهم داد که چگونه ظاهر آن را سفارشی کردم:
<input type="range">
3 بخش در این عنصر وجود دارد که باید آن را سفارشی کنیم:
سبک های عناصر محدوده
input[type="range"] {
/* style setting variables */
--track-height: .5ex;
--track-fill: 0%;
--thumb-size: 3ex;
--thumb-offset: -1.25ex;
--thumb-highlight-size: 0px;
appearance: none; /* clear styles, make way for mine */
display: block;
inline-size: 100%; /* fill container */
margin: 1ex 0; /* ensure thumb isn't colliding with sibling content */
background: transparent; /* bg is in the track */
outline-offset: 5px; /* focus styles have space */
}
چند خط اول CSS بخشهای سفارشی سبکها هستند، و امیدوارم که برچسبگذاری واضح به آنها کمک کند. بقیه سبکها عمدتاً سبکهای بازنشانی هستند، تا پایهای ثابت برای ساختن بخشهای پیچیده مولفه فراهم کنند.
سبک های ردیابی
input[type="range"]::-webkit-slider-runnable-track {
appearance: none; /* clear styles, make way for mine */
block-size: var(--track-height);
border-radius: 5ex;
background:
/* hard stop gradient:
- half transparent (where colorful fill we be)
- half dark track fill
- 1st background image is on top
*/
linear-gradient(
to right,
transparent var(--track-fill),
var(--surface1) 0%
),
/* colorful fill effect, behind track surface fill */
var(--brand-bg-gradient) fixed;
}
ترفند این کار، «آشکار کردن» رنگ پر جنب و جوش است. این کار با گرادیان توقف سخت در بالا انجام می شود. گرادیان تا درصد پر شدن شفاف است و پس از آن از رنگ سطح مسیر پر نشده استفاده می کند. در پشت آن سطح پر نشده، یک رنگ تمام عرض وجود دارد که منتظر شفافیت است تا آن را آشکار کند.
سبک پر کردن آهنگ
طراحی من برای حفظ سبک پر کردن نیاز به جاوا اسکریپت دارد . فقط استراتژیهای CSS وجود دارد، اما آنها نیاز دارند که عنصر انگشت شست به همان ارتفاع مسیر باشد، و من نتوانستم هماهنگی را در این محدودیتها پیدا کنم.
/* grab sliders on page */
const sliders = document.querySelectorAll('input[type="range"]')
/* take a slider element, return a percentage string for use in CSS */
const rangeToPercent = slider => {
const max = slider.getAttribute('max') || 10;
const percent = slider.value / max * 100;
return `${parseInt(percent)}%`;
};
/* on page load, set the fill amount */
sliders.forEach(slider => {
slider.style.setProperty('--track-fill', rangeToPercent(slider));
/* when a slider changes, update the fill prop */
slider.addEventListener('input', e => {
e.target.style.setProperty('--track-fill', rangeToPercent(e.target));
})
})
من فکر می کنم این یک ارتقاء بصری خوب را ایجاد می کند. نوار لغزنده بدون جاوا اسکریپت عالی کار می کند، پروپ --track-fill
مورد نیاز نیست، اگر وجود نداشته باشد به سادگی سبک پر نخواهد داشت. اگر جاوا اسکریپت در دسترس است، ویژگی سفارشی را پر کنید و در عین حال تغییرات کاربر را مشاهده کنید و ویژگی سفارشی را با مقدار همگام کنید.
در اینجا یک پست عالی در CSS-Tricks توسط Ana Tudor وجود دارد که تنها راه حل CSS را برای پر کردن مسیر نشان می دهد. من همچنین این عنصر range
را بسیار الهام بخش یافتم.
سبک های انگشت شست
input[type="range"]::-webkit-slider-thumb {
appearance: none; /* clear styles, make way for mine */
cursor: ew-resize; /* cursor style to support drag direction */
border: 3px solid var(--surface3);
block-size: var(--thumb-size);
inline-size: var(--thumb-size);
margin-top: var(--thumb-offset);
border-radius: 50%;
background: var(--brand-bg-gradient) fixed;
}
اکثر این سبک ها برای ایجاد یک دایره زیبا هستند. دوباره گرادیان پسزمینه ثابت را در آنجا میبینید که رنگهای پویا انگشتهای شست، آهنگها و عناصر SVG مرتبط را یکپارچه میکند. برای کمک به جداسازی تکنیک box-shadow
که برای برجسته کردن شناور استفاده میشود، سبکهای تعامل را جدا کردم:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
::-webkit-slider-thumb {
…
/* shadow spread is initally 0 */
box-shadow: 0 0 0 var(--thumb-highlight-size) var(--thumb-highlight-color);
/* if motion is OK, transition the box-shadow change */
@media (--motionOK) {
& {
transition: box-shadow .1s ease;
}
}
/* on hover/active state of parent, increase size prop */
@nest input[type="range"]:is(:hover,:active) & {
--thumb-highlight-size: 10px;
}
}
هدف، مدیریت آسان و برجسته بصری متحرک برای بازخورد کاربران بود. با استفاده از سایه جعبه می توانم از ایجاد طرح بندی با افکت جلوگیری کنم. من این کار را با ایجاد سایه ای انجام می دهم که تار نباشد و با شکل دایره ای عنصر شست مطابقت داشته باشد. سپس آن را تغییر می دهم و اندازه گسترش آن را روی شناور تغییر می دهم.
اگر فقط جلوه برجسته در چک باکس ها به این راحتی بود…
انتخابگرهای مرورگر متقابل
دریافتم که برای دستیابی به سازگاری بین مرورگرها به این انتخابگرهای -webkit-
و -moz-
نیاز دارم:
input[type="range"] {
&::-webkit-slider-runnable-track {}
&::-moz-range-track {}
&::-webkit-slider-thumb {}
&::-moz-range-thumb {}
}
چک باکس سفارشی
با توجه به عنصر ورودی HTML زیر، به شما نشان خواهم داد که چگونه ظاهر آن را سفارشی کردم:
<input type="checkbox">
3 بخش در این عنصر وجود دارد که باید آن را سفارشی کنیم:
عنصر چک باکس
input[type="checkbox"] {
inline-size: var(--space-sm); /* increase width */
block-size: var(--space-sm); /* increase height */
outline-offset: 5px; /* focus style enhancement */
accent-color: var(--brand); /* tint the input */
position: relative; /* prepare for an absolute pseudo element */
transform-style: preserve-3d; /* create a 3d z-space stacking context */
margin: 0;
cursor: pointer;
}
transform-style
و position
برای شبه عنصری که بعداً برای استایل دادن به هایلایت معرفی خواهیم کرد، آماده می شوند. در غیر این صورت، اکثراً چیزهای سبک نظری جزئی از من است. من دوست دارم مکان نما نشانگر باشد، من از خطوط طرح خارج شده خوشم می آید، چک باکس های پیش فرض خیلی کوچک هستند، و اگر accent-color
پشتیبانی می شود، این چک باکس ها را در طرح رنگ برند بیاورید.
برچسبهای چک باکس
به 2 دلیل مهم است که برای چک باکس ها برچسب ارائه کنید. اولین مورد این است که نشان دهد مقدار چک باکس برای چه چیزی استفاده می شود، برای پاسخ به "روشن یا خاموش برای چه؟" دوم این که برای UX، کاربران وب به تعامل با چک باکس ها از طریق برچسب های مرتبط خود عادت کرده اند.
<input type="checkbox" id="text-notifications" name="text-notifications" >
<label for="text-notifications"> <h3>Text Messages</h3> <small>Get notified about all text messages sent to your device</small> </label>
روی برچسب خود، یک ویژگی for
قرار دهید که با شناسه به کادر انتخاب اشاره می کند: <label for="text-notifications">
. در کادر تأیید، نام و شناسه را دو برابر کنید تا مطمئن شوید که با ابزارها و فناوریهای مختلف مانند ماوس یا صفحهخوان پیدا میشود: <input type="checkbox" id="text-notifications" name="text-notifications">
. :hover
، :active
و موارد دیگر به صورت رایگان با اتصال ارائه می شوند و راه های تعامل با فرم شما را افزایش می دهند.
برجسته کردن کادر انتخاب
من میخواهم رابطهایم را ثابت نگه دارم، و عنصر لغزنده دارای یک تصویر کوچک برجسته است که میخواهم با کادر انتخاب از آن استفاده کنم. تصویر بند انگشتی میتوانست از box-shadow
استفاده کند و خاصیت spread
برای افزایش و پایینکردن یک سایه دارد. با این حال، این اثر در اینجا کار نمی کند زیرا چک باکس های ما مربع هستند و باید باشند .
من توانستم به همان جلوه بصری با یک عنصر شبه و مقدار تاسف بار CSS دست پیدا کنم:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
input[type="checkbox"]::before {
--thumb-scale: .01; /* initial scale of highlight */
--thumb-highlight-size: var(--space-xl);
content: "";
inline-size: var(--thumb-highlight-size);
block-size: var(--thumb-highlight-size);
clip-path: circle(50%); /* circle shape */
position: absolute; /* this is why position relative on parent */
top: 50%; /* pop and plop technique (https://web.dev/centering-in-css#5-pop-and-plop) */
left: 50%;
background: var(--thumb-highlight-color);
transform-origin: center center; /* goal is a centered scaling circle */
transform: /* order here matters!! */
translateX(-50%) /* counter balances left: 50% */
translateY(-50%) /* counter balances top: 50% */
translateZ(-1px) /* PUTS IT BEHIND THE CHECKBOX */
scale(var(--thumb-scale)) /* value we toggle for animation */
;
will-change: transform;
@media (--motionOK) { /* transition only if motion is OK */
& {
transition: transform .2s ease;
}
}
}
/* on hover, set scale custom property to "in" state */
input[type="checkbox"]:hover::before {
--thumb-scale: 1;
}
ایجاد یک شبه عنصر دایره کار ساده ای است، اما قرار دادن آن در پشت عنصری که به آن متصل است سخت تر بود. قبل و بعد از اینکه درستش کردم اینجاست:
این قطعاً یک تعامل خرد است، اما برای من حفظ ثبات بصری مهم است. تکنیک مقیاسبندی انیمیشن همان است که در جاهای دیگر از آن استفاده کردهایم. ما یک ویژگی سفارشی را روی یک مقدار جدید تنظیم می کنیم و به CSS اجازه می دهیم آن را بر اساس اولویت های حرکت انتقال دهد. ویژگی کلیدی در اینجا translateZ(-1px)
است. والدین یک فضای سه بعدی ایجاد کردند و این فرزند شبه عنصر با قرار دادن کمی خود در فضای z به آن ضربه زد.
دسترسی
ویدیوی YouTube نمایش خوبی از تعامل ماوس، صفحهکلید و صفحهخوان را برای این مؤلفه تنظیمات نشان میدهد. من برخی از جزئیات را در اینجا فرا خواهم خواند.
انتخاب عناصر HTML
<form>
<header>
<fieldset>
<picture>
<label>
<input>
هر یک از این موارد حاوی نکات و نکاتی برای ابزار مرور کاربر است. برخی از عناصر نکات تعاملی را ارائه میدهند، برخی تعامل را به هم متصل میکنند و برخی به شکلدهی درخت دسترسپذیری که یک صفحهخوان پیمایش میکند کمک میکنند.
ویژگی های HTML
ما میتوانیم عناصری را که صفحهخوانها به آنها نیاز ندارند، پنهان کنیم، در این مورد نماد کنار نوار لغزنده:
<picture aria-hidden="true">
ویدیوی بالا جریان صفحهخوان را در سیستم عامل مک نشان میدهد. توجه کنید که چگونه فوکوس ورودی مستقیماً از یک نوار لغزنده به لغزنده بعدی حرکت می کند. این به این دلیل است که ما نمادی را که ممکن است توقفی در راه اسلایدر بعدی باشد، پنهان کردهایم. بدون این ویژگی، کاربر باید متوقف شود، گوش دهد و از کنار تصویری که ممکن است قادر به دیدن آن نباشد عبور کند.
SVG یک دسته از ریاضیات است، بیایید یک عنصر <title>
برای عنوان شناور رایگان ماوس و یک نظر قابل خواندن برای انسان در مورد آنچه ریاضی ایجاد می کند اضافه کنیم:
<svg viewBox="0 0 24 24">
<title>A note icon</title>
<path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/>
</svg>
به غیر از آن، ما به اندازه کافی از HTML مشخص شده استفاده کردهایم که فرم به خوبی در ماوس، صفحه کلید، کنترلکنندههای بازی ویدیویی و صفحهخوانها تست میشود.
جاوا اسکریپت
من قبلاً نحوه مدیریت رنگ پر کردن آهنگ از جاوا اسکریپت را پوشش داده ام ، بنابراین اجازه دهید اکنون به جاوا اسکریپت مربوط به <form>
نگاه کنیم:
const form = document.querySelector('form');
form.addEventListener('input', event => {
const formData = Object.fromEntries(new FormData(form));
console.table(formData);
})
هر بار که فرم با آن تعامل میکند و تغییر میکند، کنسول فرم را به عنوان یک شی در جدولی برای بررسی آسان قبل از ارسال به سرور ثبت میکند.
نتیجه گیری
حالا که می دانی من چگونه این کار را انجام دادم، شما چطور؟! این باعث می شود که معماری اجزای سرگرم کننده ای ایجاد شود! چه کسی می خواهد نسخه اول را با اسلات در چارچوب مورد علاقه خود بسازد؟ 🙂
بیایید رویکردهایمان را متنوع کنیم و همه راههای ساخت در وب را بیاموزیم. یک نسخه نمایشی ایجاد کنید، پیوندها را برای من توییت کنید ، و من آن را به بخش ریمیکس های انجمن در زیر اضافه می کنم!
ریمیکس های انجمن
- @tomayac با سبک خود در مورد ناحیه شناور برای برچسبهای چک باکس! این نسخه هیچ شکاف شناور بین عناصر: نسخه ی نمایشی و منبع ندارد.
یک نمای کلی از نحوه ایجاد یک جزء تنظیمات از لغزنده ها و چک باکس ها.
در این پست میخواهم فکری در مورد ساختن یک مؤلفه تنظیمات برای وب به اشتراک بگذارم که واکنشگرا باشد، از ورودیهای متعدد دستگاه پشتیبانی کند و در مرورگرها کار کند. نسخه ی نمایشی را امتحان کنید.
اگر ویدیو را ترجیح میدهید یا میخواهید یک پیشنمایش UI/UX از آنچه در حال ساختمان هستیم داشته باشید، در اینجا توضیح کوتاهتری در YouTube آورده شده است:
نمای کلی
من جنبه های این مؤلفه را به بخش های زیر تقسیم کرده ام:
طرح بندی ها
این اولین نسخه نمایشی چالش رابط کاربری گرافیکی است که تماماً CSS Grid است! در اینجا هر شبکه ای است که با Chrome DevTools برای شبکه هایلایت شده است:
فقط برای شکاف
رایج ترین چیدمان:
foo {
display: grid;
gap: var(--something);
}
من این طرح را "فقط برای شکاف" می نامم زیرا فقط از شبکه برای اضافه کردن شکاف بین بلوک ها استفاده می کند.
پنج طرحبندی از این استراتژی استفاده میکنند، در اینجا همه آنها نمایش داده میشوند:
عنصر fieldset
، که شامل هر گروه ورودی ( .fieldset-item
) است، از gap: 1px
برای ایجاد مرزهای مویی بین عناصر استفاده می کند. بدون راه حل مرزی مشکل!
.grid { display: grid; gap: 1px; background: var(--bg-surface-1); & > .fieldset-item { background: var(--bg-surface-2); } }
.grid { display: grid; & > .fieldset-item { background: var(--bg-surface-2); &:not(:last-child) { border-bottom: 1px solid var(--bg-surface-1); } } }
بسته بندی توری طبیعی
پیچیدهترین طرحبندی در نهایت طرح ماکرو بود، سیستم چیدمان منطقی بین <main>
و <form>
.
در مرکز قرار دادن محتوای بسته بندی
Flexbox و grid هر دو تواناییهایی را برای align-items
یا align-content
فراهم میکنند، و هنگام برخورد با عناصر بستهبندی، همترازیهای چیدمان content
فضا را بین کودکان بهعنوان یک گروه توزیع میکنند.
main {
display: grid;
gap: var(--space-xl);
place-content: center;
}
عنصر اصلی استفاده از place-content: center
کوتاهنویسی تراز وسط به طوری که کودکان به صورت عمودی و افقی در هر دو طرح بندی یک و دو ستون در مرکز قرار گیرند.
در ویدیوی بالا مشاهده کنید که چگونه "محتوا" در مرکز باقی می ماند، حتی اگر بسته بندی اتفاق افتاده باشد.
تنظیم خودکار Minmax را تکرار کنید
<form>
از یک طرح شبکه تطبیقی برای هر بخش استفاده می کند. این طرح بندی بر اساس فضای موجود از یک به دو ستون تغییر می کند.
form {
display: grid;
gap: var(--space-xl) var(--space-xxl);
grid-template-columns: repeat(auto-fit, minmax(min(10ch, 100%), 35ch));
align-items: flex-start;
max-width: 89vw;
}
این شبکه مقدار متفاوتی برای row-gap
(--space-xl) نسبت به column-gap
(--space-xxl) دارد تا آن لمس سفارشی را روی طرحبندی پاسخگو اعمال کند. وقتی ستونها روی هم قرار میگیرند، یک شکاف بزرگ میخواهیم، اما نه به اندازهای که در یک صفحه گسترده هستیم.
ویژگی grid-template-columns
از 3 تابع CSS استفاده می کند: repeat()
، minmax()
و min()
. Una Kravets یک پست وبلاگ طرح بندی عالی در مورد این دارد که آن را RAM می نامد.
اگر آن را با Una مقایسه کنید، 3 افزوده ویژه در چیدمان ما وجود دارد:
- تابع
min()
اضافی را پاس می کنیم. - ما
align-items: flex-start
. -
max-width: 89vw
وجود دارد.
تابع min()
اضافی به خوبی توسط Evan Minto در وبلاگ خود در پست Intrinsically Responsive CSS Grid با minmax() و min() توضیح داده شده است. توصیه می کنم آن را بخوانید. اصلاح تراز flex-start
برای حذف اثر کشش پیشفرض است، به طوری که فرزندان این طرحبندی نیازی به داشتن ارتفاعهای برابر نداشته باشند، آنها میتوانند ارتفاعهای طبیعی و ذاتی داشته باشند. ویدیوی یوتیوب یک تفکیک سریع از این تراز اضافه شده دارد.
max-width: 89vw
ارزش یک تفکیک کوچک در این پست را دارد. اجازه دهید طرح بندی را با و بدون سبک اعمال شده به شما نشان دهم:
چه اتفاقی می افتد؟ هنگامی که max-width
مشخص می شود، زمینه، اندازه صریح یا اندازه مشخص را برای الگوریتم چیدمان تنظیم auto-fit
فراهم می کند تا بداند چند تکرار می تواند در فضا قرار گیرد. در حالی که واضح به نظر می رسد که فضا "عرض کامل" است، با توجه به مشخصات شبکه CSS، اندازه مشخص یا حداکثر اندازه باید ارائه شود. من یک اندازه حداکثر ارائه کرده ام.
بنابراین، چرا 89vw
؟ چون برای چیدمان من "کار کرد". من و چند نفر دیگر از Chrome در حال بررسی این موضوع هستیم که چرا یک مقدار معقول تر، مانند 100vw
کافی نیست، و آیا این در واقع یک اشکال است.
فاصله گذاری
بیشتر هماهنگی این چیدمان از یک پالت محدود فاصله، به طور دقیق 7 است.
:root {
--space-xxs: .25rem;
--space-xs: .5rem;
--space-sm: 1rem;
--space-md: 1.5rem;
--space-lg: 2rem;
--space-xl: 3rem;
--space-xxl: 6rem;
}
استفاده از این جریان ها با گرید، CSS @nest و نحو سطح 5 رسانه @ بسیار خوب است. در اینجا یک مثال، مجموعه طرح بندی کاملاً <main>
از سبک ها آورده شده است.
main {
display: grid;
gap: var(--space-xl);
place-content: center;
padding: var(--space-sm);
@media (width >= 540px) {
& {
padding: var(--space-lg);
}
}
@media (width >= 800px) {
& {
padding: var(--space-xl);
}
}
}
شبکهای با محتوای متمرکز که بهطور پیشفرض بهطور متوسط (مانند تلفن همراه) پر شده است. اما با در دسترس قرار گرفتن فضای نمای بیشتر، با افزایش padding گسترش می یابد. CSS 2021 بسیار خوب به نظر می رسد!
طرح قبلی، "فقط برای شکاف" را به خاطر دارید؟ در اینجا یک نسخه کاملتر از نحوه ظاهر آنها در این مؤلفه آمده است:
header {
display: grid;
gap: var(--space-xxs);
}
section {
display: grid;
gap: var(--space-md);
}
رنگ
استفاده کنترل شده از رنگ به این طرح کمک کرد تا به عنوان رسا و در عین حال مینیمال برجسته شود. من این کار را به این صورت انجام می دهم:
:root {
--surface1: lch(10 0 0);
--surface2: lch(15 0 0);
--surface3: lch(20 0 0);
--surface4: lch(25 0 0);
--text1: lch(95 0 0);
--text2: lch(75 0 0);
}
من رنگهای سطح و متن خود را با اعداد نامگذاری میکنم، برخلاف نامهایی مانند surface-dark
و surface-darker
، زیرا در یک جستجوی رسانهای، آنها را ورق میزنم، و روشن و تیره معنیدار نخواهند بود.
من آنها را در یک درخواست رسانه ترجیحی مانند این برگردانم:
:root {
...
@media (prefers-color-scheme: light) {
& {
--surface1: lch(90 0 0);
--surface2: lch(100 0 0);
--surface3: lch(98 0 0);
--surface4: lch(85 0 0);
--text1: lch(20 0 0);
--text2: lch(40 0 0);
}
}
}
قبل از اینکه به جزئیات نحو رنگ بپردازیم، مهم است که نگاهی اجمالی به تصویر کلی و استراتژی داشته باشیم. اما، از آنجایی که من کمی از خودم جلو افتاده ام، اجازه دهید کمی پشتیبان بگیرم.
LCH
بدون اینکه خیلی عمیق به زمین تئوری رنگ بپردازیم، LCH یک نحو مبتنی بر انسان است، که به نحوه درک ما از رنگ توجه می کند، نه اینکه چگونه رنگ را با ریاضی اندازه گیری می کنیم (مانند 255). این به آن یک مزیت متمایز میدهد زیرا انسانها میتوانند آن را راحتتر بنویسند و سایر انسانها با این تنظیمات هماهنگ خواهند بود.

برای امروز، در این نسخه ی نمایشی، بیایید روی نحو و مقادیری که برای روشن کردن و تاریک کردن آنها ورق می زنم تمرکز کنیم. بیایید به 1 سطح و 1 رنگ متن نگاه کنیم:
:root {
--surface1: lch(10 0 0);
--text1: lch(95 0 0);
@media (prefers-color-scheme: light) {
& {
--surface1: lch(90 0 0);
--text1: lch(40 0 0);
}
}
}
--surface1: lch(10 0 0)
به 10%
روشنایی، 0 رنگ و 0 رنگ ترجمه می شود: یک خاکستری بی رنگ بسیار تیره. سپس، در جستجوی رسانه برای حالت نور، روشنایی با --surface1: lch(90 0 0);
به 90%
تغییر می کند. . و این اصل استراتژی است. فقط با تغییر سبکی بین 2 تم، حفظ نسبت کنتراست مورد نیاز طراحی یا آنچه که می تواند دسترسی را حفظ کند، شروع کنید.
امتیاز lch()
در اینجا این است که سبکی انسان محور است، و ما می توانیم در مورد تغییر %
نسبت به آن احساس خوبی داشته باشیم، این که از نظر ادراکی و پیوسته آن %
متفاوت خواهد بود. برای مثال hsl()
چندان قابل اعتماد نیست .
در صورت علاقه ، اطلاعات بیشتری در مورد فضاهای رنگی و lch()
وجود دارد. داره میاد!
CSS در حال حاضر به هیچ وجه نمی تواند به این رنگ ها دسترسی داشته باشد . اجازه دهید تکرار کنم: ما در اکثر مانیتورهای مدرن به یک سوم رنگ ها دسترسی نداریم. و اینها هر رنگی نیستند، بلکه زنده ترین رنگ هایی هستند که صفحه نمایش می تواند نمایش دهد . وب سایت های ما از بین رفته اند زیرا سخت افزار مانیتور سریعتر از مشخصات CSS و پیاده سازی مرورگر تکامل یافته است.
لیا ورو
کنترل های فرم تطبیقی با طرح رنگ
بسیاری از مرورگرها کنترل های تم تیره را ارسال می کنند، در حال حاضر Safari و Chromium، اما باید در CSS یا HTML مشخص کنید که طراحی شما از آنها استفاده می کند.
موارد فوق تأثیر ویژگی را از پانل Styles DevTools نشان می دهد. دمو از تگ HTML استفاده می کند که به نظر من به طور کلی مکان بهتری است:
<meta name="color-scheme" content="dark light">
در این مقاله color-scheme
توسط توماس اشتاینر همه چیز را در مورد آن بیاموزید. چیزهای بیشتری از ورودی های چک باکس تیره برای به دست آوردن وجود دارد!
CSS accent-color
اخیراً فعالیتهایی در مورد accent-color
روی عناصر فرم صورت گرفته است، که یک سبک CSS است که میتواند رنگ رنگ مورد استفاده در عنصر ورودی مرورگر را تغییر دهد. اطلاعات بیشتر در مورد آن را اینجا در GitHub بخوانید. من آن را در سبک های خود برای این جزء گنجانده ام. از آنجایی که مرورگرها از آن پشتیبانی میکنند، چک باکسهای من بیشتر با مضمون با رنگهای صورتی و بنفش ظاهر میشوند.
input[type="checkbox"] {
accent-color: var(--brand);
}
رنگ با گرادیان های ثابت و فوکوس درونی ظاهر می شود
رنگ ها زمانی که کم استفاده می شوند بیشتر ظاهر می شوند و یکی از راه هایی که من دوست دارم به آن برسم از طریق تعاملات رنگارنگ UI است.
لایههای زیادی از بازخورد و تعامل رابط کاربری در ویدیوی بالا وجود دارد که به شخصیت بخشیدن به تعامل کمک میکند:
- برجسته کردن زمینه
- ارائه بازخورد رابط کاربری در مورد «چقدر کامل» مقدار در محدوده است.
- ارائه بازخورد رابط کاربری مبنی بر اینکه یک فیلد ورودی را میپذیرد.
برای ارائه بازخورد زمانی که یک عنصر در حال تعامل با یک عنصر است، CSS از کلاس :focus-within
برای تغییر ظاهر عناصر مختلف استفاده می کند، بیایید .fieldset-item
را تجزیه کنیم، بسیار جالب است:
.fieldset-item {
...
&:focus-within {
background: var(--surface2);
& svg {
fill: white;
}
& picture {
clip-path: circle(50%);
background: var(--brand-bg-gradient) fixed;
}
}
}
هنگامی که یکی از فرزندان این عنصر دارای تمرکز- درون است:
- به پس زمینه
.fieldset-item
رنگ سطح کنتراست بالاتری نسبت داده می شود. -
svg
تودرتو برای کنتراست بالاتر به رنگ سفید پر شده است. -
clip-path
<picture>
به یک دایره کامل گسترش می یابد و پس زمینه با گرادیان ثابت روشن پر می شود.
محدوده سفارشی
با توجه به عنصر ورودی HTML زیر، به شما نشان خواهم داد که چگونه ظاهر آن را سفارشی کردم:
<input type="range">
3 بخش در این عنصر وجود دارد که باید آن را سفارشی کنیم:
سبک های عناصر محدوده
input[type="range"] {
/* style setting variables */
--track-height: .5ex;
--track-fill: 0%;
--thumb-size: 3ex;
--thumb-offset: -1.25ex;
--thumb-highlight-size: 0px;
appearance: none; /* clear styles, make way for mine */
display: block;
inline-size: 100%; /* fill container */
margin: 1ex 0; /* ensure thumb isn't colliding with sibling content */
background: transparent; /* bg is in the track */
outline-offset: 5px; /* focus styles have space */
}
چند خط اول CSS بخشهای سفارشی سبکها هستند، و امیدوارم که برچسبگذاری واضح به آنها کمک کند. بقیه سبکها عمدتاً سبکهای بازنشانی هستند، تا پایهای ثابت برای ساختن بخشهای پیچیده مولفه فراهم کنند.
سبک های ردیابی
input[type="range"]::-webkit-slider-runnable-track {
appearance: none; /* clear styles, make way for mine */
block-size: var(--track-height);
border-radius: 5ex;
background:
/* hard stop gradient:
- half transparent (where colorful fill we be)
- half dark track fill
- 1st background image is on top
*/
linear-gradient(
to right,
transparent var(--track-fill),
var(--surface1) 0%
),
/* colorful fill effect, behind track surface fill */
var(--brand-bg-gradient) fixed;
}
ترفند این کار، «آشکار کردن» رنگ پر جنب و جوش است. این کار با گرادیان توقف سخت در بالا انجام می شود. گرادیان تا درصد پر شدن شفاف است و پس از آن از رنگ سطح مسیر پر نشده استفاده می کند. در پشت آن سطح پر نشده، یک رنگ تمام عرض وجود دارد که منتظر شفافیت است تا آن را آشکار کند.
سبک پر کردن آهنگ
طراحی من برای حفظ سبک پر کردن نیاز به جاوا اسکریپت دارد . فقط استراتژیهای CSS وجود دارد، اما آنها نیاز دارند که عنصر انگشت شست به همان ارتفاع مسیر باشد، و من نتوانستم هماهنگی را در این محدودیتها پیدا کنم.
/* grab sliders on page */
const sliders = document.querySelectorAll('input[type="range"]')
/* take a slider element, return a percentage string for use in CSS */
const rangeToPercent = slider => {
const max = slider.getAttribute('max') || 10;
const percent = slider.value / max * 100;
return `${parseInt(percent)}%`;
};
/* on page load, set the fill amount */
sliders.forEach(slider => {
slider.style.setProperty('--track-fill', rangeToPercent(slider));
/* when a slider changes, update the fill prop */
slider.addEventListener('input', e => {
e.target.style.setProperty('--track-fill', rangeToPercent(e.target));
})
})
من فکر می کنم این یک ارتقاء بصری خوب را ایجاد می کند. نوار لغزنده بدون جاوا اسکریپت عالی کار می کند، پروپ --track-fill
مورد نیاز نیست، اگر وجود نداشته باشد به سادگی سبک پر نخواهد داشت. اگر جاوا اسکریپت در دسترس است، ویژگی سفارشی را پر کنید و در عین حال تغییرات کاربر را مشاهده کنید و ویژگی سفارشی را با مقدار همگام کنید.
در اینجا یک پست عالی در CSS-Tricks توسط Ana Tudor وجود دارد که تنها راه حل CSS را برای پر کردن مسیر نشان می دهد. من همچنین این عنصر range
را بسیار الهام بخش یافتم.
سبک های انگشت شست
input[type="range"]::-webkit-slider-thumb {
appearance: none; /* clear styles, make way for mine */
cursor: ew-resize; /* cursor style to support drag direction */
border: 3px solid var(--surface3);
block-size: var(--thumb-size);
inline-size: var(--thumb-size);
margin-top: var(--thumb-offset);
border-radius: 50%;
background: var(--brand-bg-gradient) fixed;
}
اکثر این سبک ها برای ایجاد یک دایره زیبا هستند. دوباره گرادیان پسزمینه ثابت را در آنجا میبینید که رنگهای پویا انگشتهای شست، آهنگها و عناصر SVG مرتبط را یکپارچه میکند. برای کمک به جداسازی تکنیک box-shadow
که برای برجسته کردن شناور استفاده میشود، سبکهای تعامل را جدا کردم:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
::-webkit-slider-thumb {
…
/* shadow spread is initally 0 */
box-shadow: 0 0 0 var(--thumb-highlight-size) var(--thumb-highlight-color);
/* if motion is OK, transition the box-shadow change */
@media (--motionOK) {
& {
transition: box-shadow .1s ease;
}
}
/* on hover/active state of parent, increase size prop */
@nest input[type="range"]:is(:hover,:active) & {
--thumb-highlight-size: 10px;
}
}
هدف، مدیریت آسان و برجسته بصری متحرک برای بازخورد کاربران بود. با استفاده از سایه جعبه می توانم از ایجاد طرح بندی با افکت جلوگیری کنم. من این کار را با ایجاد سایه ای انجام می دهم که تار نباشد و با شکل دایره ای عنصر شست مطابقت داشته باشد. سپس آن را تغییر می دهم و اندازه گسترش آن را روی شناور تغییر می دهم.
اگر فقط جلوه برجسته در چک باکس ها به این راحتی بود…
انتخابگرهای مرورگر متقابل
دریافتم که برای دستیابی به سازگاری بین مرورگرها به این انتخابگرهای -webkit-
و -moz-
نیاز دارم:
input[type="range"] {
&::-webkit-slider-runnable-track {}
&::-moz-range-track {}
&::-webkit-slider-thumb {}
&::-moz-range-thumb {}
}
چک باکس سفارشی
با توجه به عنصر ورودی HTML زیر، به شما نشان خواهم داد که چگونه ظاهر آن را سفارشی کردم:
<input type="checkbox">
3 بخش در این عنصر وجود دارد که باید آن را سفارشی کنیم:
عنصر چک باکس
input[type="checkbox"] {
inline-size: var(--space-sm); /* increase width */
block-size: var(--space-sm); /* increase height */
outline-offset: 5px; /* focus style enhancement */
accent-color: var(--brand); /* tint the input */
position: relative; /* prepare for an absolute pseudo element */
transform-style: preserve-3d; /* create a 3d z-space stacking context */
margin: 0;
cursor: pointer;
}
transform-style
و position
برای شبه عنصری که بعداً برای استایل دادن به هایلایت معرفی خواهیم کرد، آماده می شوند. در غیر این صورت، اکثراً چیزهای سبک نظری جزئی از من است. من دوست دارم مکان نما نشانگر باشد، من از خطوط طرح خارج شده خوشم می آید، چک باکس های پیش فرض خیلی کوچک هستند، و اگر accent-color
پشتیبانی می شود، این چک باکس ها را در طرح رنگ برند بیاورید.
برچسبهای چک باکس
به 2 دلیل مهم است که برای چک باکس ها برچسب ارائه کنید. اولین مورد این است که نشان دهد مقدار چک باکس برای چه چیزی استفاده می شود، برای پاسخ به "روشن یا خاموش برای چه؟" دوم این که برای UX، کاربران وب به تعامل با چک باکس ها از طریق برچسب های مرتبط خود عادت کرده اند.
<input type="checkbox" id="text-notifications" name="text-notifications" >
<label for="text-notifications"> <h3>Text Messages</h3> <small>Get notified about all text messages sent to your device</small> </label>
روی برچسب خود، یک ویژگی for
قرار دهید که با شناسه به کادر انتخاب اشاره می کند: <label for="text-notifications">
. در کادر تأیید، نام و شناسه را دو برابر کنید تا مطمئن شوید که با ابزارها و فناوریهای مختلف مانند ماوس یا صفحهخوان پیدا میشود: <input type="checkbox" id="text-notifications" name="text-notifications">
. :hover
، :active
و موارد دیگر به صورت رایگان با اتصال ارائه می شوند و راه های تعامل با فرم شما را افزایش می دهند.
برجسته کردن کادر انتخاب
من میخواهم رابطهایم را ثابت نگه دارم، و عنصر لغزنده دارای یک تصویر کوچک برجسته است که میخواهم با کادر انتخاب از آن استفاده کنم. تصویر بند انگشتی میتوانست از box-shadow
استفاده کند و خاصیت spread
برای افزایش و پایینکردن یک سایه دارد. با این حال، این اثر در اینجا کار نمی کند زیرا چک باکس های ما مربع هستند و باید باشند .
من توانستم به همان جلوه بصری با یک عنصر شبه و مقدار تاسف بار CSS دست پیدا کنم:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
input[type="checkbox"]::before {
--thumb-scale: .01; /* initial scale of highlight */
--thumb-highlight-size: var(--space-xl);
content: "";
inline-size: var(--thumb-highlight-size);
block-size: var(--thumb-highlight-size);
clip-path: circle(50%); /* circle shape */
position: absolute; /* this is why position relative on parent */
top: 50%; /* pop and plop technique (https://web.dev/centering-in-css#5-pop-and-plop) */
left: 50%;
background: var(--thumb-highlight-color);
transform-origin: center center; /* goal is a centered scaling circle */
transform: /* order here matters!! */
translateX(-50%) /* counter balances left: 50% */
translateY(-50%) /* counter balances top: 50% */
translateZ(-1px) /* PUTS IT BEHIND THE CHECKBOX */
scale(var(--thumb-scale)) /* value we toggle for animation */
;
will-change: transform;
@media (--motionOK) { /* transition only if motion is OK */
& {
transition: transform .2s ease;
}
}
}
/* on hover, set scale custom property to "in" state */
input[type="checkbox"]:hover::before {
--thumb-scale: 1;
}
ایجاد یک شبه عنصر دایره کار ساده ای است، اما قرار دادن آن در پشت عنصری که به آن متصل است سخت تر بود. قبل و بعد از اینکه درستش کردم اینجاست:
این قطعاً یک تعامل خرد است، اما برای من حفظ ثبات بصری مهم است. تکنیک مقیاسبندی انیمیشن همان است که در جاهای دیگر از آن استفاده کردهایم. ما یک ویژگی سفارشی را روی یک مقدار جدید تنظیم می کنیم و به CSS اجازه می دهیم آن را بر اساس اولویت های حرکت انتقال دهد. ویژگی کلیدی در اینجا translateZ(-1px)
است. والدین یک فضای سه بعدی ایجاد کردند و این فرزند شبه عنصر با قرار دادن کمی خود در فضای z به آن ضربه زد.
دسترسی
ویدیوی YouTube نمایش خوبی از تعامل ماوس، صفحهکلید و صفحهخوان را برای این مؤلفه تنظیمات نشان میدهد. من برخی از جزئیات را در اینجا فرا خواهم خواند.
انتخاب عناصر HTML
<form>
<header>
<fieldset>
<picture>
<label>
<input>
هر یک از این موارد حاوی نکات و نکاتی برای ابزار مرور کاربر است. برخی از عناصر نکات تعاملی را ارائه میدهند، برخی تعامل را به هم متصل میکنند و برخی به شکلدهی درخت دسترسپذیری که یک صفحهخوان پیمایش میکند کمک میکنند.
ویژگی های HTML
ما میتوانیم عناصری را که صفحهخوانها به آنها نیاز ندارند، پنهان کنیم، در این مورد نماد کنار نوار لغزنده:
<picture aria-hidden="true">
ویدیوی بالا جریان صفحهخوان را در سیستم عامل مک نشان میدهد. توجه کنید که چگونه فوکوس ورودی مستقیماً از یک نوار لغزنده به لغزنده بعدی حرکت می کند. این به این دلیل است که ما نمادی را که ممکن است توقفی در راه اسلایدر بعدی باشد، پنهان کردهایم. بدون این ویژگی، کاربر باید متوقف شود، گوش دهد و از کنار تصویری که ممکن است قادر به دیدن آن نباشد عبور کند.
SVG یک دسته از ریاضیات است، بیایید یک عنصر <title>
برای عنوان شناور رایگان ماوس و یک نظر قابل خواندن برای انسان در مورد آنچه ریاضی ایجاد می کند اضافه کنیم:
<svg viewBox="0 0 24 24">
<title>A note icon</title>
<path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/>
</svg>
به غیر از آن، ما به اندازه کافی از HTML مشخص شده استفاده کردهایم که فرم به خوبی در ماوس، صفحه کلید، کنترلکنندههای بازی ویدیویی و صفحهخوانها تست میشود.
جاوا اسکریپت
من قبلاً نحوه مدیریت رنگ پر کردن آهنگ از جاوا اسکریپت را پوشش داده ام ، بنابراین اجازه دهید اکنون به جاوا اسکریپت مربوط به <form>
نگاه کنیم:
const form = document.querySelector('form');
form.addEventListener('input', event => {
const formData = Object.fromEntries(new FormData(form));
console.table(formData);
})
هر زمان که فرم با آن تعامل داشته و تغییر می کند ، کنسول قبل از ارسال به سرور ، فرم را به عنوان یک شیء در یک جدول برای بررسی آسان وارد می کند.
نتیجه گیری
حالا که می دانید من چگونه این کار را کردم ، چطور؟! این باعث می شود معماری مؤلفه سرگرم کننده باشد! چه کسی می خواهد نسخه اول را با اسلات در چارچوب مورد علاقه خود بسازد؟ 🙂
بیایید رویکردهای خود را متنوع کنیم و تمام راه های ساخت در وب را بیاموزیم. یک نسخه ی نمایشی ایجاد کنید ، به من پیوندهایی توییت کنید ، و من آن را به بخش Remixes Community در زیر اضافه می کنم!
ریمیکس های جامعه
- Tomayac با سبک خود در مورد منطقه Hover برای برچسب های کادر انتخاب! این نسخه هیچ شکافی بین عناصر ندارد: نسخه ی نمایشی و منبع .
مروری اساسی در مورد نحوه ساخت یک مؤلفه تنظیمات کشویی و کادر انتخاب.
در این پست می خواهم در مورد ساخت یک مؤلفه تنظیمات برای وب که پاسخگو است ، به اشتراک بگذارم ، از ورودی های مختلف دستگاه پشتیبانی می کند و در مرورگرها کار می کند. نسخه ی نمایشی را امتحان کنید.
اگر فیلم را ترجیح می دهید ، یا می خواهید پیش نمایش UI/UX از آنچه در حال ساخت هستیم ، در اینجا یک پیاده روی کوتاه تر در YouTube وجود دارد:
نمای کلی
من جنبه های این مؤلفه را به بخش های زیر تقسیم کرده ام:
طرح بندی ها
این اولین نسخه ی نمایشی GUI Challenge است که همه شبکه CSS است! در اینجا هر شبکه برجسته شده با Devtools Chrome برای شبکه :
فقط برای شکاف
رایج ترین طرح:
foo {
display: grid;
gap: var(--something);
}
من این طرح را "فقط برای شکاف" می نامم زیرا فقط از شبکه برای اضافه کردن شکاف بین بلوک ها استفاده می کند.
پنج طرح بندی از این استراتژی استفاده می کنند ، در اینجا همه آنها نمایش داده شده است:
عنصر fieldset
، که حاوی هر گروه ورودی ( .fieldset-item
) است ، از gap: 1px
برای ایجاد مرزهای خط موی بین عناصر استفاده می کند. بدون راه حل مرزی پیچیده!
.grid { display: grid; gap: 1px; background: var(--bg-surface-1); & > .fieldset-item { background: var(--bg-surface-2); } }
.grid { display: grid; & > .fieldset-item { background: var(--bg-surface-2); &:not(:last-child) { border-bottom: 1px solid var(--bg-surface-1); } } }
بسته بندی شبکه طبیعی
پیچیده ترین طرح به پایان رسید که طرح کلان ، سیستم طرح منطقی بین <main>
و <form>
است.
محتوای بسته بندی محور
Flexbox و Grid هر دو توانایی align-items
یا align-content
را فراهم می کنند و هنگام برخورد با عناصر بسته بندی ، ترازهای طرح بندی content
، فضای بین کودکان را به عنوان یک گروه توزیع می کند.
main {
display: grid;
gap: var(--space-xl);
place-content: center;
}
عنصر اصلی استفاده از place-content: center
تراز مرکز به گونه ای که کودکان به صورت عمودی و افقی در هر دو طرح یک و دو ستون متمرکز می شوند.
در ویدیوی فوق تماشا کنید که چگونه "محتوا" محور می ماند ، حتی اگر بسته بندی رخ داده است.
minmax مناسب خودکار را تکرار کنید
<form>
از یک طرح شبکه تطبیقی برای هر بخش استفاده می کند. این طرح از یک به دو ستون بر اساس فضای موجود تغییر می کند.
form {
display: grid;
gap: var(--space-xl) var(--space-xxl);
grid-template-columns: repeat(auto-fit, minmax(min(10ch, 100%), 35ch));
align-items: flex-start;
max-width: 89vw;
}
این شبکه برای row-gap
(-Pace-XL) نسبت به column-gap
(-Pace-XXL) مقدار متفاوتی دارد تا بتواند آن لمس سفارشی را بر روی طرح پاسخگو قرار دهد. وقتی ستون ها پشته می شوند ، ما یک شکاف بزرگ می خواهیم ، اما به اندازه آن که در یک صفحه گسترده هستیم نیست.
ویژگی grid-template-columns
از 3 کارکرد CSS استفاده می کند: repeat()
، minmax()
و min()
. Una Kravets یک پست وبلاگ چیدمان عالی در این باره دارد و آن را رم می نامد.
اگر آن را با UNA مقایسه کنید ، 3 مورد اضافی در طرح ما وجود دارد:
- ما یک عملکرد
min()
اضافی را پشت سر می گذاریم. - ما
align-items: flex-start
. -
max-width: 89vw
.
عملکرد min()
اضافی توسط Evan Minto در وبلاگ خود در این پست به طور ذاتی پاسخ دهنده شبکه CSS با minmax () و min () شرح داده شده است. توصیه می کنم آن را بخوانید. تصحیح تراز flex-start
برای از بین بردن اثر کششی پیش فرض است ، به طوری که کودکان این طرح نیازی به ارتفاع مساوی ندارند ، می توانند ارتفاعات طبیعی و ذاتی داشته باشند. ویدیوی YouTube با شکستن سریع این تراز افزوده است.
max-width: 89vw
ارزش یک شکست کوچک در این پست را دارد. بگذارید طرح را با و بدون سبک اعمال شده به شما نشان دهم:
چه اتفاقی می افتد؟ هنگامی که max-width
مشخص شده است ، زمینه ، اندازه صریح و یا اندازه مشخص برای الگوریتم طرح بندی auto-fit
را فراهم می کند تا بدانید که چند تکرار می تواند در فضا قرار بگیرد. اگرچه به نظر می رسد که فضا "عرض کامل" است ، طبق مشخصات شبکه CSS ، باید اندازه مشخص یا حداکثر اندازه فراهم شود. من یک اندازه حداکثر ارائه داده ام.
بنابراین ، چرا 89vw
؟ زیرا "این کار کرد" برای طرح من. من و یک زن و شوهر دیگر Chrome در حال بررسی این موضوع هستیم که چرا یک ارزش معقول تر ، مانند 100vw
کافی نیست ، و اگر این در واقع یک اشکال است.
فاصله گذاری
اکثر هارمونی این طرح از یک پالت محدود از فاصله ، 7 تا دقیق است.
:root {
--space-xxs: .25rem;
--space-xs: .5rem;
--space-sm: 1rem;
--space-md: 1.5rem;
--space-lg: 2rem;
--space-xl: 3rem;
--space-xxl: 6rem;
}
استفاده از این جریان ها به خوبی با Grid ، CSSnest و Syntax سطح 5 Media . در اینجا یک مثال ، مجموعه سبک های کاملاً <main>
است.
main {
display: grid;
gap: var(--space-xl);
place-content: center;
padding: var(--space-sm);
@media (width >= 540px) {
& {
padding: var(--space-lg);
}
}
@media (width >= 800px) {
& {
padding: var(--space-xl);
}
}
}
یک شبکه با محتوای متمرکز ، به طور متوسط به طور پیش فرض (مانند موبایل). اما هرچه فضای دید بیشتر در دسترس باشد ، با افزایش بالشتک گسترش می یابد. 2021 CSS بسیار خوب به نظر می رسد!
طرح قبلی ، "فقط برای شکاف" را به خاطر می آورید؟ در اینجا نسخه کامل تری از نحوه نگاه آنها در این مؤلفه آورده شده است:
header {
display: grid;
gap: var(--space-xxs);
}
section {
display: grid;
gap: var(--space-md);
}
رنگ
استفاده کنترل شده از رنگ به این طرح کمک کرد تا به عنوان بیانگر و در عین حال حداقل باشد. من این کار را اینگونه انجام می دهم:
:root {
--surface1: lch(10 0 0);
--surface2: lch(15 0 0);
--surface3: lch(20 0 0);
--surface4: lch(25 0 0);
--text1: lch(95 0 0);
--text2: lch(75 0 0);
}
من رنگ های سطح و متن خود را با اعداد نامگذاری می کنم و بر خلاف نام هایی مانند surface-dark
و surface-darker
، زیرا در یک پرس و جو رسانه ای ، آنها را می چرخانم ، و سبک و تاریک معنی دار نخواهد بود.
من آنها را در یک پرس و جو رسانه ای ترجیح می دهم مانند این:
:root {
...
@media (prefers-color-scheme: light) {
& {
--surface1: lch(90 0 0);
--surface2: lch(100 0 0);
--surface3: lch(98 0 0);
--surface4: lch(85 0 0);
--text1: lch(20 0 0);
--text2: lch(40 0 0);
}
}
}
مهم است که قبل از اینکه به جزئیات نحوی رنگ بپردازیم ، یک نگاه سریع به تصویر و استراتژی کلی بدست آوریم. اما ، از آنجا که من کمی جلوتر از خودم هستم ، اجازه دهید کمی پشتیبان گیری کنم.
LCH؟
بدون اینکه بیش از حد به سرزمین تئوری رنگ بپردازیم ، LCH یک نحو انسانی است ، که به نحوه درک رنگ ما می پردازد ، نه اینکه چگونه رنگ را با ریاضی اندازه گیری می کنیم (مانند 255). این مزیت متمایز به آن می دهد زیرا انسان می تواند آن را راحت تر بنویسد و سایر انسانها با این تنظیمات هماهنگ باشند.

برای امروز ، در این نسخه ی نمایشی ، بیایید روی نحو و مقادیری که من می چرخم برای نور و تاریک تمرکز کنیم. بیایید به 1 سطح و 1 رنگ متن نگاه کنیم:
:root {
--surface1: lch(10 0 0);
--text1: lch(95 0 0);
@media (prefers-color-scheme: light) {
& {
--surface1: lch(90 0 0);
--text1: lch(40 0 0);
}
}
}
--surface1: lch(10 0 0)
به 10%
سبکی ، 0 کروما و 0 رنگ ترجمه می شود: یک خاکستری بی رنگ بسیار تیره. سپس ، در پرس و جو رسانه ای برای حالت نور ، سبکی به 90%
با --surface1: lch(90 0 0);
. و این مهمترین استراتژی است. فقط با تغییر سبکی بین 2 موضوع ، حفظ نسبت های کنتراست طراحی خواستار یا آنچه می تواند دسترسی را حفظ کند ، شروع کنید.
پاداش lch()
در اینجا این است که سبکی به انسان گرا است و ما می توانیم نسبت به تغییر %
در آن احساس خوبی داشته باشیم ، که به طور ادراکی و مداوم آن %
متفاوت خواهد بود. hsl()
به عنوان مثال قابل اعتماد نیست .
در صورت علاقه بیشتر در مورد فضاهای رنگی و lch()
وجود دارد. داره میاد!
CSS در حال حاضر به هیچ وجه نمی تواند به این رنگ ها دسترسی پیدا کند . بگذارید تکرار کنم: ما در اکثر مانیتورهای مدرن به یک سوم رنگ ها دسترسی نداریم. و اینها فقط هیچ رنگی نیستند ، بلکه واضح ترین رنگ های صفحه نمایش هستند . وب سایت های ما شسته می شوند زیرا سخت افزار مانیتور سریعتر از مشخصات CSS و اجرای مرورگر تکامل می یابد.
لیا ورو
کنترل فرم تطبیقی با طرح رنگی
بسیاری از مرورگرها کنترل های تم تاریک ، در حال حاضر Safari و Chromium را حمل می کنند ، اما شما باید در CSS یا HTML مشخص کنید که طراحی شما از آنها استفاده می کند.
موارد فوق نشان دهنده تأثیر خاصیت از پانل سبک های Devtools است. نسخه ی نمایشی از برچسب HTML استفاده می کند ، که به نظر من به طور کلی مکان بهتری است:
<meta name="color-scheme" content="dark light">
همه چیز را در مورد آن در این مقاله color-scheme
توسط توماس اشتاینر بیاموزید. چیزهای بیشتری برای به دست آوردن ورودی های کادر تأیید وجود دارد!
accent-color
CSS
فعالیت های اخیر در مورد accent-color
بر روی عناصر فرم وجود دارد که یک سبک CSS واحد است که می تواند رنگ رنگ مورد استفاده در عنصر ورودی مرورگرها را تغییر دهد. اطلاعات بیشتر در مورد آن را در اینجا در GitHub بخوانید. من آن را در سبک های خود برای این مؤلفه گنجانده ام. از آنجا که مرورگرها از آن پشتیبانی می کنند ، کادر انتخاب من بیشتر با رنگ صورتی و بنفش رنگ می شوند.
input[type="checkbox"] {
accent-color: var(--brand);
}
رنگ با شیب های ثابت و تمرکز خود را نشان می دهد
رنگ بیشتر در هنگام استفاده از آن به صورت کم استفاده می شود ، و یکی از راه هایی که دوست دارم برای دستیابی به آن از طریق تعامل رنگارنگ UI استفاده کنم.
بسیاری از لایه های بازخورد UI و تعامل در فیلم فوق وجود دارد که به شخصیت دادن به تعامل توسط:
- زمینه برجسته.
- ارائه بازخورد UI از "چقدر کامل" مقدار در محدوده است.
- بازخورد UI که یک فیلد در حال پذیرش ورودی است.
برای ارائه بازخورد در هنگام تعامل یک عنصر ، CSS :focus-within
برای تغییر ظاهر عناصر مختلف استفاده می کند ، بیایید تجزیه و تحلیل .fieldset-item
را تجزیه کنیم ، بسیار جالب است:
.fieldset-item {
...
&:focus-within {
background: var(--surface2);
& svg {
fill: white;
}
& picture {
clip-path: circle(50%);
background: var(--brand-bg-gradient) fixed;
}
}
}
هنگامی که یکی از فرزندان این عنصر با توجه به تمرکز دارد:
- پس زمینه
.fieldset-item
به رنگ سطح کنتراست بالاتر اختصاص داده شده است. -
svg
تو در تو برای کنتراست بالاتر به رنگ سفید پر شده است. -
clip-path
<picture>
تو در تو در یک دایره کامل گسترش می یابد و پس زمینه با شیب ثابت روشن پر می شود.
محدوده سفارشی
با توجه به عنصر ورودی HTML زیر ، من به شما نشان خواهم داد که چگونه ظاهر آن را سفارشی کردم:
<input type="range">
3 قسمت برای این عنصر وجود دارد که ما باید سفارشی کنیم:
سبک های عنصر دامنه
input[type="range"] {
/* style setting variables */
--track-height: .5ex;
--track-fill: 0%;
--thumb-size: 3ex;
--thumb-offset: -1.25ex;
--thumb-highlight-size: 0px;
appearance: none; /* clear styles, make way for mine */
display: block;
inline-size: 100%; /* fill container */
margin: 1ex 0; /* ensure thumb isn't colliding with sibling content */
background: transparent; /* bg is in the track */
outline-offset: 5px; /* focus styles have space */
}
چند خط اول CSS قسمتهای سفارشی سبک ها است و امیدوارم که به وضوح برچسب زدن به آنها کمک کند. بقیه سبک ها اکثراً سبک های تنظیم مجدد هستند ، تا پایه و اساس سازگار برای ساختن قسمت های دشوار این مؤلفه فراهم شود.
سبک های پیگیری
input[type="range"]::-webkit-slider-runnable-track {
appearance: none; /* clear styles, make way for mine */
block-size: var(--track-height);
border-radius: 5ex;
background:
/* hard stop gradient:
- half transparent (where colorful fill we be)
- half dark track fill
- 1st background image is on top
*/
linear-gradient(
to right,
transparent var(--track-fill),
var(--surface1) 0%
),
/* colorful fill effect, behind track surface fill */
var(--brand-bg-gradient) fixed;
}
ترفند این کار "آشکار کردن" رنگ پر پر جنب و جوش است. این کار با شیب Hard Stop در بالا انجام می شود. گرادیان تا درصد پر شدن شفاف است و پس از آن از رنگ سطح ردیف نشده استفاده می کند. در پشت آن سطح پر نشده ، یک رنگ کامل وجود دارد که منتظر شفافیت برای آشکار کردن آن است.
سبک پر کردن آهنگ
طراحی من برای حفظ سبک پر کردن به JavaScript نیاز دارد . فقط استراتژی های CSS وجود دارد ، اما آنها به عنصر انگشت شست همان ارتفاع مسیر نیاز دارند و من نتوانستم در آن محدودیت هارمونی پیدا کنم.
/* grab sliders on page */
const sliders = document.querySelectorAll('input[type="range"]')
/* take a slider element, return a percentage string for use in CSS */
const rangeToPercent = slider => {
const max = slider.getAttribute('max') || 10;
const percent = slider.value / max * 100;
return `${parseInt(percent)}%`;
};
/* on page load, set the fill amount */
sliders.forEach(slider => {
slider.style.setProperty('--track-fill', rangeToPercent(slider));
/* when a slider changes, update the fill prop */
slider.addEventListener('input', e => {
e.target.style.setProperty('--track-fill', rangeToPercent(e.target));
})
})
من فکر می کنم این باعث می شود یک ارتقاء تصویری خوب باشد. کشویی بدون JavaScript بسیار عالی عمل می کند ، --track-fill
لازم نیست ، در صورت عدم حضور ، به سادگی سبک پر نخواهد شد. اگر JavaScript در دسترس است ، در عین حال مشاهده هرگونه تغییر کاربر ، ویژگی های سفارشی را نیز جمع کنید و ویژگی سفارشی را با مقدار همگام سازی کنید.
در اینجا یک پست عالی در مورد CSS-Tricks توسط Ana Tudor وجود دارد ، که نشان دهنده یک راه حل فقط CSS برای پر کردن آهنگ است. من همچنین این عنصر range
را بسیار الهام بخش دیدم.
سبک های انگشت شست
input[type="range"]::-webkit-slider-thumb {
appearance: none; /* clear styles, make way for mine */
cursor: ew-resize; /* cursor style to support drag direction */
border: 3px solid var(--surface3);
block-size: var(--thumb-size);
inline-size: var(--thumb-size);
margin-top: var(--thumb-offset);
border-radius: 50%;
background: var(--brand-bg-gradient) fixed;
}
اکثر این سبک ها ایجاد یک دایره خوب هستند. مجدداً شیب پس زمینه ثابت را در آنجا مشاهده می کنید که رنگهای پویا انگشت شست ، آهنگ ها و عناصر SVG مرتبط را متحد می کند. من سبک های تعامل را جدا کردم تا به منزوی کردن تکنیک box-shadow
که برای برجسته شناور استفاده می شود ، جدا کنم:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
::-webkit-slider-thumb {
…
/* shadow spread is initally 0 */
box-shadow: 0 0 0 var(--thumb-highlight-size) var(--thumb-highlight-color);
/* if motion is OK, transition the box-shadow change */
@media (--motionOK) {
& {
transition: box-shadow .1s ease;
}
}
/* on hover/active state of parent, increase size prop */
@nest input[type="range"]:is(:hover,:active) & {
--thumb-highlight-size: 10px;
}
}
هدف برای بازخورد کاربر ، مدیریت آسان و انیمیشن برجسته بود. با استفاده از سایه جعبه می توانم از ایجاد طرح با اثر جلوگیری کنم. من این کار را با ایجاد سایه ای که مبهم نیست انجام می دهم و با شکل دایره ای عنصر انگشت شست مطابقت دارد. سپس من تغییر و انتقال آن اندازه گسترش آن در شناور است.
اگر فقط اثر برجسته در کادر انتخاب بسیار آسان بود ...
انتخاب کنندگان مرورگر صلیب
فهمیدم که برای دستیابی به قوام مرورگر متقاطع به این انتخاب کنندگان -webkit-
و -moz-
نیاز دارم:
input[type="range"] {
&::-webkit-slider-runnable-track {}
&::-moz-range-track {}
&::-webkit-slider-thumb {}
&::-moz-range-thumb {}
}
چک باکس سفارشی
با توجه به عنصر ورودی HTML زیر ، من به شما نشان خواهم داد که چگونه ظاهر آن را سفارشی کردم:
<input type="checkbox">
3 قسمت برای این عنصر وجود دارد که ما باید سفارشی کنیم:
عنصر کادر انتخاب
input[type="checkbox"] {
inline-size: var(--space-sm); /* increase width */
block-size: var(--space-sm); /* increase height */
outline-offset: 5px; /* focus style enhancement */
accent-color: var(--brand); /* tint the input */
position: relative; /* prepare for an absolute pseudo element */
transform-style: preserve-3d; /* create a 3d z-space stacking context */
margin: 0;
cursor: pointer;
}
سبک های transform-style
و position
برای شبه عنصر که بعداً معرفی خواهیم کرد تا سبک برجسته را معرفی کنیم. در غیر این صورت ، این بیشتر موارد سبک تفکر جزئی از من است. من دوست دارم که مکان نما نشانگر باشد ، من طلسم های کلی را دوست دارم ، کادر انتخاب پیش فرض خیلی ریز و درشت است و اگر accent-color
پشتیبانی می شود ، این کادرهای چک را به طرح رنگ برند وارد کنید.
برچسب های کادر انتخاب
تهیه برچسب برای کادر انتخاب به 2 دلیل مهم است. اولین مورد این است که نشان دهنده آنچه از مقدار کادر انتخاب استفاده می شود ، برای پاسخ به "روشن یا خاموش برای چه؟" دوم برای UX است ، کاربران وب عادت کرده اند که از طریق برچسب های مرتبط با کادر انتخاب خود در تعامل باشند.
<input type="checkbox" id="text-notifications" name="text-notifications" >
<label for="text-notifications"> <h3>Text Messages</h3> <small>Get notified about all text messages sent to your device</small> </label>
روی برچسب خود ، for
هایی را که به یک کادر انتخاب شده توسط شناسه نشان می دهد ، قرار دهید: <label for="text-notifications">
. در کادر انتخاب خود ، نام و شناسه را دو برابر کنید تا اطمینان حاصل کنید که با ابزارهای مختلف و فناوری ، مانند ماوس یا صفحه نمایشگر یافت می شود: <input type="checkbox" id="text-notifications" name="text-notifications">
. :hover
، :active
و بیشتر با اتصال به صورت رایگان همراه می شوند و روش های تعامل فرم شما را افزایش می دهند.
کادر انتخاب برجسته
من می خواهم رابط های خود را ثابت نگه دارم و عنصر کشویی دارای یک تصویر کوچک خوب است که می خواهم با کادر انتخاب استفاده کنم. تصویر کوچک قادر به استفاده box-shadow
بود و spread
آن برای مقیاس سایه به سمت بالا و پایین است. با این حال ، این اثر در اینجا کار نمی کند زیرا کادر انتخاب ما مربع هستند و باید باشند .
من توانستم با یک عنصر شبه و یک مقدار ناگوار از CSS پیچیده به همان اثر بصری دست یابم:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
input[type="checkbox"]::before {
--thumb-scale: .01; /* initial scale of highlight */
--thumb-highlight-size: var(--space-xl);
content: "";
inline-size: var(--thumb-highlight-size);
block-size: var(--thumb-highlight-size);
clip-path: circle(50%); /* circle shape */
position: absolute; /* this is why position relative on parent */
top: 50%; /* pop and plop technique (https://web.dev/centering-in-css#5-pop-and-plop) */
left: 50%;
background: var(--thumb-highlight-color);
transform-origin: center center; /* goal is a centered scaling circle */
transform: /* order here matters!! */
translateX(-50%) /* counter balances left: 50% */
translateY(-50%) /* counter balances top: 50% */
translateZ(-1px) /* PUTS IT BEHIND THE CHECKBOX */
scale(var(--thumb-scale)) /* value we toggle for animation */
;
will-change: transform;
@media (--motionOK) { /* transition only if motion is OK */
& {
transition: transform .2s ease;
}
}
}
/* on hover, set scale custom property to "in" state */
input[type="checkbox"]:hover::before {
--thumb-scale: 1;
}
ایجاد یک عنصر شبه دایره ای کار ساده ای است ، اما قرار دادن آن در پشت عنصری که به آن وصل شده است سخت تر بود. در اینجا قبل و بعد از رفع آن است:
این قطعاً یک تعامل میکرو است ، اما برای من مهم است که قوام بصری را حفظ کنم. تکنیک مقیاس بندی انیمیشن همان چیزی است که ما در جاهای دیگر استفاده کرده ایم. ما یک ویژگی سفارشی را به یک مقدار جدید تنظیم می کنیم و اجازه می دهیم CSS آن را بر اساس تنظیمات برگزیده حرکت منتقل کند. ویژگی اصلی در اینجا translateZ(-1px)
است. والدین یک فضای سه بعدی ایجاد کردند و این کودک شبه عنصر با قرار دادن خود در فضای z ، در آن قرار گرفت.
دسترسی
ویدیوی YouTube نمایش خوبی از تعامل ماوس ، صفحه کلید و صفحه نمایش برای این مؤلفه تنظیمات انجام می دهد. من برخی از جزئیات را در اینجا فراخوانی می کنم.
انتخاب عنصر HTML
<form>
<header>
<fieldset>
<picture>
<label>
<input>
هر یک از این موارد نکات و نکاتی را در مورد ابزار مرور کاربر در اختیار دارد. برخی از عناصر نکات متقابل را ارائه می دهند ، برخی از آنها تعامل را به هم متصل می کنند و برخی به شکل دادن به درخت دسترسی که یک صفحه نمایشگر در آن حرکت می کند ، کمک می کنند.
ویژگی های HTML
ما می توانیم عناصری را که مورد نیاز صفحه نمایش نیستند پنهان کنیم ، در این حالت نماد کنار کشویی:
<picture aria-hidden="true">
ویدیوی فوق نشان دهنده جریان ScreenReader در سیستم عامل Mac است. توجه کنید که چگونه تمرکز ورودی مستقیم از یک کشویی به حالت دیگر حرکت می کند. این امر به این دلیل است که ما نمادی را پنهان کرده ایم که ممکن است متوقف شده در راه کشویی بعدی باشد. بدون این ویژگی ، یک کاربر باید جلوی تصویری را که ممکن است نتوانند آن را متوقف کنند ، گوش دهند و حرکت کنند.
SVG یک دسته از ریاضیات است ، بیایید یک عنصر <title>
را برای یک عنوان شناور موش رایگان و یک اظهار نظر قابل خواندن انسان در مورد آنچه که ریاضی ایجاد می کند اضافه کنیم:
<svg viewBox="0 0 24 24">
<title>A note icon</title>
<path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/>
</svg>
به غیر از این ، ما از HTML به وضوح مشخص استفاده کرده ایم که فرم آن را به خوبی در ماوس ، صفحه کلید ، کنترل کننده های بازی های ویدیویی و صفحه نمایش تست می کند.
جاوا اسکریپت
من قبلاً پوشش داده ام که چگونه رنگ پر کردن آهنگ از JavaScript مدیریت می شود ، بنابراین بیایید اکنون به JavaScript مربوط به <form>
نگاه کنیم:
const form = document.querySelector('form');
form.addEventListener('input', event => {
const formData = Object.fromEntries(new FormData(form));
console.table(formData);
})
هر زمان که فرم با آن تعامل داشته و تغییر می کند ، کنسول قبل از ارسال به سرور ، فرم را به عنوان یک شیء در یک جدول برای بررسی آسان وارد می کند.
نتیجه گیری
حالا که می دانید من چگونه این کار را کردم ، چطور؟! این باعث می شود معماری مؤلفه سرگرم کننده باشد! چه کسی می خواهد نسخه اول را با اسلات در چارچوب مورد علاقه خود بسازد؟ 🙂
بیایید رویکردهای خود را متنوع کنیم و تمام راه های ساخت در وب را بیاموزیم. یک نسخه ی نمایشی ایجاد کنید ، به من پیوندهایی توییت کنید ، و من آن را به بخش Remixes Community در زیر اضافه می کنم!
ریمیکس های جامعه
- Tomayac با سبک خود در مورد منطقه Hover برای برچسب های کادر انتخاب! این نسخه هیچ شکافی بین عناصر ندارد: نسخه ی نمایشی و منبع .
مروری اساسی در مورد نحوه ساخت یک مؤلفه تنظیمات کشویی و کادر انتخاب.
در این پست می خواهم در مورد ساخت یک مؤلفه تنظیمات برای وب که پاسخگو است ، به اشتراک بگذارم ، از ورودی های مختلف دستگاه پشتیبانی می کند و در مرورگرها کار می کند. نسخه ی نمایشی را امتحان کنید.
اگر فیلم را ترجیح می دهید ، یا می خواهید پیش نمایش UI/UX از آنچه در حال ساخت هستیم ، در اینجا یک پیاده روی کوتاه تر در YouTube وجود دارد:
نمای کلی
من جنبه های این مؤلفه را به بخش های زیر تقسیم کرده ام:
طرح بندی ها
این اولین نسخه ی نمایشی GUI Challenge است که همه شبکه CSS است! در اینجا هر شبکه برجسته شده با Devtools Chrome برای شبکه :
فقط برای شکاف
رایج ترین طرح:
foo {
display: grid;
gap: var(--something);
}
من این طرح را "فقط برای شکاف" می نامم زیرا فقط از شبکه برای اضافه کردن شکاف بین بلوک ها استفاده می کند.
پنج طرح بندی از این استراتژی استفاده می کنند ، در اینجا همه آنها نمایش داده شده است:
عنصر fieldset
، که حاوی هر گروه ورودی ( .fieldset-item
) است ، از gap: 1px
برای ایجاد مرزهای خط موی بین عناصر استفاده می کند. بدون راه حل مرزی پیچیده!
.grid { display: grid; gap: 1px; background: var(--bg-surface-1); & > .fieldset-item { background: var(--bg-surface-2); } }
.grid { display: grid; & > .fieldset-item { background: var(--bg-surface-2); &:not(:last-child) { border-bottom: 1px solid var(--bg-surface-1); } } }
بسته بندی شبکه طبیعی
پیچیده ترین طرح به پایان رسید که طرح کلان ، سیستم طرح منطقی بین <main>
و <form>
است.
محتوای بسته بندی محور
Flexbox و Grid هر دو توانایی align-items
یا align-content
را فراهم می کنند و هنگام برخورد با عناصر بسته بندی ، ترازهای طرح بندی content
، فضای بین کودکان را به عنوان یک گروه توزیع می کند.
main {
display: grid;
gap: var(--space-xl);
place-content: center;
}
عنصر اصلی استفاده از place-content: center
تراز مرکز به گونه ای که کودکان به صورت عمودی و افقی در هر دو طرح یک و دو ستون متمرکز می شوند.
در ویدیوی فوق تماشا کنید که چگونه "محتوا" محور می ماند ، حتی اگر بسته بندی رخ داده است.
minmax مناسب خودکار را تکرار کنید
<form>
از یک طرح شبکه تطبیقی برای هر بخش استفاده می کند. این طرح از یک به دو ستون بر اساس فضای موجود تغییر می کند.
form {
display: grid;
gap: var(--space-xl) var(--space-xxl);
grid-template-columns: repeat(auto-fit, minmax(min(10ch, 100%), 35ch));
align-items: flex-start;
max-width: 89vw;
}
این شبکه برای row-gap
(-Pace-XL) نسبت به column-gap
(-Pace-XXL) مقدار متفاوتی دارد تا بتواند آن لمس سفارشی را بر روی طرح پاسخگو قرار دهد. وقتی ستون ها پشته می شوند ، ما یک شکاف بزرگ می خواهیم ، اما به اندازه آن که در یک صفحه گسترده هستیم نیست.
ویژگی grid-template-columns
از 3 کارکرد CSS استفاده می کند: repeat()
، minmax()
و min()
. Una Kravets یک پست وبلاگ چیدمان عالی در این باره دارد و آن را رم می نامد.
اگر آن را با UNA مقایسه کنید ، 3 مورد اضافی در طرح ما وجود دارد:
- ما یک عملکرد
min()
اضافی را پشت سر می گذاریم. - ما
align-items: flex-start
. -
max-width: 89vw
.
عملکرد min()
اضافی توسط Evan Minto در وبلاگ خود در این پست به طور ذاتی پاسخ دهنده شبکه CSS با minmax () و min () شرح داده شده است. توصیه می کنم آن را بخوانید. تصحیح تراز flex-start
برای از بین بردن اثر کششی پیش فرض است ، به طوری که کودکان این طرح نیازی به ارتفاع مساوی ندارند ، می توانند ارتفاعات طبیعی و ذاتی داشته باشند. ویدیوی YouTube با شکستن سریع این تراز افزوده است.
max-width: 89vw
ارزش یک شکست کوچک در این پست را دارد. بگذارید طرح را با و بدون سبک اعمال شده به شما نشان دهم:
چه اتفاقی می افتد؟ هنگامی که max-width
مشخص شده است ، زمینه ، اندازه صریح و یا اندازه مشخص برای الگوریتم طرح بندی auto-fit
را فراهم می کند تا بدانید که چند تکرار می تواند در فضا قرار بگیرد. اگرچه به نظر می رسد که فضا "عرض کامل" است ، طبق مشخصات شبکه CSS ، باید اندازه مشخص یا حداکثر اندازه فراهم شود. من یک اندازه حداکثر ارائه داده ام.
بنابراین ، چرا 89vw
؟ زیرا "این کار کرد" برای طرح من. من و یک زن و شوهر دیگر Chrome در حال بررسی این موضوع هستیم که چرا یک ارزش معقول تر ، مانند 100vw
کافی نیست ، و اگر این در واقع یک اشکال است.
فاصله گذاری
اکثر هارمونی این طرح از یک پالت محدود از فاصله ، 7 تا دقیق است.
:root {
--space-xxs: .25rem;
--space-xs: .5rem;
--space-sm: 1rem;
--space-md: 1.5rem;
--space-lg: 2rem;
--space-xl: 3rem;
--space-xxl: 6rem;
}
استفاده از این جریان ها به خوبی با Grid ، CSSnest و Syntax سطح 5 Media . در اینجا یک مثال ، مجموعه سبک های کاملاً <main>
است.
main {
display: grid;
gap: var(--space-xl);
place-content: center;
padding: var(--space-sm);
@media (width >= 540px) {
& {
padding: var(--space-lg);
}
}
@media (width >= 800px) {
& {
padding: var(--space-xl);
}
}
}
یک شبکه با محتوای متمرکز ، به طور متوسط به طور پیش فرض (مانند موبایل). اما هرچه فضای دید بیشتر در دسترس باشد ، با افزایش بالشتک گسترش می یابد. 2021 CSS بسیار خوب به نظر می رسد!
طرح قبلی ، "فقط برای شکاف" را به خاطر می آورید؟ در اینجا نسخه کامل تری از نحوه نگاه آنها در این مؤلفه آورده شده است:
header {
display: grid;
gap: var(--space-xxs);
}
section {
display: grid;
gap: var(--space-md);
}
رنگ
استفاده کنترل شده از رنگ به این طرح کمک کرد تا به عنوان بیانگر و در عین حال حداقل باشد. من این کار را اینگونه انجام می دهم:
:root {
--surface1: lch(10 0 0);
--surface2: lch(15 0 0);
--surface3: lch(20 0 0);
--surface4: lch(25 0 0);
--text1: lch(95 0 0);
--text2: lch(75 0 0);
}
من رنگ های سطح و متن خود را با اعداد نامگذاری می کنم و بر خلاف نام هایی مانند surface-dark
و surface-darker
، زیرا در یک پرس و جو رسانه ای ، آنها را می چرخانم ، و سبک و تاریک معنی دار نخواهد بود.
من آنها را در یک پرس و جو رسانه ای ترجیح می دهم مانند این:
:root {
...
@media (prefers-color-scheme: light) {
& {
--surface1: lch(90 0 0);
--surface2: lch(100 0 0);
--surface3: lch(98 0 0);
--surface4: lch(85 0 0);
--text1: lch(20 0 0);
--text2: lch(40 0 0);
}
}
}
مهم است که قبل از اینکه به جزئیات نحوی رنگ بپردازیم ، یک نگاه سریع به تصویر و استراتژی کلی بدست آوریم. اما ، از آنجا که من کمی جلوتر از خودم هستم ، اجازه دهید کمی پشتیبان گیری کنم.
LCH؟
بدون اینکه بیش از حد به سرزمین تئوری رنگ بپردازیم ، LCH یک نحو انسانی است ، که به نحوه درک رنگ ما می پردازد ، نه اینکه چگونه رنگ را با ریاضی اندازه گیری می کنیم (مانند 255). این مزیت متمایز به آن می دهد زیرا انسان می تواند آن را راحت تر بنویسد و سایر انسانها با این تنظیمات هماهنگ باشند.

برای امروز ، در این نسخه ی نمایشی ، بیایید روی نحو و مقادیری که من می چرخم برای نور و تاریک تمرکز کنیم. بیایید به 1 سطح و 1 رنگ متن نگاه کنیم:
:root {
--surface1: lch(10 0 0);
--text1: lch(95 0 0);
@media (prefers-color-scheme: light) {
& {
--surface1: lch(90 0 0);
--text1: lch(40 0 0);
}
}
}
--surface1: lch(10 0 0)
به 10%
سبکی ، 0 کروما و 0 رنگ ترجمه می شود: یک خاکستری بی رنگ بسیار تیره. سپس ، در پرس و جو رسانه ای برای حالت نور ، سبکی به 90%
با --surface1: lch(90 0 0);
. و این مهمترین استراتژی است. فقط با تغییر سبکی بین 2 موضوع ، حفظ نسبت های کنتراست طراحی خواستار یا آنچه می تواند دسترسی را حفظ کند ، شروع کنید.
پاداش lch()
در اینجا این است که سبکی به انسان گرا است و ما می توانیم نسبت به تغییر %
در آن احساس خوبی داشته باشیم ، که به طور ادراکی و مداوم آن %
متفاوت خواهد بود. hsl()
به عنوان مثال قابل اعتماد نیست .
در صورت علاقه بیشتر در مورد فضاهای رنگی و lch()
وجود دارد. داره میاد!
CSS در حال حاضر به هیچ وجه نمی تواند به این رنگ ها دسترسی پیدا کند . بگذارید تکرار کنم: ما در اکثر مانیتورهای مدرن به یک سوم رنگ ها دسترسی نداریم. و اینها فقط هیچ رنگی نیستند ، بلکه واضح ترین رنگ های صفحه نمایش هستند . وب سایت های ما شسته می شوند زیرا سخت افزار مانیتور سریعتر از مشخصات CSS و اجرای مرورگر تکامل می یابد.
لیا ورو
کنترل فرم تطبیقی با طرح رنگی
بسیاری از مرورگرها کنترل های تم تاریک ، در حال حاضر Safari و Chromium را حمل می کنند ، اما شما باید در CSS یا HTML مشخص کنید که طراحی شما از آنها استفاده می کند.
موارد فوق نشان دهنده تأثیر خاصیت از پانل سبک های Devtools است. نسخه ی نمایشی از برچسب HTML استفاده می کند ، که به نظر من به طور کلی مکان بهتری است:
<meta name="color-scheme" content="dark light">
همه چیز را در مورد آن در این مقاله color-scheme
توسط توماس اشتاینر بیاموزید. چیزهای بیشتری برای به دست آوردن ورودی های کادر تأیید وجود دارد!
accent-color
CSS
فعالیت های اخیر در مورد accent-color
بر روی عناصر فرم وجود دارد که یک سبک CSS واحد است که می تواند رنگ رنگ مورد استفاده در عنصر ورودی مرورگرها را تغییر دهد. اطلاعات بیشتر در مورد آن را در اینجا در GitHub بخوانید. من آن را در سبک های خود برای این مؤلفه گنجانده ام. از آنجا که مرورگرها از آن پشتیبانی می کنند ، کادر انتخاب من بیشتر با رنگ صورتی و بنفش رنگ می شوند.
input[type="checkbox"] {
accent-color: var(--brand);
}
رنگ با شیب های ثابت و تمرکز خود را نشان می دهد
رنگ بیشتر در هنگام استفاده از آن به صورت کم استفاده می شود ، و یکی از راه هایی که دوست دارم برای دستیابی به آن از طریق تعامل رنگارنگ UI استفاده کنم.
بسیاری از لایه های بازخورد UI و تعامل در فیلم فوق وجود دارد که به شخصیت دادن به تعامل توسط:
- زمینه برجسته.
- ارائه بازخورد UI از "چقدر کامل" مقدار در محدوده است.
- بازخورد UI که یک فیلد در حال پذیرش ورودی است.
برای ارائه بازخورد در هنگام تعامل یک عنصر ، CSS :focus-within
برای تغییر ظاهر عناصر مختلف استفاده می کند ، بیایید تجزیه و تحلیل .fieldset-item
را تجزیه کنیم ، بسیار جالب است:
.fieldset-item {
...
&:focus-within {
background: var(--surface2);
& svg {
fill: white;
}
& picture {
clip-path: circle(50%);
background: var(--brand-bg-gradient) fixed;
}
}
}
هنگامی که یکی از فرزندان این عنصر با توجه به تمرکز دارد:
- پس زمینه
.fieldset-item
به رنگ سطح کنتراست بالاتر اختصاص داده شده است. -
svg
تو در تو برای کنتراست بالاتر به رنگ سفید پر شده است. -
clip-path
<picture>
تو در تو در یک دایره کامل گسترش می یابد و پس زمینه با شیب ثابت روشن پر می شود.
محدوده سفارشی
با توجه به عنصر ورودی HTML زیر ، من به شما نشان خواهم داد که چگونه ظاهر آن را سفارشی کردم:
<input type="range">
3 قسمت برای این عنصر وجود دارد که ما باید سفارشی کنیم:
سبک های عنصر دامنه
input[type="range"] {
/* style setting variables */
--track-height: .5ex;
--track-fill: 0%;
--thumb-size: 3ex;
--thumb-offset: -1.25ex;
--thumb-highlight-size: 0px;
appearance: none; /* clear styles, make way for mine */
display: block;
inline-size: 100%; /* fill container */
margin: 1ex 0; /* ensure thumb isn't colliding with sibling content */
background: transparent; /* bg is in the track */
outline-offset: 5px; /* focus styles have space */
}
چند خط اول CSS قسمتهای سفارشی سبک ها است و امیدوارم که به وضوح برچسب زدن به آنها کمک کند. بقیه سبک ها اکثراً سبک های تنظیم مجدد هستند ، تا پایه و اساس سازگار برای ساختن قسمت های دشوار این مؤلفه فراهم شود.
سبک های پیگیری
input[type="range"]::-webkit-slider-runnable-track {
appearance: none; /* clear styles, make way for mine */
block-size: var(--track-height);
border-radius: 5ex;
background:
/* hard stop gradient:
- half transparent (where colorful fill we be)
- half dark track fill
- 1st background image is on top
*/
linear-gradient(
to right,
transparent var(--track-fill),
var(--surface1) 0%
),
/* colorful fill effect, behind track surface fill */
var(--brand-bg-gradient) fixed;
}
ترفند این کار "آشکار کردن" رنگ پر پر جنب و جوش است. این کار با شیب Hard Stop در بالا انجام می شود. گرادیان تا درصد پر شدن شفاف است و پس از آن از رنگ سطح ردیف نشده استفاده می کند. در پشت آن سطح پر نشده ، یک رنگ کامل وجود دارد که منتظر شفافیت برای آشکار کردن آن است.
سبک پر کردن آهنگ
طراحی من برای حفظ سبک پر کردن به JavaScript نیاز دارد . فقط استراتژی های CSS وجود دارد ، اما آنها به عنصر انگشت شست همان ارتفاع مسیر نیاز دارند و من نتوانستم در آن محدودیت هارمونی پیدا کنم.
/* grab sliders on page */
const sliders = document.querySelectorAll('input[type="range"]')
/* take a slider element, return a percentage string for use in CSS */
const rangeToPercent = slider => {
const max = slider.getAttribute('max') || 10;
const percent = slider.value / max * 100;
return `${parseInt(percent)}%`;
};
/* on page load, set the fill amount */
sliders.forEach(slider => {
slider.style.setProperty('--track-fill', rangeToPercent(slider));
/* when a slider changes, update the fill prop */
slider.addEventListener('input', e => {
e.target.style.setProperty('--track-fill', rangeToPercent(e.target));
})
})
من فکر می کنم این باعث می شود یک ارتقاء تصویری خوب باشد. کشویی بدون JavaScript بسیار عالی عمل می کند ، --track-fill
لازم نیست ، در صورت عدم حضور ، به سادگی سبک پر نخواهد شد. اگر JavaScript در دسترس است ، در عین حال مشاهده هرگونه تغییر کاربر ، ویژگی های سفارشی را نیز جمع کنید و ویژگی سفارشی را با مقدار همگام سازی کنید.
در اینجا یک پست عالی در مورد CSS-Tricks توسط Ana Tudor وجود دارد ، که نشان دهنده یک راه حل فقط CSS برای پر کردن آهنگ است. من همچنین این عنصر range
را بسیار الهام بخش دیدم.
سبک های انگشت شست
input[type="range"]::-webkit-slider-thumb {
appearance: none; /* clear styles, make way for mine */
cursor: ew-resize; /* cursor style to support drag direction */
border: 3px solid var(--surface3);
block-size: var(--thumb-size);
inline-size: var(--thumb-size);
margin-top: var(--thumb-offset);
border-radius: 50%;
background: var(--brand-bg-gradient) fixed;
}
اکثر این سبک ها ایجاد یک دایره خوب هستند. مجدداً شیب پس زمینه ثابت را در آنجا مشاهده می کنید که رنگهای پویا انگشت شست ، آهنگ ها و عناصر SVG مرتبط را متحد می کند. من سبک های تعامل را جدا کردم تا به منزوی کردن تکنیک box-shadow
که برای برجسته شناور استفاده می شود ، جدا کنم:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
::-webkit-slider-thumb {
…
/* shadow spread is initally 0 */
box-shadow: 0 0 0 var(--thumb-highlight-size) var(--thumb-highlight-color);
/* if motion is OK, transition the box-shadow change */
@media (--motionOK) {
& {
transition: box-shadow .1s ease;
}
}
/* on hover/active state of parent, increase size prop */
@nest input[type="range"]:is(:hover,:active) & {
--thumb-highlight-size: 10px;
}
}
هدف برای بازخورد کاربر ، مدیریت آسان و انیمیشن برجسته بود. با استفاده از سایه جعبه می توانم از ایجاد طرح با اثر جلوگیری کنم. من این کار را با ایجاد سایه ای که مبهم نیست انجام می دهم و با شکل دایره ای عنصر انگشت شست مطابقت دارد. سپس من تغییر و انتقال آن اندازه گسترش آن در شناور است.
اگر فقط اثر برجسته در کادر انتخاب بسیار آسان بود ...
انتخاب کنندگان مرورگر صلیب
فهمیدم که برای دستیابی به قوام مرورگر متقاطع به این انتخاب کنندگان -webkit-
و -moz-
نیاز دارم:
input[type="range"] {
&::-webkit-slider-runnable-track {}
&::-moz-range-track {}
&::-webkit-slider-thumb {}
&::-moz-range-thumb {}
}
چک باکس سفارشی
با توجه به عنصر ورودی HTML زیر ، من به شما نشان خواهم داد که چگونه ظاهر آن را سفارشی کردم:
<input type="checkbox">
3 قسمت برای این عنصر وجود دارد که ما باید سفارشی کنیم:
عنصر کادر انتخاب
input[type="checkbox"] {
inline-size: var(--space-sm); /* increase width */
block-size: var(--space-sm); /* increase height */
outline-offset: 5px; /* focus style enhancement */
accent-color: var(--brand); /* tint the input */
position: relative; /* prepare for an absolute pseudo element */
transform-style: preserve-3d; /* create a 3d z-space stacking context */
margin: 0;
cursor: pointer;
}
سبک های transform-style
و position
برای شبه عنصر که بعداً معرفی خواهیم کرد تا سبک برجسته را معرفی کنیم. در غیر این صورت ، این بیشتر موارد سبک تفکر جزئی از من است. من دوست دارم که مکان نما نشانگر باشد ، من طلسم های کلی را دوست دارم ، کادر انتخاب پیش فرض خیلی ریز و درشت است و اگر accent-color
پشتیبانی می شود ، این کادرهای چک را به طرح رنگ برند وارد کنید.
برچسب های کادر انتخاب
تهیه برچسب برای کادر انتخاب به 2 دلیل مهم است. اولین مورد این است که نشان دهنده آنچه از مقدار کادر انتخاب استفاده می شود ، برای پاسخ به "روشن یا خاموش برای چه؟" دوم برای UX است ، کاربران وب عادت کرده اند که از طریق برچسب های مرتبط با کادر انتخاب خود در تعامل باشند.
<input type="checkbox" id="text-notifications" name="text-notifications" >
<label for="text-notifications"> <h3>Text Messages</h3> <small>Get notified about all text messages sent to your device</small> </label>
روی برچسب خود ، for
هایی را که به یک کادر انتخاب شده توسط شناسه نشان می دهد ، قرار دهید: <label for="text-notifications">
. در کادر انتخاب خود ، نام و شناسه را دو برابر کنید تا اطمینان حاصل کنید که با ابزارهای مختلف و فناوری ، مانند ماوس یا صفحه نمایشگر یافت می شود: <input type="checkbox" id="text-notifications" name="text-notifications">
. :hover
، :active
و بیشتر با اتصال به صورت رایگان همراه می شوند و روش های تعامل فرم شما را افزایش می دهند.
کادر انتخاب برجسته
من می خواهم رابط های خود را ثابت نگه دارم و عنصر کشویی دارای یک تصویر کوچک خوب است که می خواهم با کادر انتخاب استفاده کنم. تصویر کوچک قادر به استفاده box-shadow
بود و spread
آن برای مقیاس سایه به سمت بالا و پایین است. با این حال ، این اثر در اینجا کار نمی کند زیرا کادر انتخاب ما مربع هستند و باید باشند .
من توانستم با یک عنصر شبه و یک مقدار ناگوار از CSS پیچیده به همان اثر بصری دست یابم:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
input[type="checkbox"]::before {
--thumb-scale: .01; /* initial scale of highlight */
--thumb-highlight-size: var(--space-xl);
content: "";
inline-size: var(--thumb-highlight-size);
block-size: var(--thumb-highlight-size);
clip-path: circle(50%); /* circle shape */
position: absolute; /* this is why position relative on parent */
top: 50%; /* pop and plop technique (https://web.dev/centering-in-css#5-pop-and-plop) */
left: 50%;
background: var(--thumb-highlight-color);
transform-origin: center center; /* goal is a centered scaling circle */
transform: /* order here matters!! */
translateX(-50%) /* counter balances left: 50% */
translateY(-50%) /* counter balances top: 50% */
translateZ(-1px) /* PUTS IT BEHIND THE CHECKBOX */
scale(var(--thumb-scale)) /* value we toggle for animation */
;
will-change: transform;
@media (--motionOK) { /* transition only if motion is OK */
& {
transition: transform .2s ease;
}
}
}
/* on hover, set scale custom property to "in" state */
input[type="checkbox"]:hover::before {
--thumb-scale: 1;
}
ایجاد یک عنصر شبه دایره ای کار ساده ای است ، اما قرار دادن آن در پشت عنصری که به آن وصل شده است سخت تر بود. در اینجا قبل و بعد از رفع آن است:
این قطعاً یک تعامل میکرو است ، اما برای من مهم است که قوام بصری را حفظ کنم. تکنیک مقیاس بندی انیمیشن همان چیزی است که ما در جاهای دیگر استفاده کرده ایم. ما یک ویژگی سفارشی را به یک مقدار جدید تنظیم می کنیم و اجازه می دهیم CSS آن را بر اساس تنظیمات برگزیده حرکت منتقل کند. ویژگی اصلی در اینجا translateZ(-1px)
است. والدین یک فضای سه بعدی ایجاد کردند و این کودک شبه عنصر با قرار دادن خود در فضای z ، در آن قرار گرفت.
دسترسی
ویدیوی YouTube نمایش خوبی از تعامل ماوس ، صفحه کلید و صفحه نمایش برای این مؤلفه تنظیمات انجام می دهد. من برخی از جزئیات را در اینجا فراخوانی می کنم.
انتخاب عنصر HTML
<form>
<header>
<fieldset>
<picture>
<label>
<input>
هر یک از این موارد نکات و نکاتی را در مورد ابزار مرور کاربر در اختیار دارد. برخی از عناصر نکات متقابل را ارائه می دهند ، برخی از آنها تعامل را به هم متصل می کنند و برخی به شکل دادن به درخت دسترسی که یک صفحه نمایشگر در آن حرکت می کند ، کمک می کنند.
ویژگی های HTML
ما می توانیم عناصری را که مورد نیاز صفحه نمایش نیستند پنهان کنیم ، در این حالت نماد کنار کشویی:
<picture aria-hidden="true">
ویدیوی فوق نشان دهنده جریان ScreenReader در سیستم عامل Mac است. توجه کنید که چگونه تمرکز ورودی مستقیم از یک کشویی به حالت دیگر حرکت می کند. این امر به این دلیل است که ما نمادی را پنهان کرده ایم که ممکن است متوقف شده در راه کشویی بعدی باشد. بدون این ویژگی ، یک کاربر باید جلوی تصویری را که ممکن است نتوانند آن را متوقف کنند ، گوش دهند و حرکت کنند.
The SVG is a bunch of math, let's add a <title>
element for a free mouse hover title and a human readable comment about what the math is creating:
<svg viewBox="0 0 24 24">
<title>A note icon</title>
<path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/>
</svg>
Other than that, we've used enough clearly marked HTML, that the form tests really well across mouse, keyboard, video game controllers and screenreaders.
جاوا اسکریپت
I've already covered how the track fill color was being managed from JavaScript, so let's look at the <form>
related JavaScript now:
const form = document.querySelector('form');
form.addEventListener('input', event => {
const formData = Object.fromEntries(new FormData(form));
console.table(formData);
})
Everytime the form is interacted with and changed, the console logs the form as an object into a table for easy review before submitting to a server.
نتیجه گیری
Now that you know how I did it, how would you?! This makes for some fun component architecture! Who's going to make the 1st version with slots in their favorite framework? 🙂
Let's diversify our approaches and learn all the ways to build on the web. Create a demo, tweet me links, and I'll add it to the Community remixes section below!