Thông tin tổng quan cơ bản về cách tạo thành phần cài đặt của thanh trượt và hộp đánh dấu.
Trong bài đăng này, tôi muốn chia sẻ suy nghĩ về việc xây dựng một thành phần Cài đặt cho web có khả năng thích ứng, hỗ trợ nhiều phương thức nhập của thiết bị và hoạt động trên nhiều trình duyệt. Dùng thử bản minh hoạ.
Nếu bạn thích xem video hoặc muốn xem trước giao diện người dùng/trải nghiệm người dùng của ứng dụng mà chúng ta đang xây dựng, thì dưới đây là video hướng dẫn ngắn hơn trên YouTube:
Tổng quan
Tôi đã chia các khía cạnh của thành phần này thành các phần sau:
- Bố cục
- Màu
- Dữ liệu đầu vào của dải ô tuỳ chỉnh
- Thông tin đầu vào hộp đánh dấu tuỳ chỉnh
- Những điểm cần lưu ý về khả năng hỗ trợ tiếp cận
- JavaScript
Bố cục
Đây là bản minh hoạ đầu tiên của Thử thách về giao diện người dùng đồ hoạ (GUI) hoàn toàn sử dụng CSS Grid! Dưới đây là từng lưới được làm nổi bật bằng Chrome DevTools cho lưới:

Just for gap
Bố cục phổ biến nhất:
foo {
display: grid;
gap: var(--something);
}
Tôi gọi bố cục này là "chỉ để tạo khoảng trống" vì bố cục này chỉ sử dụng lưới để thêm khoảng trống giữa các khối.
Có 5 bố cục sử dụng chiến lược này, sau đây là tất cả các bố cục đó:

