ภาพรวมพื้นฐานของวิธีสร้างองค์ประกอบการตั้งค่าของแถบเลื่อนและช่องทำเครื่องหมาย
ในโพสต์นี้ ผมอยากจะแชร์ความคิดเห็นเกี่ยวกับการสร้างคอมโพเนนต์การตั้งค่าสำหรับ เว็บที่ปรับเปลี่ยนตามอุปกรณ์ รองรับอินพุตอุปกรณ์ที่หลากหลาย และทำงานต่างๆ ได้ เบราว์เซอร์ ทดลองใช้การสาธิต
หากต้องการดูวิดีโอ หรือต้องการดูตัวอย่าง UI/UX ของสิ่งที่เรากำลังสร้าง นี่คือ คำแนะนำแบบทีละขั้นที่สั้นกว่าบน YouTube:
ภาพรวม
เราได้แบ่งองค์ประกอบนี้ออกเป็นส่วนต่างๆ ดังต่อไปนี้
- เลย์เอาต์
- สี
- อินพุตช่วงที่กำหนดเอง
- อินพุตช่องทำเครื่องหมายที่กําหนดเอง
- ข้อควรพิจารณาเกี่ยวกับการช่วยเหลือพิเศษ
- JavaScript
เลย์เอาต์
นี่คือการสาธิต GUI Challenge แรกที่เป็นตารางกริด CSS ทั้งหมด ตารางแต่ละรายการมีดังนี้ ที่ไฮไลต์ด้วยเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome สำหรับตารางกริด
เพื่อช่องว่าง
เลย์เอาต์ที่ใช้กันมากที่สุดมีดังนี้
foo {
display: grid;
gap: var(--something);
}
ฉันเรียกเลย์เอาต์นี้ว่า "สำหรับช่องว่างเท่านั้น" เนื่องจากจะใช้ตารางกริดเพื่อเพิ่มช่องว่างระหว่างบล็อกเท่านั้น
เลย์เอาต์ 5 รายการใช้กลยุทธ์นี้ แสดงเลย์เอาต์ทั้งหมดดังนี้
องค์ประกอบ 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 และตารางกริดสามารถรองรับ align-items
หรือ
align-content
และเมื่อจัดการกับองค์ประกอบการรวม เลย์เอาต์แบบ content
การจัดแนวขอบจะกระจายพื้นที่ในกลุ่มเด็ก
main {
display: grid;
gap: var(--space-xl);
place-content: center;
}
องค์ประกอบหลักใช้การจัดแนว place-content: center
Shorthand ดังนั้น
ให้เด็กอยู่กึ่งกลางในแนวตั้งและแนวนอนทั้งในเลย์เอาต์แบบ 1 และ 2 คอลัมน์
ดูวิดีโอด้านบนว่า "เนื้อหา" อยู่ตรงกลางแม้ว่าการห่อ เกิดขึ้น
ใช้ Minmax ที่ปรับให้พอดีอัตโนมัติซ้ำ
<form>
ใช้เลย์เอาต์ตารางกริดแบบปรับอัตโนมัติสำหรับแต่ละส่วน
เลย์เอาต์นี้จะเปลี่ยนจาก 1 เป็น 2 คอลัมน์ตามพื้นที่ว่าง
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
ใช้ฟังก์ชัน CSS 3 รายการ ได้แก่ repeat()
, minmax()
และ
min()
Una Kravets มีบล็อกที่มีเลย์เอาต์สวยงาม
โพสต์เกี่ยวกับเรื่องนี้ โดยกล่าวว่า
RAM
มีรายละเอียดเพิ่มเติม 3 รายการในเลย์เอาต์ของเรา หากคุณเปรียบเทียบกับ Una's:
- เราส่งฟังก์ชัน
min()
เพิ่มเติม - เราระบุเป็น
align-items: flex-start
- มีรูปแบบ
max-width: 89vw
Evan Minto ได้อธิบายฟังก์ชันเพิ่มเติมของ min()
ไว้อย่างดีในบล็อกใน
โพสต์ กริด 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;
}
การใช้งานขั้นตอนเหล่านี้ทำได้อย่างดีเยี่ยมกับตารางกริด, CSS @nest และไวยากรณ์ระดับ 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);
}
}
}
ตารางกริดที่มีเนื้อหาอยู่ตรงกลาง โดยจะได้รับการเพิ่มระดับปานกลางโดยค่าเริ่มต้น (เช่น บนอุปกรณ์เคลื่อนที่) แต่ เมื่อมีพื้นที่วิวพอร์ตมากขึ้น พื้นที่ว่างก็จะแผ่ขยายออกไปด้วยการเพิ่มระยะห่างจากขอบ 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) สิ่งนี้มีข้อได้เปรียบที่ต่างจากปกติ เนื่องจากมนุษย์สามารถเขียนข้อความได้อย่างง่ายดาย และ ผู้คนจะปรับตัวให้เข้ากับ การเปลี่ยนแปลงเหล่านี้ได้
![ภาพหน้าจอของหน้าเว็บ pod.link/csspodcast ซึ่งแสดงสีที่ 2: ตอน Perception ขึ้น](https://web.dev/static/articles/building/a-settings-component/image/a-screenshot-podlinkcs-a40f130bf81b8.png?authuser=1&hl=th)
สำหรับวันนี้ ในการสาธิตนี้ เรามาโฟกัสที่ไวยากรณ์และค่าที่ฉันจะสลับกัน ให้เป็นความสว่างและมืด เรามาดูพื้นผิว 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: a
สีเทาที่เข้มมาก จากนั้นในคิวรี่สื่อสำหรับโหมดสว่าง
พลิกเป็น 90%
ด้วย --surface1: lch(90 0 0);
และนั่นคือสาระสำคัญของ
ของคุณ เริ่มด้วยการเปลี่ยนความสว่างระหว่าง 2 ธีม โดยคง
อัตราส่วนความคมชัดที่ต้องการออกแบบหรือสิ่งที่รักษาการเข้าถึงได้
ข้อดีของ lch()
คือ ความสว่างเน้นความเป็นมนุษย์ เราจึงรู้สึก
การเปลี่ยนแปลงของ %
เป็นไปอย่างที่ดีและสม่ำเสมอ
แตกต่างไป %
ตัวอย่างเช่น hsl()
ไม่เท่ากับ
เชื่อถือได้
ยังมีอีกมากมาย
ดูข้อมูลเกี่ยวกับ
พื้นที่สีและ lch()
หากคุณสนใจ ใกล้จะถึงเวลาแล้ว!
ตอนนี้ CSS ไม่สามารถเข้าถึงสีเหล่านี้ได้เลย ขอย้ำอีกครั้งว่าเราไม่มีสิทธิ์เข้าถึงสี 1 ใน 3 ของสีที่ทันสมัยที่สุด จอภาพ สีเหล่านี้ไม่ได้เป็นเพียงสีใดๆ แต่เป็นสีที่สดใสที่สุด ที่สามารถแสดงได้ เว็บไซต์ของเราหายไปเนื่องจากฮาร์ดแวร์การตรวจสอบพัฒนา เร็วกว่าข้อกำหนดของ CSS และการใช้งานเบราว์เซอร์
เลอา เวรู
การควบคุมแบบฟอร์มแบบปรับได้พร้อมรูปแบบสี
เบราว์เซอร์จำนวนมากมีการควบคุมธีมมืด ซึ่งปัจจุบันคือ Safari และ Chromium แต่คุณ ต้องระบุใน CSS หรือ HTML ที่การออกแบบของคุณจะนำไปใช้
ข้อมูลด้านบนกำลังแสดงถึงผลกระทบของพร็อพเพอร์ตี้จากแผงรูปแบบของ เครื่องมือสำหรับนักพัฒนาเว็บ การสาธิตใช้แท็ก HTML ซึ่งในความคิดของฉันโดยทั่วไป ตำแหน่งที่ดีกว่า:
<meta name="color-scheme" content="dark light">
เรียนรู้เกี่ยวกับเรื่องนี้ได้ใน color-scheme
นี้
บทความโดย Thomas
Steiner ยังมีสิทธิประโยชน์อีกมากมาย
มากกว่าช่องทำเครื่องหมายแบบมืดๆ เลย!
CSS accent-color
มีเมื่อเร็วๆ นี้
กิจกรรมรอบๆ
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
ที่ฝังจะเป็นสีขาวเพื่อคอนทราสต์ที่สูงขึ้น<picture>
clip-path
ที่ฝังจะขยายเป็นรูปวงกลมเต็มและ จะเต็มไปด้วยการไล่ระดับสีคงที่ที่สดใส
ช่วงที่กำหนดเอง
จากองค์ประกอบอินพุต 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;
}
เคล็ดลับก็คือ "การเปิดเผย" สีเติมที่ฉูดฉาด ซึ่งทำได้ด้วย การไล่ระดับสีแบบฮาร์ดหยุดที่ด้านบน การไล่ระดับสีจะโปร่งใสจนถึงเปอร์เซ็นต์การเติมสี และหลังจาก ที่ใช้สีพื้นผิวแทร็กที่ไม่เติมสี เบื้องหลังพื้นผิวที่ไม่ถูกเติม สีเต็มความกว้าง โดยรอให้มีความโปร่งใสเผยให้เห็น
ติดตามรูปแบบการเติมสี
การออกแบบของฉันต้องใช้ 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 ประการ วิธีแรกคือ ระบุว่าค่าช่องทำเครื่องหมายนั้นใช้สำหรับอะไร โดยตอบคำถามว่า "เปิดหรือปิดสำหรับอะไร" อย่างที่ 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">
ในช่องทำเครื่องหมาย ให้เพิ่มทั้งชื่อและรหัส 2 เท่าไปยัง
เพื่อให้แน่ใจว่าเนื้อหาจะได้รับการค้นพบด้วยเครื่องมือและเทคโนโลยีที่หลากหลาย เช่น เมาส์หรือโปรแกรมอ่านหน้าจอ
<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)
ผู้ปกครองสร้างพื้นที่ 3 มิติ และองค์ประกอบย่อยนี้เข้าถึงพื้นที่ได้
วางตัวเองกลับไปที่ z-space เล็กน้อย
การช่วยเหลือพิเศษ
วิดีโอ YouTube สาธิตการใช้เมาส์ แป้นพิมพ์ และ การโต้ตอบของโปรแกรมอ่านหน้าจอสำหรับคอมโพเนนต์การตั้งค่านี้ ผมจะพูดถึง รายละเอียดที่นี่
ตัวเลือกองค์ประกอบ HTML
<form>
<header>
<fieldset>
<picture>
<label>
<input>
แต่ละแหล่งข้อมูลจะมีคำแนะนำและเคล็ดลับเกี่ยวกับเครื่องมือท่องเว็บของผู้ใช้ องค์ประกอบบางอย่าง ให้คำแนะนำในการโต้ตอบ บางวิธีเชื่อมต่อการโต้ตอบ และบางอย่างช่วยกำหนดทิศทางของ แผนผังการช่วยเหลือพิเศษที่โปรแกรมอ่านหน้าจอไปยังส่วนต่างๆ
แอตทริบิวต์ HTML
เราสามารถซ่อนองค์ประกอบที่โปรแกรมอ่านหน้าจอไม่จำเป็นต้องใช้ ในกรณีนี้คือไอคอนถัดจากแถบเลื่อน
<picture aria-hidden="true">
วิดีโอด้านบนแสดงการทำงานของโปรแกรมอ่านหน้าจอใน Mac OS สังเกตวิธีป้อนข้อมูล โฟกัสจะเลื่อนจากแถบเลื่อนหนึ่งไปยังอีกแถบหนึ่งโดยตรง เพราะเราได้ซ่อน ไอคอนที่เคยเป็นจุดแวะระหว่างทางไปยังแถบเลื่อนถัดไป หากไม่มีข้อมูลนี้ ที่ผู้ใช้จะต้องหยุด ฟัง และเลื่อนผ่านรูปภาพ พวกเขาอาจไม่สามารถมองเห็นได้
SVG เป็นโจทย์คณิตศาสตร์มากมาย มาเพิ่มเอลิเมนต์ <title>
สำหรับการวางเมาส์แบบอิสระกันเถอะ
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 ไปแล้ว
ต่อไปมาดู JavaScript ที่เกี่ยวข้องของ <form>
กัน
const form = document.querySelector('form');
form.addEventListener('input', event => {
const formData = Object.fromEntries(new FormData(form));
console.table(formData);
})
ทุกครั้งที่มีการโต้ตอบกับแบบฟอร์มและมีการเปลี่ยนแปลง คอนโซลจะบันทึกแบบฟอร์มเป็น ออบเจ็กต์ลงในตารางเพื่อให้ตรวจสอบได้ง่ายก่อนส่งไปยังเซิร์ฟเวอร์
บทสรุป
เมื่อรู้แล้วว่าฉันทำแบบนั้นได้อย่างไร คุณจะทำอย่างไร ฟีเจอร์นี้ช่วยให้เล่นสนุกขึ้น สถาปัตยกรรมคอมโพเนนต์ ใครที่จะทำให้เวอร์ชันแรกมีช่องใน กรอบการทำงานที่ชอบใช้คืออะไร 🙂
มาเพิ่มความหลากหลายให้กับแนวทางของเราและเรียนรู้วิธีทั้งหมดในการสร้างเนื้อหาบนเว็บกัน สร้างลิงก์สาธิต ทวีตฉัน แล้วฉันจะเพิ่มให้เอง ไปยังส่วนรีมิกซ์ของชุมชนที่ด้านล่าง
รีมิกซ์ในชุมชน
- @tomayac พร้อมสไตล์เกี่ยวกับ พื้นที่สำหรับป้ายกำกับช่องทำเครื่องหมาย เวอร์ชันนี้ไม่มีช่องว่างเมื่อวางเมาส์เหนือ องค์ประกอบ ได้แก่ การสาธิตและ แหล่งที่มา