Tổng quan cơ bản về cách tạo các thành phần <button>
thích ứng màu, phản hồi 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 ra màu sắc thích ứng,
và có khả năng thích ứng cao <button>
.
Thử bản minh hoạ và xem
nguồn
Nếu bạn thích xem video hơn, sau đây là phiên bản của bài đăng này trên YouTube:
Tổng quan
Chiến lược phát hành đĩa đơn
<button>
được xây dựng để tương tác của người dùng. Sự kiện click
của nó kích hoạt từ bàn phím,
chuột, chạm, giọng nói, v.v. với các quy tắc thông minh về
thời gian. Điều này cũng đi kèm
với một số kiểu mặc định trong mỗi trình duyệt, để bạn có thể sử dụng trực tiếp mà không cần
bất kỳ tuỳ chỉnh nào. Sử dụng color-scheme
để chọn
vào cả nút sáng và tối do trình duyệt cung cấp.
Ngoài ra còn có các loại
các nút,
mỗi thành phần được hiển thị trong mã nhúng Codepen trước đó. <button>
không có loại sẽ
thích ứng với việc nằm trong <form>
, thay đổi thành loại gửi.
<!-- buttons -->
<button></button>
<button type="submit"></button>
<button type="button"></button>
<button type="reset"></button>
<!-- button state -->
<button disabled></button>
<!-- input buttons -->
<input type="button" />
<input type="file">
Trong Thử thách GUI của tháng này, mỗi nút sẽ nhận được các kiểu để giúp phân biệt ý định của chúng một cách trực quan. Đặt lại các nút sẽ có màu cảnh báo vì chúng có tính phá hoại và gửi các nút sẽ nhận được văn bản có màu xanh dương, nên chúng được quảng bá nhiều hơn một chút so với bình thường các nút.
Các nút cũng có lớp giả
để CSS sử dụng cho việc tạo kiểu. Các lớp này cung cấp hook CSS để tuỳ chỉnh
cảm giác của nút: :hover
khi chuột nằm trên nút,
:active
khi chuột
hoặc bàn phím đang nhấn và
:focus
hoặc
:focus-visible
để hỗ trợ việc tạo kiểu cho công nghệ hỗ trợ.
button:hover {}
button:active {}
button:focus {}
button:focus-visible {}
Markup (note: đây là tên ứng dụng)
Ngoài các loại nút do đặc tả HTML cung cấp, tôi đã thêm một
nút có một biểu tượng và một nút có lớp tuỳ chỉnh btn-custom
.
<button>Default</button>
<input type="button" value="<input>"/>
<button>
<svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true">
<path d="..." />
</svg>
Icon
</button>
<button type="submit">Submit</button>
<button type="button">Type Button</button>
<button type="reset">Reset</button>
<button disabled>Disabled</button>
<button class="btn-custom">Custom</button>
<input type="file">
Sau đó, để kiểm thử, mỗi nút được đặt bên trong một biểu mẫu. Bằng cách này, tôi có thể đảm bảo các kiểu được cập nhật phù hợp cho nút mặc định, nút này hoạt động như một gửi. Tôi cũng chuyển đổi chiến lược biểu tượng, từ SVG cùng dòng sang SVG bị che khuất, để đảm bảo cả hai đều hoạt động hiệu quả như nhau.
<form>
<button>Default</button>
<input type="button" value="<input>"/>
<button>Icon <span data-icon="cloud"></span></button>
<button type="submit">Submit</button>
<button type="button">Type Button</button>
<button type="reset">Reset</button>
<button disabled>Disabled</button>
<button class="btn-custom btn-large" type="button">Large Custom</button>
<input type="file">
</form>
Hiện tại, ma trận kết hợp khá là quá choáng ngợp. Nút Giữa loại, lớp giả và ở trong hoặc ngoài một biểu mẫu, có hơn 20 để kết hợp các nút. Đây là một điều hữu ích khi CSS có thể giúp chúng ta trình bày rõ ràng chúng một cách rõ ràng!
Hỗ trợ tiếp cận
Các thành phần nút có thể truy cập được một cách tự nhiên, nhưng có một số các tính năng nâng cao.
Di chuột và lấy nét cùng nhau
Tôi muốn nhóm :hover
và :focus
cùng với chức năng :is()
bộ chọn giả. Điều này giúp đảm bảo rằng giao diện của tôi luôn cân nhắc đến bàn phím
và phong cách công nghệ hỗ trợ.
button:is(:hover, :focus) {
…
}
Vòng lấy nét tương tác
Tôi thích tạo ảnh động cho vòng lấy nét cho những người dùng bàn phím và công nghệ hỗ trợ. N thực hiện điều này bằng cách tạo ảnh động cho đường viền cách nút 5px, nhưng chỉ khi nút không hoạt động. Thao tác này tạo ra một hiệu ứng làm cho vòng lấy nét thu nhỏ lại kích thước nút khi được nhấn.
:where(button, input):where(:not(:active)):focus-visible {
outline-offset: 5px;
}
Đảm bảo độ tương phản màu truyền qua
Có ít nhất 4 tổ hợp màu sáng và tối khác nhau cần xem xét độ tương phản màu: nút, nút gửi, nút đặt lại và nút tắt. VisBug được dùng ở đây để kiểm tra và hiển thị tất cả điểm số của học viên cùng một lúc:
Đang ẩn biểu tượng để những người không xem được
Khi tạo nút biểu tượng, biểu tượng đó phải hỗ trợ trực quan cho văn bản của nút. Điều này cũng có nghĩa là biểu tượng không có giá trị đối với người có tầm nhìn tổn thất. Rất may là trình duyệt có cung cấp cách ẩn các mục khỏi trình đọc màn hình để những người bị mất thị lực không bận tâm đến nút trang trí hình ảnh:
<button>
<svg … aria-hidden="true">...</svg>
Icon Button
</button>
Kiểu
Trong phần tiếp theo này, trước tiên, tôi thiết lập hệ thống thuộc tính tuỳ chỉnh để quản lý các kiểu thích ứng của nút. Với các thuộc tính tuỳ chỉnh đó, tôi có thể bắt đầu chọn các phần tử và tuỳ chỉnh hình thức của chúng.
Chiến lược thuộc tính tuỳ chỉnh thích ứng
Chiến lược thuộc tính tuỳ chỉnh được sử dụng trong Thử thách về giao diện người dùng đồ hoạ này rất giống với dùng để tạo bảng phối màu. Cho hệ thống màu sáng và tối thích ứng, mỗi thuộc tính tuỳ chỉnh cho mỗi giao diện là được xác định và đặt tên tương ứng. Sau đó, một thuộc tính tùy chỉnh duy nhất được sử dụng để lưu giữ giá trị hiện tại của giao diện và được gán cho thuộc tính CSS. Sau đó, đĩa đơn có thể cập nhật thuộc tính tuỳ chỉnh thành một giá trị khác, rồi cập nhật nút phong cách.
button {
--_bg-light: white;
--_bg-dark: black;
--_bg: var(--_bg-light);
background-color: var(--_bg);
}
@media (prefers-color-scheme: dark) {
button {
--_bg: var(--_bg-dark);
}
}
Điều tôi thích là giao diện sáng và tối đều mang tính khai báo và rõ ràng. Chiến lược phát hành đĩa đơn
gián tiếp và trừu tượng được giảm tải vào thuộc tính tuỳ chỉnh --_bg
,
đây là chức năng "phản ứng" duy nhất bất động sản; --_bg-light
và --_bg-dark
là
tĩnh. Ngoài ra, bạn cũng dễ dàng nhận thấy rằng giao diện sáng là giao diện mặc định và
màu tối chỉ được áp dụng có điều kiện.
Chuẩn bị để đảm bảo tính nhất quán trong thiết kế
Bộ chọn dùng chung
Bộ chọn sau được dùng để nhắm mục tiêu tất cả các loại nút và
hơi choáng ngợp lúc đầu. :where()
là
nên việc tuỳ chỉnh nút không cần cụ thể. Các nút thường
được điều chỉnh cho các tình huống thay thế và bộ chọn :where()
giúp đảm bảo tác vụ
rất dễ dàng. Bên trong :where()
, mỗi loại nút đều được chọn, bao gồm
::file-selector-button
, không được
đã dùng
bên trong :is()
hoặc :where()
.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"],
input[type="file"]
),
:where(input[type="file"])::file-selector-button {
…
}
Tất cả thuộc tính tuỳ chỉnh sẽ nằm trong phạm vi của bộ chọn này. Thời gian xem xét tất cả thuộc tính tuỳ chỉnh! Có khá nhiều thuộc tính tuỳ chỉnh được sử dụng trong giao diện này . Tôi sẽ mô tả từng nhóm khi chúng ta bắt đầu, sau đó chia sẻ màn tối và giảm thiểu ngữ cảnh chuyển động ở cuối phần này.
Màu nhấn của nút
Các nút và biểu tượng gửi là nơi tuyệt vời để tạo hiệu ứng nổi bật:
--_accent-light: hsl(210 100% 40%);
--_accent-dark: hsl(210 50% 70%);
--_accent: var(--_accent-light);
Màu văn bản nút
Màu văn bản trên nút không phải là màu trắng hoặc đen, mà có phiên bản đã được làm tối hoặc sáng
trong tổng số --_accent
đang sử dụng
hsl()
và
luôn gắn bó với sắc thái 210
:
--_text-light: hsl(210 10% 30%);
--_text-dark: hsl(210 5% 95%);
--_text: var(--_text-light);
Màu nền của nút
Nền của các nút theo cùng một mẫu hsl()
, ngoại trừ giao diện sáng
các nút—các nút đó được đặt thành màu trắng để bề mặt của chúng làm cho chúng xuất hiện gần với
người dùng hoặc trước các thiết bị khác:
--_bg-light: hsl(0 0% 100%);
--_bg-dark: hsl(210 9% 31%);
--_bg: var(--_bg-light);
Nền của nút hợp lý
Màu nền này dùng để làm cho một bề mặt xuất hiện phía sau các bề mặt khác, hữu ích cho nền của đầu vào tệp:
--_input-well-light: hsl(210 16% 87%);
--_input-well-dark: hsl(204 10% 10%);
--_input-well: var(--_input-well-light);
Khoảng đệm nút
Giãn cách xung quanh văn bản trong nút được thực hiện bằng cách sử dụng toán tử
ch
một đơn vị, chiều dài tương đối so với cỡ chữ. Điều này trở nên quan trọng khi quy mô lớn
các nút có thể tăng kích thước font-size
và tỷ lệ của nút
theo tỷ lệ:
--_padding-inline: 1.75ch;
--_padding-block: .75ch;
Đường viền nút
Bán kính đường viền của nút được lưu trữ trong một thuộc tính tuỳ chỉnh để nội dung nhập vào tệp có thể khớp với các nút khác. Màu đường viền tuân theo màu thích ứng đã thiết lập hệ thống:
--_border-radius: .5ch;
--_border-light: hsl(210 14% 89%);
--_border-dark: var(--_bg-dark);
--_border: var(--_border-light);
Hiệu ứng làm nổi bật khi di chuột qua nút
Các thuộc tính này thiết lập thuộc tính kích thước để chuyển đổi khi tương tác và
màu đánh dấu tuân theo hệ thống màu thích ứng. Chúng tôi sẽ đề cập đến cách
tương tác sau trong bài đăng này, nhưng cuối cùng những thông tin này vẫn được sử dụng cho box-shadow
hiệu ứng:
--_highlight-size: 0;
--_highlight-light: hsl(210 10% 71% / 25%);
--_highlight-dark: hsl(210 10% 5% / 25%);
--_highlight: var(--_highlight-light);
Độ bóng văn bản nút
Mỗi nút có một kiểu bóng văn bản tinh tế. Điều này giúp văn bản nằm trên nút này, cải thiện mức độ dễ đọc và thêm một lớp trau chuốt cho bản trình bày.
--_ink-shadow-light: 0 1px 0 var(--_border-light);
--_ink-shadow-dark: 0 1px 0 hsl(210 11% 15%);
--_ink-shadow: var(--_ink-shadow-light);
Biểu tượng nút
Biểu tượng có kích thước của 2 ký tự nhờ đơn vị ch
có độ dài tương đối
để giúp biểu tượng điều chỉnh theo tỷ lệ tương ứng với văn bản trên nút. Chiến lược phát hành đĩa đơn
màu biểu tượng dựa vào --_accent-color
để mang đến giao diện thích ứng và phù hợp
.
--_icon-size: 2ch;
--_icon-color: var(--_accent);
Bóng nút
Để bóng thích ứng thích hợp với ánh sáng và tối, chúng cần phải chuyển cả hai bóng màu sắc và độ mờ. Bóng giao diện sáng phù hợp nhất khi bóng mờ và được phủ màu theo màu sắc bề mặt mà chúng phủ lên. Bóng của giao diện tối cần phải tối hơn và bão hoà hơn để chúng có thể phủ lên các màu tối hơn của bề mặt.
--_shadow-color-light: 220 3% 15%;
--_shadow-color-dark: 220 40% 2%;
--_shadow-color: var(--_shadow-color-light);
--_shadow-strength-light: 1%;
--_shadow-strength-dark: 25%;
--_shadow-strength: var(--_shadow-strength-light);
Với màu sắc và độ mạnh thích ứng, tôi có thể tập hợp hai độ sâu bóng:
--_shadow-1: 0 1px 2px -1px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 9%));
--_shadow-2:
0 3px 5px -2px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 3%)),
0 7px 14px -5px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 5%));
Ngoài ra, để tạo cho các nút giao diện hơi 3D, bóng hộp 1px
tạo ra ảo tưởng:
--_shadow-depth-light: 0 1px var(--_border-light);
--_shadow-depth-dark: 0 1px var(--_bg-dark);
--_shadow-depth: var(--_shadow-depth-light);
Hiệu ứng chuyển đổi nút
Theo mẫu dành cho màu thích ứng, tôi tạo 2 thuộc tính tĩnh để giữ các tuỳ chọn hệ thống thiết kế:
--_transition-motion-reduce: ;
--_transition-motion-ok:
box-shadow 145ms ease,
outline-offset 145ms ease
;
--_transition: var(--_transition-motion-reduce);
Tất cả tài sản cùng xuất hiện trong bộ chọn
:where( button, input[type="button"], input[type="submit"], input[type="reset"], input[type="file"] ), :where(input[type="file"])::file-selector-button { --_accent-light: hsl(210 100% 40%); --_accent-dark: hsl(210 50% 70%); --_accent: var(--_accent-light);--_text-light: hsl(210 10% 30%); --_text-dark: hsl(210 5% 95%); --_text: var(--_text-light);
--_bg-light: hsl(0 0% 100%); --_bg-dark: hsl(210 9% 31%); --_bg: var(--_bg-light);
--_input-well-light: hsl(210 16% 87%); --_input-well-dark: hsl(204 10% 10%); --_input-well: var(--_input-well-light);
--_padding-inline: 1.75ch; --_padding-block: .75ch;
--_border-radius: .5ch; --_border-light: hsl(210 14% 89%); --_border-dark: var(--_bg-dark); --_border: var(--_border-light);
--_highlight-size: 0; --_highlight-light: hsl(210 10% 71% / 25%); --_highlight-dark: hsl(210 10% 5% / 25%); --_highlight: var(--_highlight-light);
--_ink-shadow-light: 0 1px 0 hsl(210 14% 89%); --_ink-shadow-dark: 0 1px 0 hsl(210 11% 15%); --_ink-shadow: var(--_ink-shadow-light);
--_icon-size: 2ch; --_icon-color-light: var(--_accent-light); --_icon-color-dark: var(--_accent-dark); --_icon-color: var(--accent, var(--_icon-color-light));
--_shadow-color-light: 220 3% 15%; --_shadow-color-dark: 220 40% 2%; --_shadow-color: var(--_shadow-color-light); --_shadow-strength-light: 1%; --_shadow-strength-dark: 25%; --_shadow-strength: var(--_shadow-strength-light); --_shadow-1: 0 1px 2px -1px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 9%)); --_shadow-2: 0 3px 5px -2px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 3%)), 0 7px 14px -5px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 5%)) ;
--_shadow-depth-light: hsl(210 14% 89%); --_shadow-depth-dark: var(--_bg-dark); --_shadow-depth: var(--_shadow-depth-light);
--_transition-motion-reduce: ; --_transition-motion-ok: box-shadow 145ms ease, outline-offset 145ms ease ; --_transition: var(--_transition-motion-reduce); }
Điều chỉnh giao diện tối
Giá trị của mẫu đạo cụ tĩnh -light
và -dark
sẽ trở nên rõ ràng khi
các thành phần trong giao diện tối được thiết lập:
@media (prefers-color-scheme: dark) {
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"],
input[type="file"]
),
:where(input[type="file"])::file-selector-button {
--_bg: var(--_bg-dark);
--_text: var(--_text-dark);
--_border: var(--_border-dark);
--_accent: var(--_accent-dark);
--_highlight: var(--_highlight-dark);
--_input-well: var(--_input-well-dark);
--_ink-shadow: var(--_ink-shadow-dark);
--_shadow-depth: var(--_shadow-depth-dark);
--_shadow-color: var(--_shadow-color-dark);
--_shadow-strength: var(--_shadow-strength-dark);
}
}
Nút này không chỉ đọc tốt mà người sử dụng các nút tuỳ chỉnh này còn có thể sử dụng đạo cụ trần và tự tin rằng chúng sẽ thích ứng theo lựa chọn ưu tiên của người dùng.
Giảm khả năng điều chỉnh chuyển động
Nếu người dùng truy cập này chấp nhận chuyển động, hãy chỉ định --_transition
cho
var(--_transition-motion-ok)
:
@media (prefers-reduced-motion: no-preference) {
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"],
input[type="file"]
),
:where(input[type="file"])::file-selector-button {
--_transition: var(--_transition-motion-ok);
}
}
Một số kiểu chung
Các nút và thao tác nhập vào cần có phông chữ inherit
để khớp với
phông chữ còn lại của trang; nếu không thì trình duyệt sẽ định kiểu. Việc này cũng
áp dụng cho letter-spacing
. Việc đặt line-height
thành 1.5
sẽ đặt hộp chữ cái
để tạo khoảng trống cho văn bản ở phía trên và phía dưới:
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"],
input[type="file"]
),
:where(input[type="file"])::file-selector-button {
/* …CSS variables */
font: inherit;
letter-spacing: inherit;
line-height: 1.5;
border-radius: var(--_border-radius);
}
Tạo kiểu nút
Điều chỉnh bộ chọn
Bộ chọn input[type="file"]
không phải là một phần nút của đầu vào,
pseudo-element ::file-selector-button
là, vì vậy tôi đã xoá input[type="file"]
khỏi danh sách:
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"],
input[type="file"]
),
:where(input[type="file"])::file-selector-button {
}
Điều chỉnh con trỏ và thao tác chạm
Trước tiên, tôi tạo kiểu con trỏ theo kiểu pointer
, điều này giúp nút biểu thị
cho những người dùng chuột thấy rằng công cụ đó có tính tương tác. Sau đó, tôi thêm touch-action: manipulation
vào
không cần chờ đợi và quan sát một lượt nhấp đúp tiềm năng, giúp
các nút hoạt động nhanh hơn:
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
cursor: pointer;
touch-action: manipulation;
}
Màu và đường viền
Tiếp theo, tôi tuỳ chỉnh cỡ chữ, màu nền, màu văn bản và màu đường viền, sử dụng một số của các thuộc tính tuỳ chỉnh thích ứng đã thiết lập trước đó:
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
…
font-size: var(--_size, 1rem);
font-weight: 700;
background: var(--_bg);
color: var(--_text);
border: 2px solid var(--_border);
}
Bóng
Các nút được áp dụng một số kỹ thuật tuyệt vời. Chiến lược phát hành đĩa đơn
text-shadow
là
thích ứng với sáng và tối, tạo nên hình thức tinh tế dễ chịu cho nút
văn bản nằm gọn trên nền. Đối với
box-shadow
!
3 bóng được gán. Đầu tiên, --_shadow-2
, là bóng hộp thông thường.
Bóng thứ hai là một trò đánh lừa mắt khiến nút trông có vẻ như
nghiêng lên một chút. Bóng cuối cùng là dành cho vùng nổi bật khi di chuột, ban đầu
ở kích thước 0, nhưng sẽ có kích thước sau và được chuyển đổi để biểu ngữ xuất hiện
phát triển từ nút.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
…
box-shadow:
var(--_shadow-2),
var(--_shadow-depth),
0 0 0 var(--_highlight-size) var(--_highlight)
;
text-shadow: var(--_ink-shadow);
}
Bố cục
Tôi đã tạo cho nút một bố cục hộp linh hoạt,
cụ thể là bố cục inline-flex
sẽ phù hợp với nội dung của nó. Sau đó, tôi căn giữa
và căn chỉnh phần tử con theo chiều dọc và chiều ngang
trung tâm. Thao tác này sẽ giúp các biểu tượng và
để căn chỉnh chính xác.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
…
display: inline-flex;
justify-content: center;
align-items: center;
text-align: center;
}
Giãn cách
Để giãn cách các nút, tôi đã sử dụng
gap
để giữ các thành phần đồng cấp
từ chạm và logic
thuộc tính cho khoảng đệm. Vì vậy, nút này
giãn cách sẽ phù hợp với mọi bố cục văn bản.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
…
gap: 1ch;
padding-block: var(--_padding-block);
padding-inline: var(--_padding-inline);
}
Trải nghiệm người dùng bằng chuột và cảm ứng
Phần tiếp theo này chủ yếu dành cho người dùng cảm ứng trên thiết bị di động. Đầu tiên
tài sản,
user-select
!
dành cho tất cả người dùng; nút này không cho phép văn bản đánh dấu văn bản của nút. Việc này chủ yếu
dễ nhận thấy trên thiết bị cảm ứng, khi người dùng nhấn và giữ một nút, cũng như
hệ thống đánh dấu văn bản của nút đó.
Nhìn chung, tôi nhận thấy đây không phải là trải nghiệm người dùng có các nút được tích hợp sẵn
nên tôi tắt nó bằng cách đặt user-select
thành không có. Nhấn vào màu đánh dấu
(-webkit-tap-highlight-color
)
và trình đơn theo bối cảnh của hệ điều hành
(-webkit-touch-callout
)
là các tính năng khác của nút chỉ tập trung vào web không phù hợp với các khái niệm chung
đáp ứng kỳ vọng của người dùng, vì vậy, tôi cũng xoá chúng.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
…
user-select: none;
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
}
Kiểu chuyển cảnh
Biến --_transition
thích ứng được chỉ định cho
thuộc tính chuyển đổi:
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
…
transition: var(--_transition);
}
Khi người dùng không chủ động nhấn, hãy điều chỉnh phần đánh dấu bóng khi di chuột qua để mang lại giao diện tiêu điểm đẹp mắt dường như phát triển từ bên trong nút:
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
):where(:not(:active):hover) {
--_highlight-size: .5rem;
}
Khi lấy tiêu điểm, hãy tăng độ lệch đường viền tiêu điểm trên nút, đồng thời tạo cho nút này giao diện tiêu điểm đẹp mắt dường như tăng lên từ bên trong nút:
:where(button, input):where(:not(:active)):focus-visible {
outline-offset: 5px;
}
Biểu tượng
Để xử lý các biểu tượng, bộ chọn này có thêm một bộ chọn :where()
dành cho SVG trực tiếp
phần tử con hoặc phần tử có thuộc tính tuỳ chỉnh data-icon
. Đã đặt kích thước biểu tượng
với thuộc tính tuỳ chỉnh bằng cách sử dụng các thuộc tính logic cùng dòng và khối. Màu nét chữ
đã đặt, cũng như
drop-shadow
để khớp với text-shadow
. flex-shrink
được đặt thành 0
nên biểu tượng này sẽ không bao giờ
bóp méo. Cuối cùng, tôi chọn các biểu tượng được sắp xếp và chỉ định các kiểu đó ở đây
Viết hoa fill: none
và round
dòng và liên kết dòng:
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
) > :where(svg, [data-icon]) {
block-size: var(--_icon-size);
inline-size: var(--_icon-size);
stroke: var(--_icon-color);
filter: drop-shadow(var(--_ink-shadow));
flex-shrink: 0;
fill: none;
stroke-linecap: round;
stroke-linejoin: round;
}
Tuỳ chỉnh nút gửi
Tôi muốn các nút gửi có giao diện được quảng bá một chút và tôi đã đạt được điều này bằng cách làm cho màu văn bản của các nút làm màu nhấn:
:where(
[type="submit"],
form button:not([type],[disabled])
) {
--_text: var(--_accent);
}
Tuỳ chỉnh nút đặt lại
Tôi muốn các nút đặt lại được tích hợp sẵn một số dấu hiệu cảnh báo để cảnh báo người dùng hành vi có khả năng phá hoại của chúng. Tôi cũng chọn tạo kiểu cho giao diện sáng có nhiều điểm nhấn màu đỏ hơn so với giao diện tối. Việc tuỳ chỉnh được thực hiện bằng thay đổi màu cơ bản sáng hoặc tối thích hợp và nút này sẽ cập nhật kiểu:
:where([type="reset"]) {
--_border-light: hsl(0 100% 83%);
--_highlight-light: hsl(0 100% 89% / 20%);
--_text-light: hsl(0 80% 50%);
--_text-dark: hsl(0 100% 89%);
}
Tôi cũng nghĩ màu viền của tiêu điểm phù hợp với điểm nhấn của
màu đỏ. Màu văn bản điều chỉnh từ đỏ đậm thành đỏ nhạt. Tôi tạo màu đường viền
so khớp cụm từ này với từ khoá
currentColor
:
:where([type="reset"]):focus-visible {
outline-color: currentColor;
}
Tuỳ chỉnh nút bị tắt
Các nút bị vô hiệu hoá có độ tương phản màu kém trong hãy cố gắng nhấn nút đã bị vô hiệu hoá để nút này trông ít hoạt động hơn. Tôi đã kiểm tra từng bộ màu và đảm bảo chúng đã vượt qua, đẩy giá trị độ sáng HSL cho đến khi điểm số được chuyển trong Công cụ cho nhà phát triển hoặc VisBug.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
)[disabled] {
--_bg: none;
--_text-light: hsl(210 7% 40%);
--_text-dark: hsl(210 11% 71%);
cursor: not-allowed;
box-shadow: var(--_shadow-1);
}
Tuỳ chỉnh các nút nhập tệp
Nút nhập tệp là vùng chứa span và nút. CSS có thể
định kiểu cho vùng chứa đầu vào một chút, cũng như nút lồng nhau, nhưng không
span. Vùng chứa này được cấp max-inline-size
để nó sẽ không lớn hơn
cần thiết, trong khi inline-size: 100%
sẽ cho phép chính nó co lại và vừa vặn
nhỏ hơn kích thước thực. Màu nền được đặt thành màu thích ứng
tối hơn các nền tảng khác, vì vậy giao diện này sẽ nhìn phía sau nút bộ chọn tệp.
:where(input[type="file"]) {
inline-size: 100%;
max-inline-size: max-content;
background-color: var(--_input-well);
}
Nút bộ chọn tệp và nút loại dữ liệu nhập được cung cấp riêng
appearance: none
để xoá mọi kiểu do trình duyệt cung cấp mà không phải
bị ghi đè bởi các kiểu nút khác.
:where(input[type="button"]),
:where(input[type="file"])::file-selector-button {
appearance: none;
}
Cuối cùng, lề được thêm vào inline-end
của nút để đẩy văn bản span
ra khỏi nút, tạo ra một số không gian.
:where(input[type="file"])::file-selector-button {
margin-inline-end: var(--_padding-inline);
}
Các trường hợp ngoại lệ đặc biệt đối với giao diện tối
Tôi đã đặt nền tối hơn cho các nút hành động chính để độ tương phản cao hơn văn bản, giúp quảng cáo trông có vẻ được quảng bá nhiều hơn một chút.
@media (prefers-color-scheme: dark) {
:where(
[type="submit"],
[type="reset"],
[disabled],
form button:not([type="button"])
) {
--_bg: var(--_input-well);
}
}
Tạo biến thể
Để giải trí và vì tính thực tế, tôi chọn trình bày cách tạo một vài các biến thể. Một biến thể rất rực rỡ, tương tự như mức độ thường thấy của các nút chính ánh sáng. Một biến thể khác là lớn. Biến thể cuối cùng có biểu tượng tô màu nền chuyển màu.
Nút phát sáng
Để có được kiểu nút này, tôi đã trực tiếp ghi đè các đạo cụ cơ sở bằng màu xanh dương màu. Mặc dù quá trình này nhanh chóng và dễ dàng, nhưng nó sẽ loại bỏ các đạo cụ và giao diện thích ứng như nhau trong cả giao diện sáng lẫn tối.
.btn-custom {
--_bg: linear-gradient(hsl(228 94% 67%), hsl(228 81% 59%));
--_border: hsl(228 89% 63%);
--_text: hsl(228 89% 100%);
--_ink-shadow: 0 1px 0 hsl(228 57% 50%);
--_highlight: hsl(228 94% 67% / 20%);
}
Nút lớn
Bạn tạo được kiểu nút này bằng cách sửa đổi thuộc tính tuỳ chỉnh --_size
.
Khoảng đệm và các phần tử không gian khác tương ứng với kích thước này và điều chỉnh theo tỷ lệ
tương ứng với kích thước mới.
.btn-large {
--_size: 1.5rem;
}
Nút biểu tượng
Hiệu ứng biểu tượng này không liên quan gì đến các kiểu nút, nhưng có liên quan cho biết cách thực hiện điều đó chỉ với một vài thuộc tính CSS và nút xử lý các biểu tượng không phải là SVG cùng dòng.
[data-icon="cloud"] {
--icon-cloud: url("https://api.iconify.design/mdi:apple-icloud.svg") center / contain no-repeat;
-webkit-mask: var(--icon-cloud);
mask: var(--icon-cloud);
background: linear-gradient(to bottom, var(--_accent-dark), var(--_accent-light));
}
Kết luận
Giờ bạn đã biết cách tôi thực hiện điều đó, bạn sẽ làm cách nào‽ 🙂
Hãy đa dạng hoá phương pháp tiếp cận và tìm hiểu tất cả các cách xây dựng ứng dụng trên web.
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 vào vào phần bản phối lại của cộng đồng dưới đây!
Bản phối lại của cộng đồng
Chưa có gì để xem ở đây.
Tài nguyên
- Mã nguồn trên GitHub