Phần tử fieldset chứa từng nhóm dữ liệu đầu vào (.fieldset-item) đang sử dụng gap: 1px để tạo đường viền mảnh giữa các phần tử. Không có giải pháp biên giới phức tạp!
.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); } } }
Tự xuống dòng dạng lưới tự nhiên
Bố cục phức tạp nhất là bố cục vĩ mô, hệ thống bố cục logic giữa <main> và <form>.
Căn giữa nội dung xuống dòng
Flexbox và lưới đều cung cấp khả năng align-items hoặc align-content, và khi xử lý các phần tử gói, các căn chỉnh bố cục content sẽ phân phối không gian giữa các phần tử con dưới dạng một nhóm.
main {
display: grid;
gap: var(--space-xl);
place-content: center;
}
Phần tử chính đang sử dụng place-content: center căn chỉnh
tốc ký để
các phần tử con được căn giữa theo chiều dọc và chiều ngang trong cả bố cục một và hai cột.
Hãy xem video ở trên để biết cách "nội dung" luôn nằm ở giữa, ngay cả khi đã xuống dòng.
Lặp lại minmax tự động điều chỉnh
<form> sử dụng bố cục lưới thích ứng cho mỗi phần.
Bố cục này chuyển từ một sang hai cột dựa trên không gian có sẵn.
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;
}
Lưới này có giá trị cho row-gap (--space-xl) khác với column-gap (--space-xxl) để tạo điểm nhấn tuỳ chỉnh cho bố cục thích ứng. Khi các cột xếp chồng lên nhau, chúng ta muốn có một khoảng trống lớn, nhưng không lớn như khi chúng ta đang ở trên màn hình rộng.
Thuộc tính grid-template-columns sử dụng 3 hàm CSS: repeat(), minmax() và min(). Una Kravets có một bài đăng trên blog về bố cục tuyệt vời về vấn đề này, gọi là RAM.
Có 3 phần bổ sung đặc biệt trong bố cục của chúng tôi, nếu bạn so sánh với bố cục của Una:
- Chúng ta truyền thêm một hàm
min(). - Chúng ta chỉ định
align-items: flex-start. - Có kiểu
max-width: 89vw.
Hàm min() bổ sung được Evan Minto mô tả chi tiết trên blog của họ trong bài đăng Intrinsically Responsive CSS Grid with minmax() and min() (Lưới CSS thích ứng nội tại với minmax() và min()). Bạn nên đọc bài đăng đó. Việc điều chỉnh căn chỉnh flex-start là để loại bỏ hiệu ứng kéo giãn mặc định, nhờ đó các thành phần con của bố cục này không cần phải có chiều cao bằng nhau, mà có thể có chiều cao tự nhiên, nội tại. Video trên YouTube này có thông tin chi tiết nhanh về việc bổ sung tính năng căn chỉnh này.
max-width: 89vw là một tính năng đáng được phân tích chi tiết trong bài đăng này.
Hãy để tôi cho bạn xem bố cục khi áp dụng và không áp dụng kiểu:
Chuyện gì đang xảy ra? Khi max-width được chỉ định, nó sẽ cung cấp ngữ cảnh,
kích thước rõ ràng hoặc kích thước
xác định cho auto-fit
thuật toán bố cục để biết
số lần lặp lại mà nó có thể phù hợp với không gian. Mặc dù có vẻ rõ ràng là không gian này có "chiều rộng đầy đủ", nhưng theo thông số kỹ thuật của lưới CSS, bạn phải cung cấp kích thước hoặc kích thước tối đa xác định. Tôi đã cung cấp kích thước tối đa.
Vậy thì tại sao bạn nên chọn 89vw? Vì "nó phù hợp" với bố cục của tôi.
Tôi và một số người khác trong nhóm Chrome đang điều tra lý do tại sao một giá trị hợp lý hơn,
chẳng hạn như 100vw, lại không đủ và liệu đây có thực sự là lỗi hay không.
Giãn cách
Sự hài hoà của bố cục này chủ yếu đến từ một bảng khoảng cách giới hạn, chính xác là 7.
:root {
--space-xxs: .25rem;
--space-xs: .5rem;
--space-sm: 1rem;
--space-md: 1.5rem;
--space-lg: 2rem;
--space-xl: 3rem;
--space-xxl: 6rem;
}
Việc sử dụng các quy tắc này rất phù hợp với lưới, CSS @nest và cú pháp cấp 5 của @media. Sau đây là ví dụ về bộ kiểu bố cục <main> đầy đủ.
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);
}
}
}
Một lưới có nội dung ở giữa, được đệm vừa phải theo mặc định (như trên thiết bị di động). Nhưng khi có thêm không gian khung nhìn, nội dung sẽ trải rộng ra bằng cách tăng khoảng đệm. CSS năm 2021 có vẻ khá ổn!
Bạn còn nhớ bố cục trước đó, "chỉ để tạo khoảng trống" không? Sau đây là phiên bản hoàn chỉnh hơn về giao diện của các thành phần này:
header {
display: grid;
gap: var(--space-xxs);
}
section {
display: grid;
gap: var(--space-md);
}
Màu
Việc sử dụng màu sắc có kiểm soát giúp thiết kế này nổi bật, vừa biểu cảm vừa tối giản. Tôi làm như sau:
: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);
}
Tôi đặt tên cho màu nền và màu văn bản bằng số thay vì tên như
surface-dark và surface-darker vì trong truy vấn đa phương tiện, tôi sẽ lật
chúng, và sáng và tối sẽ không có ý nghĩa.
Tôi lật chúng trong một truy vấn phương tiện ưu tiên như sau:
: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);
}
}
}
Bạn cần nắm được bức tranh tổng thể và chiến lược trước khi đi sâu vào chi tiết cú pháp màu. Nhưng vì tôi đã đi hơi xa, nên hãy để tôi quay lại một chút.
LCH?
Không đi quá sâu vào lý thuyết màu sắc, LCH là một cú pháp hướng đến con người, phục vụ cho cách chúng ta cảm nhận màu sắc, chứ không phải cách chúng ta đo lường màu sắc bằng toán học (như 255). Điều này mang lại lợi thế rõ rệt vì con người có thể viết dễ dàng hơn và những người khác sẽ hiểu được những điều chỉnh này.
Hôm nay, trong bản minh hoạ này, hãy tập trung vào cú pháp và các giá trị mà tôi đang lật để tạo chế độ sáng và tối. Hãy xem xét 1 màu nền và 1 màu văn bản:
: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) chuyển thành độ sáng 10%, sắc độ 0 và sắc thái 0: màu xám không màu rất tối. Sau đó, trong truy vấn phương tiện cho chế độ sáng, độ sáng được chuyển sang 90% bằng --surface1: lch(90 0 0);. Và đó là nội dung chính của chiến lược này. Bắt đầu bằng cách chỉ thay đổi độ sáng giữa 2 giao diện, duy trì tỷ lệ tương phản mà thiết kế yêu cầu hoặc những gì có thể duy trì khả năng hỗ trợ tiếp cận.
Điểm cộng khi dùng lch() ở đây là độ sáng hướng đến con người và chúng ta có thể cảm thấy hài lòng về sự thay đổi % đối với độ sáng, rằng sự thay đổi % đó sẽ nhất quán và có thể cảm nhận được. Ví dụ: hsl() không đáng tin cậy.
Bạn có thể tìm hiểu thêm về không gian màu sắc và lch() nếu quan tâm. Sắp đến lúc rồi!
CSS hiện không thể truy cập vào những màu này. Tôi xin nhắc lại: Chúng ta không thể sử dụng 1/3 số màu trong hầu hết các màn hình hiện đại. Và đây không chỉ là màu sắc bất kỳ, mà là màu sắc sống động nhất mà màn hình có thể hiển thị. Trang web của chúng ta bị mờ vì phần cứng màn hình phát triển nhanh hơn thông số kỹ thuật CSS và cách triển khai trình duyệt.
Lea Verou
Điều khiển biểu mẫu thích ứng bằng bảng phối màu
Nhiều trình duyệt có các chế độ kiểm soát giao diện tối, hiện tại là Safari và Chromium, nhưng bạn phải chỉ định trong CSS hoặc HTML rằng thiết kế của bạn sử dụng các chế độ đó.
Phần trên minh hoạ hiệu ứng của thuộc tính trong bảng điều khiển Kiểu của Công cụ cho nhà phát triển. Bản minh hoạ sử dụng thẻ HTML, theo tôi thì đây thường là vị trí phù hợp hơn:
<meta name="color-scheme" content="dark light">
Tìm hiểu tất cả về API này trong color-schemebài viết này của Thomas Steiner. Còn nhiều điều khác để khám phá
ngoài các hộp đánh dấu tối!
CSS accent-color
Gần đây, có một số hoạt động liên quan đến accent-color trên các phần tử biểu mẫu, đây là một kiểu CSS duy nhất có thể thay đổi màu sắc được dùng trong phần tử nhập của trình duyệt. Đọc thêm về vấn đề này tại đây trên GitHub. Tôi đã đưa nó vào
kiểu của mình cho thành phần này. Vì trình duyệt hỗ trợ, nên các Hộp đánh dấu của tôi sẽ phù hợp hơn với giao diện có màu hồng và tím nổi bật màu.
input[type="checkbox"] {
accent-color: var(--brand);
}

