เมื่อใดที่ปุ่มไม่ใช่ปุ่ม

เผยแพร่แล้ว: 2022-03-10
สรุปสั้นๆ ↬ ไม่ใช่ทุกสิ่งที่กลมและโดดเด่นจะถือว่าเป็นปุ่ม ในบทความนี้ Vadim จะอธิบายวิธีสร้างปุ่มโต้ตอบที่เหมาะสมสำหรับผู้ใช้ของคุณ ซึ่งเป็นปุ่มที่ไม่ต้องสับสนกับอย่างอื่น

สมมติว่าคุณมีส่วนหนึ่งของอินเทอร์เฟซที่ผู้ใช้คลิกและมีบางอย่างเกิดขึ้น ฟังดูเหมือนเป็นปุ่มสำหรับฉัน แต่ตอนนี้ขอเรียกมันว่า "สิ่งที่คลิก" ฉันรู้ คุณมั่นใจว่ามันเป็นปุ่มเหมือนกัน มันกลมและโดดเด่นด้วยสีมะเขือเทศที่สวยงาม ขอให้มีปฏิสัมพันธ์ด้วย แต่ลองคิดดูสักครู่ จะช่วยประหยัดเวลาในระยะยาว ฉันสัญญา

สิ่งที่เหมือนปุ่มมะเขือเทศที่มีข้อความ 'บางอย่าง' อยู่
ออกแบบสำหรับ 'สิ่งที่คลิก' ของคุณ (ตัวอย่างขนาดใหญ่)

จะเกิดอะไรขึ้นหากข้อความในเรื่องที่น่าตกใจนี้คือ “อ่านเพิ่มเติม” และการคลิกนั้นนำผู้ใช้ไปยังบทความในหน้าอื่น อืม. แล้วถ้ามีคำที่ขีดเส้นใต้สีน้ำเงินว่า "ปิด" ที่ปิดกล่องโต้ตอบป๊อปอัปล่ะ เป็นลิงก์เพียงเพราะเป็นสีน้ำเงินและขีดเส้นใต้หรือไม่ แน่นอนไม่

ลิงค์เหมือนปุ่มและปุ่มลิงค์เหมือน
ภาวะที่กลืนไม่เข้าคายไม่ออกของลิงก์หรือปุ่ม (ตัวอย่างขนาดใหญ่)
เพิ่มเติมหลังกระโดด! อ่านต่อด้านล่าง↓

โว้ว! ดูเหมือนว่าจะไม่มีทางบอกได้ว่ามันเป็นลิงก์หรือปุ่มเพียงแค่ดูมัน บ้าไปแล้ว! เราต้องเข้าใจว่าสิ่งนี้ทำอะไรก่อนที่จะเลือกองค์ประกอบที่เหมาะสม แต่ถ้าเราไม่รู้ว่ามันทำอะไรอยู่หรือแค่สับสนล่ะ? มีผังงานที่สะดวกสำหรับเรา:

ผังงาน: มันเป็นปุ่ม หากไม่เป็นเช่นนั้นแสดงว่าเป็นลิงก์ แค่นั้นแหละ.
ผังงานทางวิทยาศาสตร์สำหรับการเลือกองค์ประกอบที่เหมาะสม (ตัวอย่างขนาดใหญ่)
  1. มันเป็นปุ่ม
  2. ถ้าไม่อย่างนั้นก็เป็นลิงค์
  3. แค่นั้นแหละ.

ดังนั้นทุกอย่างเป็นปุ่มหรือไม่? ไม่ได้ แต่คุณสามารถเริ่มต้นด้วยปุ่มสำหรับองค์ประกอบเกือบทุกอย่างที่สามารถคลิกหรือโต้ตอบในลักษณะเดียวกันได้ และถ้าขาดอะไรไป เช่น การนำทางไปยังหน้าอื่น ให้ใช้ลิงก์แทน และไม่ ตัวชี้ไม่ใช่เหตุผลที่จะทำให้เป็น <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:

  • วิธีการออกแบบปุ่มที่ดีขึ้น
  • การสร้างปุ่มสลับแบบรวม
  • การออกแบบปุ่มผี: นี่ยังคงเป็นสิ่งที่ (และทำไม)
  • รูปแบบการออกแบบ: เมื่อฝ่าฝืนกฎก็โอเค