เมื่อ HTML ไม่ใช่ XML – ความมึนของนักพัฒนาโปรแกรม

สำหรับเรา ๆ ชาวโปรแกรมเมอร์คงต้องมีสักครั้งที่ต้องเขียนไฟล์ XML (ถ้าไม่เคยก็คงเพราะคุณอายุมากแล้ว (ใช้ CSV) ไม่ก็ยังเด็กเกินไป (ใช้ JSON)) XML เป็นเทคโนโลยีที่เกิดขึ้นเมื่อสักสิบปีที่แล้วเห็นจะได้ และถูกใช้ในกันอย่างกว้างขวาง จนพอจะเรียกได้ว่าใช้เยอะไปหน่อยก็คงได้มั้ง ??

XML เป็นเทคโนโลยีที่พัฒนามาจาก HTML 2.0 (ถ้าผมจำไม่ผิด) โดยการเปลี่ยนจากการใช้ชุดของ  Tag ที่กำหนดตายตัว มาเป็นให้นักพัฒนาสร้างชุด Tag ขึ้นมาเอง ซึ่งการยอมให้นักพัฒนาสร้าง Tag ขึ้นมาในครั้งนี้มาพร้อมกับการลดความกำกวมที่มีในชุด  Tag ของ HTML กล่าวคือใน  XML ทุก Tag จะต้องมี Tag ปิดท้ายด้วยเสมอ เมื่อเทียบกับ HTML ที่บาง Tag นั้นไม่ต้องปิดก็ได้

ทีนี้มันก็จะมีบางงานที่เราต้องใช้ทั้ง HTML และ  XML ในโปรเจคเดียวกัน … ที่จริงคือ มีเยอะเลยแหละ ก็บรรดา Web App จำนวนมากใช้ AJAX  ในการแลกเปลี่ยนข้อมูล ความสับสนระหว่าง HTML และ XML นั้นเกิดขึ้นกับหลาย ๆ คน รวมทั้งผมด้วย (นี่ล่ะเหตุที่ผมเขียน Entry นี้) ลองดูโค๊ดข้างล่างนี้ก่อนนะครับ แล้วลองตอบตัวเองว่ามันมีปัญหาอะไร  🙂  (ให้เวลาคิด 15 วินาทีนะ)

<!doctype html>
<script src="jquery.js"/>
<h1>Spot the error!</h1>

บางคนคงบอกว่า  ไม่ถูก หรือบางคนก็คงบอกว่า script ไม่มี language … สองอันนี้ถูกอยู่แล้วนะครับ (เป็นฟีเจอร์ของ HTML5)  จุดที่ผิดอยู่ที่ <script src="jquery.js"/> ครับ

ถ้าจะแก้ให้ถูกต้อง ต้องเขียนแบบนี้ครับ

<!doctype html>
<script src="jquery.js"></script>
<h1>Spot the error!</h1>

เห็นอะไรไหมครับ ? Tag <script> นั้นจะต้องปิดด้วย </script> เสมอ เพราะว่าจริง ๆ แล้ว Tag นี้ถูกระบุว่าควรมีเนื้อหาภายใน (แต่อันนี้ไม่มี 555)

แต่เหตุผลจริง ๆ ก็คงเป็นว่า ใน HTML ไม่มี self-closing tag ครับ ด้วยเหตุด้านความเข้ากันได้กับเวปเพจรุ่นเก่า ๆ โดยใน  HTML นั้นจะมี Tag อยู่สองประเภท คือ Tag ที่อยู่ด้วยตัวมันเองได้ (ไม่มีเนื้อหาภายใน เช่น  br, hr, link เป็นต้น) กับ Tag ที่ต้องมี Tag ปิด (มีเนื้อหาภายใน เช่น p, h1, small, i เป็นต้น)

ส่วน self-closing tag นั้นเป็นฟีเจอร์ของ XML ครับ

อธิบายต่อ ทีนี้ ถ้าเวปเรามี Tag ที่เป็น  self-closing  แล้วมันจะเป็นอย่างไร ? สำหรับนักพัฒนา XML ก็คงคิดว่า ตัว web browser นั้นจะปิดแท็กให้ … แต่ในความเป็นจริงแล้วตัว HTML parser จะมองว่า self-closing tag เป็นแค่ tag เปิดครับ และจะไม่ใส่ tag ปิดให้ (จนกระทั่งมันเริ่มรู้ว่ามี tag ที่เปิดค้างอยู่นั่นแหละ)

