เมื่อใดที่ปุ่มไม่ใช่ปุ่ม
เผยแพร่แล้ว: 2022-03-10สมมติว่าคุณมีส่วนหนึ่งของอินเทอร์เฟซที่ผู้ใช้คลิกและมีบางอย่างเกิดขึ้น ฟังดูเหมือนเป็นปุ่มสำหรับฉัน แต่ตอนนี้ขอเรียกมันว่า "สิ่งที่คลิก" ฉันรู้ คุณมั่นใจว่ามันเป็นปุ่มเหมือนกัน มันกลมและโดดเด่นด้วยสีมะเขือเทศที่สวยงาม ขอให้มีปฏิสัมพันธ์ด้วย แต่ลองคิดดูสักครู่ จะช่วยประหยัดเวลาในระยะยาว ฉันสัญญา
จะเกิดอะไรขึ้นหากข้อความในเรื่องที่น่าตกใจนี้คือ “อ่านเพิ่มเติม” และการคลิกนั้นนำผู้ใช้ไปยังบทความในหน้าอื่น อืม. แล้วถ้ามีคำที่ขีดเส้นใต้สีน้ำเงินว่า "ปิด" ที่ปิดกล่องโต้ตอบป๊อปอัปล่ะ เป็นลิงก์เพียงเพราะเป็นสีน้ำเงินและขีดเส้นใต้หรือไม่ แน่นอนไม่
โว้ว! ดูเหมือนว่าจะไม่มีทางบอกได้ว่ามันเป็นลิงก์หรือปุ่มเพียงแค่ดูมัน บ้าไปแล้ว! เราต้องเข้าใจว่าสิ่งนี้ทำอะไรก่อนที่จะเลือกองค์ประกอบที่เหมาะสม แต่ถ้าเราไม่รู้ว่ามันทำอะไรอยู่หรือแค่สับสนล่ะ? มีผังงานที่สะดวกสำหรับเรา:
- มันเป็นปุ่ม
- ถ้าไม่อย่างนั้นก็เป็นลิงค์
- แค่นั้นแหละ.
ดังนั้นทุกอย่างเป็นปุ่มหรือไม่? ไม่ได้ แต่คุณสามารถเริ่มต้นด้วยปุ่มสำหรับองค์ประกอบเกือบทุกอย่างที่สามารถคลิกหรือโต้ตอบในลักษณะเดียวกันได้ และถ้าขาดอะไรไป เช่น การนำทางไปยังหน้าอื่น ให้ใช้ลิงก์แทน และไม่ ตัวชี้ไม่ใช่เหตุผลที่จะทำให้เป็น <a href>
เรามี cursor: pointer
สำหรับสิ่งนั้น
เอาล่ะ มันคือ <button>
เราเห็นด้วย มาใส่ไว้ในเทมเพลตของเราและจัดรูปแบบตามการออกแบบ: ช่องว่างภายใน การปัดเศษ การเติมมะเขือเทศ ข้อความสีขาว และแม้กระทั่งรูปแบบการโฟกัสบางรูปแบบ โอ้ นั่นเป็นสิ่งที่ดีสำหรับคุณ
<button type="button" class="button"> Something </button> <style> .button { display: inline-block; padding: 10px 20px; border-radius: 20px; background-color: tomato; color: white; } .button:focus { outline: none; box-shadow: 0 0 0 5px #006AE3; } </style>
ที่ใช้เวลาไม่นาน คุณต้องการสร้างมันขึ้นมาอย่างรวดเร็วและคว้าอาหารกลางวันมาทานเพราะคุณหิว ตกลงเรามาดูกันว่ามันมีลักษณะอย่างไรและไปต่อ
โอ้พระเจ้า! มีบางอย่างผิดปกติกับเบราว์เซอร์ ทำไมปุ่มนี้น่าเกลียดจัง ข้อความมีขนาดเล็กแม้ว่าเราจะตั้งค่า body
ไว้อย่างชัดเจนเป็น 16px
และแม้แต่ชุด font-family
ก็ผิด เส้นขอบโค้งมนที่มีเงาหลอกดูย้อนยุคมากจนยังไม่เป็นเทรนด์
อ๊ะ เป็นสไตล์เริ่มต้นของเบราว์เซอร์ คุณต้องเลิกทำอย่างระมัดระวัง หรือแม้แต่เพิ่ม Normalize.css หรือ Reset.css... หรือคุณสามารถใช้ <div>
แล้วลืมมันไปได้เลย ไม่ใช่การแก้ปัญหาอย่างรวดเร็วในสิ่งที่พวกเขาจ่ายให้คุณใช่หรือไม่? คุณหิวและนี่ไม่ได้ช่วยอะไรเลย แต่คุณเป็นมืออาชีพ: ดึงตัวเองมารวมกันและคิด
อะไรคือความแตกต่างระหว่าง <button>
และ <div>
? <button>
ในตัวเป็นองค์ประกอบแบบโต้ตอบ ซึ่งหมายความว่าสามารถโต้ตอบได้ ที่ลึก คุณสามารถคลิกได้ คุณสามารถโฟกัสไปที่มันโดยใช้คีย์บอร์ด และยังถ่ายทอดบทบาทของ button
ที่เข้าถึงได้ให้กับโปรแกรมอ่านหน้าจอ ทำให้ผู้ใช้เข้าใจว่านี่คือปุ่ม
ประทับใจ! คุณไม่เพียงรับรู้องค์ประกอบ <button>
ของ HTML เท่านั้น แต่คุณยังรู้สิ่งหนึ่งหรือสองอย่างเกี่ยวกับ ARIA และการสนับสนุนโปรแกรมอ่านหน้าจอ คุณอาจลองใช้ VoiceOver หรือ NVDA เพื่อทดสอบว่าอินเทอร์เฟซของคุณเข้าถึงได้มากน้อยเพียงใด
ดังนั้น คุณได้ตัดสินใจที่จะทำเคล็ดลับ คุณจะไม่ยุ่งกับการจัดสไตล์ของเบราว์เซอร์ และ คุณจะทำให้องค์ประกอบดูเหมือนปุ่มโต้ตอบที่เหมาะสมสำหรับผู้ใช้ที่อาจจำเป็นต้องใช้ นั่นฉลาด!
<div class="button" tabindex="0" role="button"> Something </div>
ตอนนี้ไม่เพียงแต่ดูดีเท่านั้น แต่ยังโฟกัสได้ผ่านแป้นพิมพ์ด้วยแอตทริบิวต์ tabindex="0"
และโปรแกรมอ่านหน้าจอจะถือว่าเป็นปุ่มที่เหมาะสม เนื่องจากคุณได้เพิ่ม role="button"
เข้าไปอย่างชาญฉลาด Git กระทำ && ดันแล้ว! มีงานเพิ่มเติมบางอย่างสำหรับสิ่งนี้ แต่เราเสร็จสิ้นการจัดแต่งทรงผมแล้ว สิ่งที่อาจจะผิดไป? ถึงเวลาอาหารกลางวัน ดีมาก ไปกันเลย!
หนึ่งชั่วโมงต่อมา…
นั่นเป็นอาหารกลางวันที่ดี! กลับไปที่สิ่งที่คลิกของเรากันเถอะ เราต้องทำงานบางอย่างให้เสร็จก่อนที่จะไปต่อ มาดูกัน… เราจำเป็นต้องเรียกใช้ฟังก์ชัน doSomething
เมื่อคลิกปุ่ม และควรมีวิธีปิดการใช้งานปุ่มเพื่อไม่ให้คลิกได้ ฟังดูง่าย มาเพิ่มฟังเหตุการณ์ให้กับปุ่มนี้:
<script> const buttons = document.querySelectorAll('.button'); [...buttons].forEach(button => { button.addEventListener('click', doSomething); }); function doSomething() { console.log('Something!'); } </script>
เสร็จแล้ว. ขณะนี้ผู้ใช้สามารถคลิกด้วยเมาส์บนเดสก์ท็อปแล้วแตะด้วยนิ้วบนหน้าจอสัมผัส เหตุการณ์การคลิกจะเริ่มขึ้นอย่างน่าเชื่อถือ และคุณจะเห็นบางสิ่งบางอย่างมากมาย! ในคอนโซลของคุณ ภารกิจต่อไปคืออะไร?
เดี๋ยว! เราจำเป็นต้องตรวจสอบให้แน่ใจว่ามันใช้งานได้เหมือนกันสำหรับผู้ใช้แป้นพิมพ์ เนื่องจากเรามีปุ่มนี้ tabindex="0"
จึงสามารถโฟกัสได้ และเมื่อโฟกัสแล้ว ผู้ใช้ควรกดแป้นเว้นวรรคหรือปุ่ม "Enter" เพื่อทริกเกอร์สิ่งที่เราแนบมา
ดังนั้น เราจำเป็นต้องแนบตัวฟังเหตุการณ์ อื่น เพื่อจับคีย์อัปทั้งหมด และเราจะทริกเกอร์ฟังก์ชันของเราสำหรับบางคีย์เท่านั้น ขอบคุณพระเจ้าที่อุปกรณ์สัมผัสนั้นฉลาดพอที่จะแปลงการแตะทั้งหมดเป็นการคลิก ไม่เช่นนั้นเราจะต้องแนบกิจกรรมการสัมผัสด้วย
<script> const buttons = document.querySelectorAll('.button'); [...buttons].forEach(button => { button.addEventListener('click', doSomething); button.addEventListener('keyup', (event) => { if (event.key == 'Enter' || event.key == ' ') { doSomething(); } }); }); function doSomething() { console.log('Something!'); } </script>
วุ้ย ตอนนี้สิ่งที่คลิกของเราสามารถเข้าถึงได้อย่างเต็มที่จากแป้นพิมพ์ ฉันภูมิใจในตัวคุณมาก! และ JavaScript นั้นวิเศษมาก - เราจะทำอย่างไรถ้าไม่มีมัน?
เอาล่ะ ภารกิจสุดท้ายคืออะไร: “ปุ่มควรมีสถานะปิดการใช้งานซึ่งเปลี่ยนรูปลักษณ์และลักษณะการทำงานเป็นอาการชา” มึนงง? ฉันเดาว่ามันหมายถึงบางสิ่งที่เป็นสีเทาและไม่ตอบสนองต่อการโต้ตอบ ตกลง มาเพิ่มสถานะในสไตล์ชีตโดยใช้การตั้งชื่อ BEM
<div class="button button--disabled" tabindex="0" role="button"> Something </div> <style> .button--disabled { background-color: #9B9B9B; } </style>
ที่ดู สบาย ตาสำหรับฉัน เมื่อใดก็ตามที่จำเป็นต้องปิดใช้งานปุ่ม เราจะเพิ่ม button--disabled
เพื่อทำให้เป็นสีเทา แต่ยังมึนไม่พอ: ยังสามารถโฟกัสและทริกเกอร์ได้ทั้งโดยตัวชี้และจากแป้นพิมพ์
ดาร์น นี่มันเริ่มยากแล้ว
ไม่เพียงแค่นั้น แต่ปุ่มไม่ควรสามารถเข้าถึงได้ในลำดับแท็บ ซึ่งหมายความว่าแอตทริบิวต์ tabindex
ไม่ควรอยู่ที่นั่น และเราจำเป็นต้องตรวจสอบว่าปุ่มมีสถานะปิดใช้งานหรือไม่ จากนั้นหยุดเรียกใช้ฟังก์ชันของเรา นอกจากนี้ ตัวปรับแต่งนี้ยังสามารถนำไปใช้แบบไดนามิกได้ แม้ว่าจะไม่ใช่ปัญหาสำหรับ CSS ในการจับคู่องค์ประกอบกับตัวเลือกและนำสไตล์ไปใช้ แต่เราอาจต้องใช้ตัวสังเกตการกลายพันธุ์บางประเภทเพื่อทริกเกอร์การเปลี่ยนแปลงอื่นๆ สำหรับปุ่มนี้
ฉันรู้ใช่ไหม เราคิดว่านี่น่าจะเป็นปุ่มเล็กๆ ง่ายๆ ที่เรียกใช้ฟังก์ชันและมีสถานะปิดใช้งาน เราได้พยายามทำให้มันถูกต้องด้วยการช่วยการเข้าถึงและทุกสิ่ง และตอนนี้เราก็อยู่ลึกเข้าไปในโพรงกระต่ายแล้ว
มาซื้ออาหารกลับบ้านกัน เราจะไม่กลับบ้านเพื่อทานอาหารเย็นเมื่อเราทำเสร็จแล้วและทดสอบสิ่งนี้อย่างถูกต้อง W3C กระหายเลือด! ทำไมพวกเขาไม่พยายามทำให้ชีวิตของเราง่ายขึ้น? ราวกับว่าพวกเขาห่วงใยเรา!
ตามความเป็นจริงพวกเขาทำ ...
ลองย้อนกลับไปสักสองสามก้าวก่อนที่จะกระโดดลงไปในระเบียบนี้ ทำไมเราไม่ลองทำสิ่งเหล่านี้โดยใช้องค์ประกอบ <button>
มันมีลูกเล่นที่มีประโยชน์อยู่บ้าง ไม่ใช่แค่สไตล์ที่น่าเกลียดของเบราว์เซอร์เท่านั้น โอ้ และอย่าลืม type="button"
— คุณไม่ต้องการให้ปุ่ม "ปิด" ของป๊อปอัปส่งแบบฟอร์มโดยไม่ได้ตั้งใจ เนื่องจาก type="submit"
เป็นค่าเริ่มต้น
เห็นได้ชัดว่าเมื่อ <button>
ถูกโฟกัสและกดแป้นเว้นวรรคหรือแป้น "Enter" มันจะทริกเกอร์เหตุการณ์การ click
เช่นเดียวกับอุปกรณ์เคลื่อนที่เมื่อได้รับการแตะ ตบ เลีย หรืออะไรก็ตามที่พวกเขาสามารถรับได้ วันนี้. มีผู้ฟังเหตุการณ์น้อยกว่าหนึ่งในรหัสของเรา! ดี.
// A click is enough! button.addEventListener('click', doSomething);
สำหรับสถานะ disabled
คุณลักษณะที่ปิดใช้งานจะพร้อมใช้งานสำหรับองค์ประกอบ <button>
เช่นเดียวกับองค์ประกอบแบบฟอร์มทั้งหมด รวมถึง <fieldset>
ไม่ได้ล้อเล่น. คุณรู้หรือไม่ว่าคุณสามารถปิดการใช้งานอินพุตทั้งกลุ่มที่จัดกลุ่มเข้าด้วยกันโดยใช้แอตทริบิวต์เดียวกับพาเรนต์ <fieldset>
<fieldset disabled> <legend>A bunch of numb inputs</legend> <p> <label> <input type="radio" name="option"> Of course it's a link </label> </p> <p> <label> <input type="radio" name="option"> Obviously, it's a button </label> </p> <p> <label> <input type="radio" name="option"> I just wanna go home </label> </p> <button type="button">Button</button> </fieldset>
คุณรู้แล้วตอนนี้! คุณลักษณะนี้ไม่เพียงแต่ปิดใช้งานเหตุการณ์ทั้งหมดในองค์ประกอบของแบบฟอร์ม แต่ยังลบออกจากลำดับแท็บด้วย แก้ไขปัญหา!
<button disabled type="button" class="button"> Something </button>
แต่เดี๋ยวก่อน ยังมีอีก! นอกจากนี้ยังทริกเกอร์ :disabled
pseudo-class ใน CSS ซึ่งหมายความว่าเราสามารถกำจัดตัวแก้ไข BEM เพื่อประกาศสไตล์และใช้ตัวปรับแต่งไดนามิกในตัวแทน
.button:disabled { background-color: #9B9B9B; }
สำหรับสไตล์ที่น่าเกลียดของเบราว์เซอร์ เราไม่จำเป็นต้องใช้ Normalize.css ทั้งหมดเพื่อแก้ไขปุ่มเดียว ใช้เป็นแหล่งของภูมิปัญญา: สามบรรทัดพิเศษด้านล่างจะแก้ไขความแตกต่างที่น่ารำคาญส่วนใหญ่จาก <div>
หากคุณต้องการมากกว่านี้ คุณสามารถคัดลอกส่วนที่เกี่ยวข้องได้
.button { font-size: 100%; font-family: inherit; border: none; }
เสร็จแล้ว. HTML ก็ไม่ได้แย่ขนาดนั้น!
แต่ถ้ามันทำให้คุณประหลาดใจเป็นบางครั้ง อย่าลืมตรวจสอบข้อกำหนด HTML เพื่อหาคำตอบ ในช่วงหลายปีที่ผ่านมามีความเป็นมิตรมากขึ้น และเต็มไปด้วยตัวอย่างการใช้งานและการเข้าถึงที่ดี และแน่นอนว่า HTML5 Doctor ก็ยังเป็นที่ที่น่าเชื่อถือในการค้นหาความแตกต่างระหว่างองค์ประกอบ <section>
และ <article>
และเพื่อตรวจสอบว่าโครงร่างเอกสารนั้นเป็นของจริงหรือไม่ (ไม่ใช่จริงๆ) มีโอกาสดีที่คุณจะอ่านเอกสาร HTML ของ Mozilla และคุณจะไม่เสียใจเช่นกัน
งานนี้เสร็จสิ้นแล้ว! อะไรต่อไป? ปฏิทินหมุนแบบเลื่อนลงพร้อมช่องค้นหา? พุทโธ่! ขอให้โชคดีกับสิ่งนั้น แต่จำไว้ว่า <button>
คือเพื่อนของคุณ!
อ่านเพิ่มเติม เกี่ยวกับ SmashingMag:
- วิธีการออกแบบปุ่มที่ดีขึ้น
- การสร้างปุ่มสลับแบบรวม
- การออกแบบปุ่มผี: นี่ยังคงเป็นสิ่งที่ (และทำไม)
- รูปแบบการออกแบบ: เมื่อฝ่าฝืนกฎก็โอเค