Màu sắc nổi bật với dải chuyển màu cố định và trạng thái focus-within
Màu sắc sẽ nổi bật nhất khi được sử dụng một cách tiết kiệm và một trong những cách tôi thích để đạt được điều đó là thông qua các hoạt động tương tác trên giao diện người dùng đầy màu sắc.
Có nhiều lớp phản hồi và tương tác trên giao diện người dùng trong video trên, giúp tạo nên cá tính cho hoạt động tương tác bằng cách:
- Nêu bật bối cảnh.
- Cung cấp ý kiến phản hồi về giao diện người dùng về "mức độ đầy đủ" của giá trị trong phạm vi.
- Cung cấp phản hồi về giao diện người dùng cho biết một trường đang chấp nhận dữ liệu đầu vào.
Để cung cấp ý kiến phản hồi khi một phần tử đang được tương tác, CSS sẽ sử dụng lớp giả :focus-within để thay đổi giao diện của nhiều phần tử. Hãy cùng phân tích .fieldset-item, đây là một lớp giả rất thú vị:
.fieldset-item {
...
&:focus-within {
background: var(--surface2);
& svg {
fill: white;
}
& picture {
clip-path: circle(50%);
background: var(--brand-bg-gradient) fixed;
}
}
}
Khi một trong các phần tử con của phần tử này có focus-within:
- Nền
.fieldset-itemđược chỉ định màu nền có độ tương phản cao hơn. svglồng nhau được tô màu trắng để có độ tương phản cao hơn.<picture>clip-pathlồng ghép mở rộng thành một vòng tròn đầy đủ và nền được lấp đầy bằng dải chuyển màu cố định sáng.
Phạm vi tùy chỉnh
Với phần tử đầu vào HTML sau đây, tôi sẽ cho bạn thấy cách tôi tuỳ chỉnh giao diện của phần tử đó:
<input type="range">
Có 3 phần của phần tử này mà chúng ta cần tuỳ chỉnh:
Kiểu phần tử phạm vi
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 */
}
Vài dòng đầu tiên của CSS là các phần tuỳ chỉnh của kiểu và tôi hy vọng rằng việc gắn nhãn rõ ràng cho các phần đó sẽ giúp ích cho bạn. Các kiểu còn lại chủ yếu là kiểu đặt lại, để cung cấp nền tảng nhất quán cho việc xây dựng các phần phức tạp của thành phần.
Kiểu kênh
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;
}
Mẹo để làm việc này là "hiển thị" màu nền rực rỡ. Bạn có thể thực hiện việc này bằng cách dùng dải chuyển màu có điểm dừng cứng ở trên cùng. Màu chuyển tiếp sẽ trong suốt cho đến khi đạt tỷ lệ lấp đầy, sau đó sẽ sử dụng màu nền của thanh tiến trình chưa được lấp đầy. Đằng sau vùng hiển thị chưa được lấp đầy đó là một màu có chiều rộng đầy đủ, đang chờ độ trong suốt để hiển thị.
Kiểu màu nền của thanh trượt
Thiết kế của tôi yêu cầu JavaScript để duy trì kiểu tô. Có các chiến lược chỉ dành cho CSS nhưng chúng yêu cầu phần tử thumb phải có cùng chiều cao với track và tôi không thể tìm thấy sự hài hoà trong các giới hạn đó.
/* 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));
})
})
Tôi nghĩ điều này giúp nâng cấp hình ảnh một cách đẹp mắt. Thanh trượt hoạt động hiệu quả mà không cần JavaScript, thuộc tính --track-fill không bắt buộc, chỉ đơn giản là sẽ không có kiểu lấp đầy nếu không có. Nếu có JavaScript, hãy điền thuộc tính tuỳ chỉnh, đồng thời quan sát mọi thay đổi của người dùng, đồng bộ hoá thuộc tính tuỳ chỉnh với giá trị.
Dưới đây là một bài đăng hay trên CSS-Tricks của Ana Tudor, minh hoạ một giải pháp chỉ dùng CSS để tô màu thanh trượt. Tôi cũng thấy
phần tử range này rất truyền cảm hứng.
Kiểu nút trượt
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;
}
Phần lớn các kiểu này là để tạo một vòng tròn đẹp mắt.
Một lần nữa, bạn sẽ thấy dải chuyển màu nền cố định giúp hợp nhất
màu động của nút kéo, dải và các phần tử SVG liên quan.
Tôi đã tách riêng các kiểu cho hoạt động tương tác để giúp tách biệt kỹ thuật box-shadow đang được dùng cho hiệu ứng làm nổi bật khi di chuột:
@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;
}
}
Mục tiêu là tạo ra một điểm nhấn trực quan dễ quản lý và sinh động cho ý kiến phản hồi của người dùng. Bằng cách sử dụng bóng hộp, tôi có thể tránh kích hoạt bố cục bằng hiệu ứng. Tôi thực hiện việc này bằng cách tạo một bóng không bị mờ và khớp với hình tròn của phần tử thumb. Sau đó, tôi thay đổi và chuyển đổi kích thước trải rộng của bóng đổ khi di chuột.
Giá mà hiệu ứng làm nổi bật cũng dễ dàng như vậy trên hộp đánh dấu…
Bộ chọn trên nhiều trình duyệt
Tôi nhận thấy mình cần các bộ chọn -webkit- và -moz- này để đạt được tính nhất quán trên nhiều trình duyệt:
input[type="range"] {
&::-webkit-slider-runnable-track {}
&::-moz-range-track {}
&::-webkit-slider-thumb {}
&::-moz-range-thumb {}
}
Hộp đánh dấu tuỳ chỉnh
Với phần tử đầu vào HTML sau đây, tôi sẽ cho bạn thấy cách tôi tuỳ chỉnh giao diện của phần tử đó:
<input type="checkbox">
Có 3 phần của phần tử này mà chúng ta cần tuỳ chỉnh:
Phần tử hộp đánh dấu
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;
}
Kiểu transform-style và position chuẩn bị cho phần tử giả mà chúng ta sẽ giới thiệu sau để tạo kiểu cho phần đánh dấu. Nếu không, thì hầu hết là
những vấn đề nhỏ về phong cách theo ý kiến của tôi. Tôi muốn con trỏ là con trỏ, tôi thích độ lệch đường viền, hộp đánh dấu mặc định quá nhỏ và nếu accent-color được hỗ trợ, hãy đưa các hộp đánh dấu này vào bảng phối màu của thương hiệu.
Nhãn hộp đánh dấu
Bạn cần cung cấp nhãn cho hộp đánh dấu vì 2 lý do. Đầu tiên là để thể hiện giá trị của hộp đánh dấu được dùng cho mục đích gì, để trả lời câu hỏi "bật hay tắt cho cái gì?" Thứ hai là về trải nghiệm người dùng, người dùng web đã quen với việc tương tác với hộp đánh dấu thông qua nhãn liên kết của họ.
<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>
Trên nhãn, hãy đặt một thuộc tính for trỏ đến hộp đánh dấu theo mã nhận dạng: <label for="text-notifications">. Trên hộp đánh dấu, hãy nhân đôi cả tên và mã nhận dạng để đảm bảo hộp đánh dấu này được tìm thấy bằng nhiều công cụ và công nghệ, chẳng hạn như chuột hoặc trình đọc màn hình:
<input type="checkbox" id="text-notifications" name="text-notifications">.
:hover, :active và nhiều tính năng khác được cung cấp miễn phí khi kết nối, giúp tăng
số cách người dùng có thể tương tác với biểu mẫu của bạn.
Đánh dấu hộp đánh dấu
Tôi muốn giữ cho giao diện của mình nhất quán và phần tử thanh trượt có một điểm đánh dấu hình thu nhỏ đẹp mắt mà tôi muốn sử dụng với hộp đánh dấu. Hình thu nhỏ có thể sử dụng box-shadow và thuộc tính spread của hình thu nhỏ để tăng và giảm tỷ lệ bóng. Tuy nhiên, hiệu ứng đó không hoạt động ở đây vì các hộp đánh dấu của chúng ta và nên có hình vuông.
Tôi có thể đạt được hiệu ứng hình ảnh tương tự bằng một phần tử giả và một lượng CSS phức tạp không mong muốn:
@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;
}
Việc tạo một phần tử giả hình tròn là công việc đơn giản, nhưng việc đặt phần tử đó phía sau phần tử được đính kèm sẽ khó hơn. Đây là trước và sau khi tôi sửa nó:
Đây chắc chắn là một hoạt động tương tác vi mô, nhưng điều quan trọng đối với tôi là duy trì tính nhất quán về hình ảnh. Kỹ thuật điều chỉnh tỷ lệ ảnh động cũng giống như kỹ thuật chúng ta đã sử dụng ở những nơi khác. Chúng tôi đặt một thuộc tính tuỳ chỉnh thành một giá trị mới và cho phép CSS chuyển đổi thuộc tính đó dựa trên lựa chọn ưu tiên về chuyển động. Tính năng chính ở đây là translateZ(-1px). Phần tử mẹ đã tạo không gian 3D và phần tử giả con này đã khai thác không gian đó bằng cách đặt chính nó lùi lại một chút trong không gian z.
Hỗ trợ tiếp cận
Video trên YouTube minh hoạ rất rõ các hoạt động tương tác bằng chuột, bàn phím và trình đọc màn hình cho thành phần cài đặt này. Tôi sẽ nêu ra một số thông tin chi tiết tại đây.
Lựa chọn phần tử HTML
<form>
<header>
<fieldset>
<picture>
<label>
<input>
Mỗi gợi ý này chứa các gợi ý và mẹo cho công cụ duyệt web của người dùng. Một số phần tử cung cấp gợi ý tương tác, một số phần tử kết nối khả năng tương tác và một số phần tử giúp định hình cây hỗ trợ tiếp cận mà trình đọc màn hình điều hướng.
Thuộc tính HTML
Chúng ta có thể ẩn các phần tử mà trình đọc màn hình không cần đến, trong trường hợp này là biểu tượng bên cạnh thanh trượt:
<picture aria-hidden="true">
Video trên minh hoạ quy trình của trình đọc màn hình trên Mac OS. Hãy để ý cách tiêu điểm đầu vào di chuyển thẳng từ thanh trượt này sang thanh trượt tiếp theo. Điều này là do chúng tôi đã ẩn biểu tượng có thể là điểm dừng trên đường đến thanh trượt tiếp theo. Nếu không có thuộc tính này, người dùng sẽ cần dừng lại, nghe và di chuyển qua hình ảnh mà họ có thể không nhìn thấy.
SVG là một loạt phép toán, hãy thêm phần tử <title> để có tiêu đề di chuột miễn phí và nhận xét mà con người có thể đọc được về nội dung mà phép toán đang tạo:
<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>
Ngoài ra, chúng tôi đã sử dụng đủ HTML được đánh dấu rõ ràng để biểu mẫu kiểm thử thực sự hiệu quả trên chuột, bàn phím, tay điều khiển trò chơi điện tử và trình đọc màn hình.
JavaScript
Tôi đã giải thích cách quản lý màu nền của thanh trượt bằng JavaScript,
nên giờ hãy xem JavaScript liên quan đến <form>:
const form = document.querySelector('form');
form.addEventListener('input', event => {
const formData = Object.fromEntries(new FormData(form));
console.table(formData);
})
Mỗi khi biểu mẫu được tương tác và thay đổi, bảng điều khiển sẽ ghi lại biểu mẫu dưới dạng một đối tượng vào bảng để dễ dàng xem xét trước khi gửi đến máy chủ.

Kết luận
Giờ thì bạn đã biết cách tôi làm, vậy bạn sẽ làm thế nào?! Điều này tạo nên một cấu trúc thành phần thú vị! Ai sẽ là người tạo phiên bản đầu tiên có khe trong khung yêu thích của họ? 🙂
Hãy đa dạng hoá các phương pháp tiếp cận và tìm hiểu mọi cách để xây dựng trên web. Hãy tạo một bản minh hoạ, tweet cho tôi các đường liên kết và tôi sẽ thêm bản minh hoạ đó vào phần Bản phối lại của cộng đồng bên dưới!
Bản phối lại của cộng đồng
- @tomayac với phong cách của họ về vùng di chuột cho nhãn hộp đánh dấu! Phiên bản này không có khoảng trống khi di chuột giữa các phần tử: bản minh hoạ và nguồn.