อย่างโค๊ดข้างล่างนี้ …

<!doctype html>
<script src="jquery.js"/>
<h1>Spot the error!</h1>

จะถูก parse กลายเป็น

<!doctype html>
<script src="jquery.js">
    <h1>Spot the error!</h1>
</script>

ความหมายผิดไปเลย เห็นไหมครับ ?

ผมคิดว่าทุกคนคงจะเห็นแล้วว่าปัญหาอยู่ที่ตรงไหน เชื่อไหมครับผมใช้เวลาเกือบครึ่งเดือนหาว่าบั๊กที่ผมเจอนั้นเกิดจากอะไรจนมารู้เรื่องนี้แหละ รู้สึกเหมือนถูกตีหัวแรง ๆ เลยครับ 555

บางคนคงคิดเหมือนกันว่าทำไมเราถึงไม่มี HTML ในรูปของ XML อันที่จริงมันก็มีครับ ชื่อว่ามาตรฐาน XHTML แต่ว่ามาตรฐานนี้แท้งไปแล้ว เพราะว่าพัฒนานานเกินและผู้ผลิต Browser ดูจะไม่ค่อยจริงจังกับมันเท่าไหร่ (ทั้ง ๆ ที่ความจริงถ้ามาตรฐานนี้ผ่าน ตัว Parser จะทำงานง่ายมากเลย และความเร็วในการอ่าน Parse จะเร็วขึ้นอย่างเห็นได้ชัด) สุดท้ายก็เลยมีแค่ HTML 5 ที่อยู่รอดมาจนถึงปัจจุบันนี้ครับ

Request & Order

เวลาที่เราต้องการให้ผู้อื่นทำอะไรให้ วิธีที่เรามักจะทำก็คือการบอกให้คนอื่นทำ ซึ่งการบอกนี้มีอยู่สองอย่างก็คือการขอ และการสั่ง

สองอย่างนี้ต่างกันอย่างไร ? ความแตกต่างอยู่ที่การตัดสินใจว่าจะทำหรือไม่ทำนั้นถูกกระทำโดยผู้พูด หรือผู้ฟัง การสั่งคือการบอกให้ผู้ฟังทำโดยไม่มีข้อแม้ ในขณะที่การขอนั้นให้สิทธิในการตัดสินใจว่าจะทำหรือไม่แก่ผู้ฟัง

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

การให้สิทธิการตัดสินใจที่จะกระทำตามนั้นเป็นการทำให้อีกฝ่ายนั้นรู้สึกว่าตัวเองมีอำนาจ (ถึงแม้อาจจะไม่ได้มากเท่าของผู้พูดก็ตาม) ซึ่งทำให้ผู้ฟังเต็มใจที่จะกระทำตามคำพูดของผู้พูด

ส่วนการยึดสิทธิการตัดสินใจมาเป็นของตัวเองนั้น ในแง่หนึ่งก็เป็นการบีบบังคับผู้ฟังให้ปฎิบัติตามคำพูดของตน ในอีกแง่หนึ่งก็เป็นการแสดงอำนาจของผู้พูด และในอีกแง่หนึ่งก็เป็นการดูถูกผู้ฟังว่าเป็นได้แค่เพียงผู้ปฎิบัติ ไม่มีสิทธิมีเสียงในการคิดแต่อย่างใด

ทั้งนี้มีการใช้คำขอในสถานการณ์ที่เป็นคำสั่งเช่นกัน กล่าวคือ ถ้าเป็นคำขอที่มีอำนาจสูงกว่ามาก ๆ ผู้ฟังก็ย่อมปฎิบัติตามอยู่แล้ว ดังนั้นคำขอในลักษณะเช่นนี้ก็เป็นคำสั่งกลาย ๆ แต่ผู้ฟังเองก็ไม่ได้รู้สึกว่าตัวเองถูกบีบบังคับ จะกลายเป็นการปฎิบัติตามหน้าที่ไป

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

ผมคิดว่า ผู้นำที่มีความสามารถสูง ๆ จะสามารถแยกแยะสถานการณ์ที่เหมาะกับการใช้คำสั่ง และสถานการณ์ที่เหมาะกับการใช้คำขอ ซึ่งในความเป็นจริงผมว่าสถานการณ์ที่ต้องใช้คำสั่งจริง ๆ นั้นมีน้อยมาก

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

