บทความ
เรื่องเล็ก ๆ ที่ไม่มีใครสังเกต จนถึงนาทีที่มันทำคุณหงุดหงิด
งานออกแบบส่วนที่ดีที่สุดคือส่วนที่คุณไม่เคยเห็น และจะเห็นก็ต่อเมื่อมันทำผิดจนคุณหงุดหงิดนั่นแหละครับ
เผยแพร่
ลองนึกภาพตามนะครับ พนักงานบัญชีคนหนึ่งกำลังกรอกแบบฟอร์มออนไลน์ของหน่วยงานรัฐอยู่ ช่องหนึ่งขอเลขประจำตัวผู้เสียภาษีของคู่ค้า เธอเปิดเว็บไซต์ของบริษัทนั้นขึ้นมาอีกแท็บ ลากคลุมตัวเลข กด copy กลับมา paste
แล้วระบบก็ขึ้นข้อความสีแดงว่ารูปแบบไม่ถูกต้อง
คุ้น ๆ กันใช่มั้ยครับ สิ่งที่เธอ paste ลงไปคือ 0-1055-61086-66-8 พร้อมขีดคั่นครบทุกตัว ส่วนสิ่งที่ฟอร์มต้องการคือเลขสิบสามหลักติดกัน เธอเลยต้องลบขีดออกทีละตัวด้วยมือ เสียเวลาไปยี่สิบวินาที แล้วก็หงุดหงิดในระดับที่ไม่คุ้มจะบ่นกับใคร
ยี่สิบวินาทีนั้นแหละครับ คือหัวข้อของบทความวันนี้
จัดรูปแบบให้สายตาด้วย CSS แต่เก็บค่าจริงไว้ในข้อความ
บนเว็บไซต์นี้ เราแสดงเลขทะเบียนนิติบุคคลเป็น 0-1055-61086-66-8 ครับ เหตุผลง่าย ๆ คือการอ่านเลขสิบสามหลักติดกันเพื่อเทียบกับหนังสือรับรอง เป็นงานที่สายตาคนเราทำได้แย่มาก พอแบ่งเป็นกลุ่มแล้ว คุณจะเทียบทีละท่อนได้สบายขึ้นเยอะ
แต่เพื่อน ๆ รู้มั้ยครับว่าขีดคั่นพวกนั้นไม่ใช่ตัวอักษร มันเป็นเนื้อหาที่สร้างขึ้นจาก CSS ผ่าน ::before และถูกกำหนดให้ user-select: none ตัวเลขจริงอยู่ในข้อความ ส่วนขีดอยู่แค่ในการแสดงผล ผลก็คือพอคุณลากคลุมแล้วคัดลอก สิ่งที่ติดมือไปคือ 0105561086668 ล้วน ๆ ไม่มีเครื่องหมายอะไรติดมาเลย
เหตุผลไม่ใช่เรื่องความสวยงามนะครับ แต่เป็นการยอมรับความจริงว่าคนที่คัดลอกเลขนี้ ร้อยทั้งร้อยกำลังจะเอาไปวางในแบบฟอร์มราชการหรือระบบบัญชี และระบบพวกนั้นก็ปฏิเสธเครื่องหมายวรรคตอน
กฎที่พวกเราถือคือ จัดรูปแบบเพื่อสายตาด้วย CSS แล้วเก็บค่าที่ใช้งานได้จริงไว้ในข้อความ ใช้ได้กับเบอร์โทรศัพท์ เลขผู้เสียภาษี เลขบัญชีธนาคาร และหมายเลขคำสั่งซื้อ ทุกอย่างที่คนจะคัดลอกไปวางที่อื่น
แล้วถ้าค่าที่รับเข้ามาไม่ใช่เลขสิบสามหลักล่ะครับ ระบบจะแสดงมันตามที่เป็น โดยไม่จัดกลุ่มให้เลย เพราะข้อมูลที่พิมพ์ผิดควรดูผิด ไม่ใช่ถูกแต่งหน้าให้ดูเรียบร้อยจนไม่มีใครสังเกต
บริบทที่ควรตามคุณข้ามคลิกไปด้วย
ลองนึกภาพว่าท่านผู้อ่านเพิ่งอ่านหน้าผลงานชิ้นหนึ่งจนจบ แล้วกดปุ่มติดต่อเรา ถ้าฟอร์มที่เปิดขึ้นมาเป็นกล่องข้อความว่างเปล่า คุณก็ต้องเริ่มพิมพ์อธิบายใหม่ว่า “พอดีเพิ่งอ่านงานที่...” ทั้งที่ระบบมันรู้อยู่แล้วว่าคุณมาจากหน้าไหน น่าเสียดายใช่มั้ยครับ
ลิงก์จากหน้าผลงานหรือหน้าบริการที่พามาที่ฟอร์มติดต่อ จึงพาอ้างอิงของหน้านั้นมาด้วย ฟอร์มเอาไปใช้สองอย่างครับ อย่างแรกคือเติมประโยคเปิดให้ในช่องข้อความ เพื่อไม่ให้ใครต้องเริ่มจากหน้าว่าง อย่างที่สองคือบันทึกอ้างอิงนั้นไว้กับข้อความที่ส่ง คนที่รับเรื่องต่อจะได้รู้ว่าอีกฝ่ายกำลังพูดถึงอะไร
แต่ตรงนี้มีจุดที่ต้องระวังครับ เพราะค่าตัวนี้เดินทางมาใน URL
อะไรก็ตามที่มาจาก URL แล้วถูกเอาไปแสดงบนหน้าเว็บ คือช่องทางโจมตีแบบคลาสสิกเลย ใครก็ตามที่ส่งลิงก์ต่อให้คนอื่นจะใส่ข้อความอะไรลงไปก็ได้ เราจึงไม่เชื่อค่าที่ได้มาครับ แต่ตรวจกับรูปแบบที่กำหนดไว้อย่างเข้มงวดก่อน แล้วเอาไปค้นในเนื้อหาของเราเอง ชื่อที่คุณเห็นบนหน้าจอมาจากฐานข้อมูลของเรา ไม่ได้มาจากลิงก์
ถ้าค้นไม่เจอ ไม่ว่าจะเพราะเป็นลิงก์เก่าที่บทความถูกถอดไปแล้ว หรือเพราะมีใครพยายามใส่อะไรแปลก ๆ เข้ามา ระบบจะไม่ทำอะไรเลยนอกจากแสดงฟอร์มธรรมดา ไม่มีข้อความแจ้งเตือน และไม่มีการสะท้อนสิ่งที่ใส่มากลับไปบนหน้าจอ
ประกาศชื่อครั้งเดียวพอ ไม่ใช่สองครั้ง
โลโก้บนหน้าเว็บของเรามีสองสีครับ สีหนึ่งสำหรับพื้นสว่าง อีกสีสำหรับพื้นมืด วิธีที่ตรงไปตรงมาที่สุดคือใส่ไปทั้งคู่ แล้วให้ CSS ซ่อนอันที่ไม่ได้ใช้ ในทางสายตามันก็ถูกต้องสมบูรณ์ไม่มีที่ติ
แต่สำหรับโปรแกรมอ่านหน้าจอ การซ่อนด้วย CSS ไม่ได้แปลว่าไม่มีอยู่นะครับ ถ้าเราไม่ทำอะไรเพิ่ม ผู้ใช้ที่ตาบอดจะได้ยินชื่อบริษัทสองครั้งติดกันทุกครั้งที่โหลดหน้าใหม่ ซึ่งไม่ได้ผิดพลาดร้ายแรงอะไร แต่ลองนึกภาพว่าต้องฟังแบบนั้นทั้งวันดูสิครับ มันน่ารำคาญในแบบที่สะสมไปเรื่อย ๆ
สำเนาที่ถูกซ่อนไว้ เราจึงกำกับว่า aria-hidden และให้ข้อความแทนภาพเป็นค่าว่าง มันหายไปจากต้นไม้การเข้าถึงโดยสิ้นเชิง ชื่อบริษัทถูกประกาศครั้งเดียว
การทำสำเนาซ้ำเพื่อรองรับธีมเป็นเทคนิคที่ใช้กันทั่วไปและไม่มีอะไรผิดเลยครับ สิ่งที่ผิดคือการลืมไปว่ายังมีผู้ใช้อีกกลุ่มที่ไม่ได้ “เห็น” หน้าเว็บของเรา
เนื้อหาต้องไม่พังหน้าเว็บของเราได้
เนื้อหาบางส่วนของเว็บไซต์นี้มาจากระบบจัดการเนื้อหา ซึ่งแปลว่าคนที่เขียนเขาไม่ได้กำลังคิดถึงกริดหรือความกว้างของคอลัมน์หรอกครับ เขากำลังคิดถึงเรื่องที่จะเล่า และวันหนึ่งเขาจะใส่ตารางเจ็ดคอลัมน์เข้ามา เชื่อผมเถอะครับ
ตารางที่กว้างเกินคอลัมน์ ถ้าปล่อยไว้เฉย ๆ มันจะดันความกว้างของทั้งหน้า ผลคือทั้งเอกสารมีแถบเลื่อนแนวนอน หัวข้อทุกอันเลื่อนตามไปด้วย แล้วพอเปิดบนมือถือก็พังจนอ่านไม่ได้
ตารางทุกอันที่ออกมาจากระบบจัดการเนื้อหา เราจึงห่อด้วยกล่องที่เลื่อนได้ในตัวเอง ตารางจะกว้างเท่าไรก็ได้ครับ แต่มันเลื่อนอยู่ในกรอบของมันเอง ไม่ลากทั้งหน้าไปด้วย
หลักการคือระบบต้องทนต่อเนื้อหาที่คาดเดาไม่ได้ ไม่ใช่ไปขอให้คนเขียนคอยระวังตัวแทน เพราะข้อตกลงแบบหลังนี่ ถูกลืมภายในสามเดือนเสมอครับ
ปัญหาตระกูลเดียวกันที่เจอได้ทุกที่
พอรู้จักรูปแบบนี้แล้ว เพื่อน ๆ จะเห็นมันเต็มไปหมดเลยครับ
ช่องกรอกเลขบัตรเครดิตที่ปฏิเสธการวางข้อมูล เพราะมีช่องว่างคั่นทุกสี่หลัก ทั้งที่ช่องว่างนั้นผู้ใช้ไม่ได้พิมพ์เอง มันติดมาจากที่ที่แสดงผลไว้สวยงาม การลบช่องว่างออกให้เองเป็นโค้ดบรรทัดเดียวครับ การบังคับให้ผู้ใช้ทำเองคือการผลักงานไปให้คนที่กำลังจะจ่ายเงินให้เรา
ปุ่มคัดลอกที่คัดลอกข้อความที่จัดรูปแบบไว้แล้ว คนกดปุ่มก็เพราะเชื่อว่ามันจะให้ค่าที่ใช้ได้เลยใช่มั้ยครับ ปุ่มที่ให้สตริงที่ต้องมาแก้ต่อ จึงแย่กว่าการไม่มีปุ่มเสียอีก เพราะมันหลอกให้เราไว้ใจไปแล้ว
ฟอร์มที่ลบสิ่งที่พิมพ์ไปทั้งหมดเมื่อการตรวจสอบไม่ผ่าน อันนี้เจ็บที่สุดครับ กรอกครบสิบสองช่อง พลาดไปช่องเดียว กดส่ง แล้วได้หน้าว่างเปล่ากลับมาพร้อมข้อความว่ากรอกไม่ถูกต้อง นี่แหละครับคือจุดที่คนปิดแท็บทิ้ง และไม่มีตัวชี้วัดไหนจะบอกเราได้ว่าทำไม
เส้นที่ร้อยทุกเรื่องเข้าด้วยกัน
ไม่มีเรื่องไหนในบทความนี้เลยครับที่จะปรากฏในการรีวิวงานออกแบบ ไม่มีเรื่องไหนที่เห็นได้จากภาพหน้าจอ และไม่มีเรื่องไหนที่ลูกค้าจะชมเมื่อเห็นงานครั้งแรก
มันปรากฏในนาทีเดียวที่มีคนกำลังพยายามทำอะไรสักอย่างให้เสร็จ คนบัญชีที่กำลังปิดงบ คนที่กดปุ่มติดต่อหลังอ่านจบ คนที่ใช้โปรแกรมอ่านหน้าจอเปิดหน้าที่ยี่สิบของวัน
ในนาทีนั้น งานที่เราทำไว้ดีจะไม่ถูกสังเกตเห็นเลย และนั่นแหละครับคือความสำเร็จ
ถ้าเพื่อน ๆ อยากคุยเรื่องงานของคุณ ติดต่อเราได้เลยครับ
เกี่ยวกับผู้เขียน
ฟิล์ม — วิสิฏฐ์ ครับ ทำธุรกิจเป็นหลัก แต่ยังลงมือทำ BA เองอยู่บ่อยกว่าที่ควร และเขียนโค้ดได้ประปรายทั้งหน้าบ้านหลังบ้าน มีธุรกิจเล็ก ๆ อยู่สองสามบริษัท ติดตามวงการเทคโนโลยีและธุรกิจแบบคลั่งไคล้ ทั้งในไทยและต่างประเทศ นอกเวลางานชอบฟิสิกส์ ดาราศาสตร์ งาน DIY และเรื่องเน็ตเวิร์ก เปิดเพลงฟังตลอดเวลาแต่ร้องไม่เป็น ชอบเล่นดนตรีทั้งที่เล่นได้ไม่ค่อยดี เล่นกีฬาหลายอย่าง โดยเฉพาะกีฬาแร็กเกต เสียอยู่อย่างเดียวคือแทบไม่เล่นเกม
เขียนร่วมกับ Claude Opus 5