Tổng quan cơ bản về cách tạo các thành phần FAB thích ứng với màu sắc, thích ứng và dễ tiếp cận.
Trong bài đăng này, tôi muốn chia sẻ suy nghĩ của mình về cách tạo các thành phần FAB thích ứng với màu sắc, phản hồi và hỗ trợ tiếp cận. Dùng thử bản minh hoạ và xem mã nguồn!
Nếu bạn thích xem video, hãy xem phiên bản video của bài đăng này trên YouTube:
Tổng quan
FAB phổ biến hơn trên thiết bị di động so với máy tính, nhưng chúng cũng phổ biến trong cả hai trường hợp. Các nút này giúp hiển thị các thao tác chính, giúp thao tác thuận tiện và có mặt ở mọi nơi. Kiểu trải nghiệm người dùng này được Material UI phổ biến và bạn có thể xem các đề xuất về cách sử dụng và vị trí của họ tại đây.
Phần tử và kiểu
HTML cho các thành phần điều khiển này bao gồm một phần tử vùng chứa và một nhóm gồm một hoặc nhiều nút. Vùng chứa đặt các FAB trong khung nhìn và quản lý khoảng trống giữa các nút. Các nút có thể là nút nhỏ hoặc nút mặc định, tạo ra sự đa dạng giữa các thao tác chính và thao tác phụ.
Vùng chứa FAB
Phần tử này có thể là một <div>
thông thường, nhưng hãy giúp người dùng khiếm thị bằng cách gắn thẻ cho phần tử đó bằng một số thuộc tính hữu ích để giải thích mục đích và nội dung của vùng chứa này.
Mã đánh dấu FAB
Bắt đầu với một lớp .fabs
để CSS có thể liên kết với kiểu, sau đó thêm role="group"
và aria-label
để không chỉ là một vùng chứa chung, mà còn được đặt tên và có mục đích.
<div class="fabs" role="group" aria-label="Floating action buttons">
<!-- buttons will go here -->
</div>
Kiểu FAB
Để thuận tiện, các FAB luôn nằm trong khung nhìn.
Đây là một trường hợp sử dụng tuyệt vời cho vị trí fixed
. Trong vị trí khung nhìn này, tôi đã chọn sử dụng inset-block
và inset-inline
để vị trí này sẽ bổ sung cho chế độ tài liệu của người dùng, chẳng hạn như từ phải sang trái hoặc từ trái sang phải. Các thuộc tính tuỳ chỉnh cũng được dùng để ngăn chặn việc lặp lại và đảm bảo khoảng cách bằng nhau từ cạnh dưới cùng và cạnh bên của khung nhìn:
.fabs {
--_viewport-margin: 2.5vmin;
position: fixed;
z-index: var(--layer-1);
inset-block: auto var(--_viewport-margin);
inset-inline: auto var(--_viewport-margin);
}
Tiếp theo, tôi sẽ cung cấp màn hình vùng chứa flex
và thay đổi hướng bố cục thành column-reverse
.
Thao tác này sẽ xếp chồng các phần tử con lên nhau (cột) và cũng đảo ngược thứ tự hình ảnh của các phần tử con. Điều này sẽ khiến phần tử có thể lấy tiêu điểm đầu tiên trở thành phần tử dưới cùng thay vì phần tử trên cùng, đây là nơi tiêu điểm thường chuyển đến trong tài liệu HTML. Việc đảo ngược thứ tự hình ảnh sẽ hợp nhất trải nghiệm cho người dùng khiếm thị và người dùng bàn phím, vì kiểu của thao tác chính lớn hơn các nút nhỏ cho người dùng khiếm thị biết đó là thao tác chính và người dùng bàn phím sẽ lấy đó làm mục đầu tiên trong nguồn.
.fabs {
…
display: flex;
flex-direction: column-reverse;
place-items: center;
gap: var(--_viewport-margin);
}
Việc căn giữa được xử lý bằng place-items
và gap
sẽ thêm khoảng trống giữa mọi nút FAB được đặt trong vùng chứa.
Nút hành động nổi (FAB)
Đã đến lúc tạo kiểu cho một số nút để trông như chúng đang nổi lên trên mọi thứ.
Nút hành động nổi mặc định
Nút đầu tiên để tạo kiểu là nút mặc định. Đây sẽ là cơ sở cho tất cả các nút FAB. Sau đó, chúng ta sẽ tạo một biến thể có giao diện thay thế trong khi sửa đổi ít kiểu cơ sở này nhất có thể.
Mã đánh dấu FAB
Phần tử <button>
là lựa chọn phù hợp. Chúng ta sẽ bắt đầu với lớp này làm cơ sở vì lớp này mang lại trải nghiệm người dùng tuyệt vời với chuột, cảm ứng và bàn phím. Khía cạnh quan trọng nhất của mã đánh dấu này là ẩn biểu tượng khỏi người dùng trình đọc màn hình bằng aria-hidden="true"
và thêm văn bản nhãn cần thiết vào chính mã đánh dấu <button>
. Khi thêm nhãn trong những trường hợp này, tôi cũng muốn thêm title
để người dùng chuột có thể nhận được thông tin về nội dung mà biểu tượng muốn truyền đạt.
<button data-icon="plus" class="fab" title="Add new action" aria-label="Add new action">
<svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">...</svg>
</button>
Kiểu FAB
Trước tiên, hãy biến nút này thành một nút tròn có đệm với bóng đổ mạnh, vì đây là những đặc điểm xác định đầu tiên của nút:
.fab {
--_size: 2rem;
padding: calc(var(--_size) / 2);
border-radius: var(--radius-round);
aspect-ratio: 1;
box-shadow: var(--shadow-4);
}
Tiếp theo, hãy thêm màu. Chúng ta sẽ sử dụng một chiến lược mà chúng ta đã sử dụng trong các Thử thách GUI trước đây. Tạo một nhóm thuộc tính tuỳ chỉnh được đặt tên rõ ràng để lưu giữ tĩnh màu sáng và màu tối, sau đó một thuộc tính tuỳ chỉnh thích ứng sẽ được đặt thành biến sáng hoặc tối tuỳ thuộc vào lựa chọn ưu tiên của người dùng về màu sắc trên hệ thống:
.fab {
…
/* light button and button hover */
--_light-bg: var(--pink-6);
--_light-bg-hover: var(--pink-7);
/* dark button and button hover */
--_dark-bg: var(--pink-4);
--_dark-bg-hover: var(--pink-3);
/* adaptive variables set to light by default */
--_bg: var(--_light-bg);
/* static icon colors set to the adaptive foreground variable */
--_light-fg: white;
--_dark-fg: black;
--_fg: var(--_light-fg);
/* use the adaptive properties on some styles */
background: var(--_bg);
color: var(--_fg);
&:is(:active, :hover, :focus-visible) {
--_bg: var(--_light-bg-hover);
@media (prefers-color-scheme: dark) {
--_bg: var(--_dark-bg-hover);
}
}
/* if users prefers dark, set adaptive props to dark */
@media (prefers-color-scheme: dark) {
--_bg: var(--_dark-bg);
--_fg: var(--_dark-fg);
}
}
Tiếp theo, hãy thêm một số kiểu để giúp biểu tượng SVG vừa với không gian.
.fab {
…
& > svg {
inline-size: var(--_size);
block-size: var(--_size);
stroke-width: 3px;
}
}
Cuối cùng, hãy xoá phần đánh dấu nhấn khỏi nút vì chúng ta đã thêm phản hồi hình ảnh riêng cho hoạt động tương tác:
.fab {
-webkit-tap-highlight-color: transparent;
}
FAB thu nhỏ
Mục tiêu của phần này là tạo một biến thể cho nút FAB. Bằng cách làm cho một số FAB nhỏ hơn hành động mặc định, chúng ta có thể quảng bá hành động mà người dùng thực hiện thường xuyên nhất.
Mã đánh dấu FAB thu nhỏ
HTML giống với FAB nhưng chúng ta thêm một lớp ".mini" để cung cấp cho CSS một móc vào biến thể.
<button data-icon="heart" class="fab mini" title="Like action" aria-label="Like action">
<svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">...</svg>
</button>
Kiểu FAB thu nhỏ
Nhờ sử dụng các thuộc tính tuỳ chỉnh, bạn chỉ cần điều chỉnh biến --_size
.
.fab.mini {
--_size: 1.25rem;
}
Hỗ trợ tiếp cận
Phần quan trọng nhất cần nhớ đối với khả năng hỗ trợ tiếp cận bằng FAB là vị trí trong luồng bàn phím của trang. Bản minh hoạ này chỉ có các FAB, không có gì để cạnh tranh về thứ tự và luồng bàn phím, nghĩa là bản minh hoạ này không có cơ hội để thể hiện một luồng bàn phím có ý nghĩa. Trong trường hợp có các phần tử cạnh tranh để lấy tiêu điểm, bạn nên suy nghĩ kỹ về vị trí trong luồng đó mà người dùng sẽ thấy mình đang chuyển sang luồng nút FAB.
Sau khi người dùng đặt tiêu điểm vào vùng chứa FAB, chúng ta đã thêm role="group"
và aria-label="floating action buttons"
để thông báo cho người dùng trình đọc màn hình về nội dung của những gì họ đã đặt tiêu điểm. Về chiến lược, tôi đã đặt FAB mặc định trước tiên để người dùng tìm thấy hành động chính trước tiên. Sau đó, tôi sử dụng flex-direction: column-reverse;
để sắp xếp trực quan nút chính ở dưới cùng, gần với các ngón tay của người dùng để dễ dàng truy cập. Đây là một chiến thắng tuyệt vời vì nút mặc định nổi bật về mặt hình ảnh và cũng là nút đầu tiên cho người dùng bàn phím, mang lại cho họ trải nghiệm rất giống nhau.
Cuối cùng, đừng quên ẩn biểu tượng của bạn khỏi người dùng trình đọc màn hình và đảm bảo bạn cung cấp nhãn cho nút để người dùng biết được nút đó là gì. Việc này đã được thực hiện trong HTML bằng aria-hidden="true"
trên <svg>
và aria-label="Some action"
trên <button>
.
Hoạt ảnh
Bạn có thể thêm nhiều loại ảnh động để nâng cao trải nghiệm người dùng. Giống như trong các Thử thách GUI khác, chúng ta sẽ thiết lập một số thuộc tính tuỳ chỉnh để lưu giữ ý định về trải nghiệm giảm chuyển động và trải nghiệm chuyển động đầy đủ. Theo mặc định, các kiểu sẽ giả định người dùng muốn giảm chuyển động, sau đó sử dụng truy vấn nội dung đa phương tiện prefers-reduced-motion
để hoán đổi giá trị chuyển đổi thành chuyển động đầy đủ.
Chiến lược giảm chuyển động có thuộc tính tuỳ chỉnh
Ba thuộc tính tuỳ chỉnh được tạo trong CSS sau: --_motion-reduced
, --_motion-ok
và --_transition
. Hai biến đầu tiên chứa các hiệu ứng chuyển đổi phù hợp dựa trên lựa chọn ưu tiên của người dùng và biến cuối cùng --_transition
sẽ được đặt thành --_motion-reduced
hoặc --_motion-ok
tương ứng.
.fab {
/* box-shadow and background-color can safely be transitioned for reduced motion users */
--_motion-reduced:
box-shadow .2s var(--ease-3),
background-color .3s var(--ease-3);
/* add transform and outline-offset for users ok with motion */
--_motion-ok:
var(--_motion-reduced),
transform .2s var(--ease-3),
outline-offset 145ms var(--ease-2);
/* default the transition styles to reduced motion */
--_transition: var(--_motion-reduced);
/* set the transition to our adaptive transition custom property*/
transition: var(--_transition);
/* if motion is ok, update the adaptive prop to the respective transition prop */
@media (prefers-reduced-motion: no-preference) {
--_transition: var(--_motion-ok);
}
}
Khi đã thực hiện những bước trên, bạn có thể chuyển đổi các thay đổi đối với box-shadow
, background-color
, transform
và outline-offset
, cung cấp cho người dùng phản hồi giao diện người dùng tốt đẹp về việc hệ thống đã nhận được hoạt động tương tác của họ.
Tiếp theo, hãy thêm một chút tinh tế vào trạng thái :active
bằng cách điều chỉnh translateY
một chút, điều này sẽ tạo cho nút một hiệu ứng nhấn đẹp mắt:
.fab {
…
&:active {
@media (prefers-reduced-motion: no-preference) {
transform: translateY(2%);
}
}
}
Cuối cùng, hãy chuyển đổi mọi thay đổi đối với biểu tượng SVG trong các nút:
.fab {
…
&[data-icon="plus"]:hover > svg {
transform: rotateZ(.25turn);
}
& > svg {
@media (prefers-reduced-motion: no-preference) {
will-change: transform;
transition: transform .5s var(--ease-squish-3);
}
}
}
Kết luận
Giờ thì bạn đã biết cách tôi làm, còn bạn thì sao‽ 🙂
Hãy đa dạng hoá các phương pháp và tìm hiểu tất cả các cách xây dựng trên web.
Hãy tạo bản minh hoạ, gửi đường liên kết cho tôi trên Twitter và tôi sẽ thêm bản minh hoạ đó vào phầ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
Chưa có nội dung nào.
Tài nguyên
- Mã nguồn trên GitHub