ดังนั้น ถ้าไม่จำเป็นจริง ๆ ลองใช้คำขอแทนดีกว่าครับ

ถ้าเราต้องการจะแก้ Web เก่า ๆ ให้ปรับเปลี่ยนหน้าตาได้ง่าย ๆ ควรจะทำอย่างไรก่อน ?

ถ้าย้อนอดีตกลับไปสักยี่สิบปี (โห นานมาก) ในขณะที่เรากำลังเริ่มใช้ WWW กันใหม่ ๆ สิ่งที่บนเวปมีก็คือ กองไฟล์รูป กับ HTML เท่านั้น แต่พอเวลาผ่าน อะไรมันก็เพิ่มเข้ามา ไฟล์วิดีโอเอย ไฟล์เสียงเอย สคริปท์เอย โน่นนั่นนี่เต็มไปหมด แต่แกนกลางของ WWW ก็ยังคงเป็น HTML

หลาย ๆ คนที่เคยทำเว็บไซต์ในช่วงนั้นคงจะจำได้ว่า เวลาทำเว็บจะต้องทำหัวเว็บใหม่ ทำพื้นหลังใหม่ ทำโน่นนั่นนี่ใหม่ ทุกครั้งที่ทำหน้าเว็บขึ้นมาใหม่หนึ่งหน้า เป็นที่น่ารำคาญเล็กน้อย ในตอนนั้นก็มีตัวช่วยเข้ามาอย่างการใช้ frame (ที่ปัจจุบันไม่แนะนำให้ทำกันแล้ว) หรือการใช้ Template ซึ่งก็ผูกกับ Editor ที่เราใช้

พัฒนาการหลังจากนั้นก็คือการแยกเอา Attribute ที่เกี่ยวข้องกับรูปแบบการแสดงผลของ HTML มารวมกันเป็นภาษาใหม่ เรียกว่า Cascading Style Sheet (CSS) ทำให้ส่วนที่อยู่ใน HTML นั้นมีเพียงแต่เนื้อหาเท่านั้น

หลาย ๆ คนในอดีตคงไม่คิดถึงว่า ในอนาคต เราจะมีจอภาพ 4K ขนาด 80″ หรือ จอภาพ 1080p ขนาด 4.6″ เราทำเวปเพื่อหน้าจอขนาดใกล้เคียงกัน ความละเอียดใกล้เคียงกัน ก็คือตามขนาดของหน้าจอคอมพิวเตอร์นั่นเอง (ถึงแม้ว่ามาตรฐานตอนนั้น (15″) กับตอนนี้ (23″) จะต่างกันมากก็ตาม แต่ก็คงเทียบกับ 80″ บนจอทีวีไม่ได้หรอกครับ) การใช้ CSS นั้นดูจะเป็นภาระมากกว่าประโยชน์ เราก็เลยใช้ HTML ในการสร้างโค๊ดสำหรับการแสดงผล

ผมว่าหลายคนคงนึกไม่ออกว่า การใช้ HTML แทน CSS ในการแสดงผลนั้นเป็นยังไง คืออย่างนี้ครับ ผมว่าหลาย ๆ คนคงเคยทำเวปที่มีส่วนหัว (header) ส่วนเนื้อหา (content) และส่วนท้าย (footer) แยกจากกันโดยใช้ Table ใช่ไหมครับ ?

<!doctype html>
<html>
    <table>
        <tr>
            <td>...Header....</td>
        </tr>
        <tr>
            <td>Content Content Content Content Content Content Content </td>
        </tr>
        <tr>
            <td>...Footer....</td>
        </tr>
   <table>
</html>

ถามว่าแสดงผลถูกใหม ? ผมว่าไม่มีปัญหา ทีนี้ถ้าเราต้องการจะแก้ไขให้มันแสดงผลเป็นอีกแบบนึงล่ะ สมมติว่า เฮ้ย ผมอยากทำให้มันแสดงผลในแนวนอนล่ะ ? ทำไงดี ? ถ้าเราใช้วิธีเดียวกันผมก็ต้องแก้ HTML ครับ ก็จะกลายเป็นแบบนี้

<!doctype html>
<html>
    <table>
        <tr>
           <td>...Header....</td>
           <td>Content Content Content Content Content Content Content</td>
           <td>...Footer....</td>
        </tr>
    </table>
</html>

มันก็จะแสดงผลเป็นสามคอลัมภ์ตามแนวนอนอย่างที่เราต้องการเช่นกัน …

ปัญหาจะมาอีตอนที่บอกว่า ผมมีหน้าที่ต้องเปลี่ยน Layout อยู่ 100 หน้า การใช้ HTML ในการกำหนด Layout เป็นการล็อกตายตำแหน่งเนื้อหาไปแล้วเรียบร้อย ดังนั้นผมต้องแก้ไขหมด 100 ไฟล์ ผมคงตายครับแบบนี้ 555 เหนื่อยแย่

ถ้าใช้ HTML + CSS ผมก็จะเปลี่ยนโค๊ดข้างบนเป็น…แบบนี้ ..

<!doctype html>
<div id="header">....Header....</div>
<div id="content">Content Content Content Content Content Content Content</div>
<div id="footer">...Footer....</div>

ร่วมกับ CSS เพื่อจัดให้มันเป็นเนื้อหา 1 คอลัมพ์ 3 แถว หรือ จัดให้เป็น 3 คอลัมภ์ 1 แถว ก็ได้ (หรือจัดให้พิศดารกว่านั้นก็ได้ (ทั้งนี้ถ้าเราไม่ใช้ CSS เลย ตัว Browser จะแสดงออกมาเป็น 1 คอลัมภ์ 3 แถวครับ)

ดังนั้น ถ้าเรามี Web ที่เขียนมาตั้งแต่สมัย HTML4 นู่น ผมว่า ถ้าเราต้องการจะทำให้หน้าตามันดูดีในปัจจุบัน (ไม่นับเรื่องโครงสร้างโปรแกรมข้างหลังนะ) สิ่งแรกที่ควรทำคือ แยกเอา layout ออกมาจาก HTML ไปใส่ใน CSS ให้หมด ส่วน HTML นั้นให้ทำแค่แยกเนื้อหาเป็นชิ้น ๆ รวมกันภายใน div เมื่อทำได้ดังนี้แล้วการจะวาง layout ให้สวยก็ไม่ใช่เรื่องยาก

(ก็ไม่ง่ายหรอก ผมว่าแก้ CSS มันยากกว่าแก้ HTML แต่มันได้ประโยชน์ในระยะยาวนะ)

ในกรณีของ Web Application นั้น ถ้าเกิดว่าเรามีลูกค้าหลายเจ้าที่ต้องการให้แสดงผลไม่เหมือนกันเลย เราสามารถใช้ CSS ในการช่วยให้ลูกค้าแต่ละเจ้าเห็นหน้าตาเว็บไม่เหมือนกันได้ครับ ก็คือให้แต่ละเจ้ามี CSS เป็นของตัวเองไปเลยนั่นเอง (ถ้าเป็นกรณี HTML นั้นตายครับ ต้องมีโค๊ดแยกกันระหว่างลูกค้าแต่ละเจ้า แก้บั๊กกันทีตาเหลือก)

อ้อสำหรับ HTML5 นั้นมีการเพิ่ม Tag เข้ามาในส่วนของ HTML Semantic (ซึ่งช่วยในการแยกแยะประเภทของ Content แต่ละส่วนในหน้า HTML นั้น ๆ ว่าเป็นประเภทใด) ดังนั้นแทนที่เราจะใช้ div อย่างเดียว เราก็สามารถใช้ Semantic Tag ช่วย ทำให้อ่านโค๊ดได้ง่ายขึ้นอีกมากทีเดียว) ซึ่งจากโค๊ด HTML ข้างบนก็สามารถเขียนอยู่ในรูปแบบนี้ได้ครับ

<!doctype html>
<header>....Header....</header>
<article>Content Content Content Content Content Content Content</article>
<footer>...Footer....</footer>

อ่านง่ายกว่าข้างบนไหม บางคนก็คงแย้งว่าไม่ … อืม สมมติว่าส่วน content ผมมีสัก 50 บรรทัดล่ะครับ 🙂 ลองคิดดูนะว่าเราเคยทรมาณกับการนั่งหาว่า ไอ้ </div> เนี่ยมันไปคู่กับ <div> อันไหนกันแน่

ก็ลองดูกันละกันนะครับ