บทความ

เคล็ดลับ HTML 10 ข้อ ที่ใช้ได้เลยโดยไม่ต้องเขียน JavaScript

รวม tag กับ attribute ของ HTML ที่ช่วยงานหน้าเว็บได้โดยไม่ต้องเขียน JavaScript ตั้งแต่ lazy load รูป ลิงก์โทรออก meter และ datalist ไปจนถึง accordion ด้วย details พร้อมเช็คการรองรับของเบราว์เซอร์ใหม่

เผยแพร่
อัปเดต
— เช็คการรองรับของเบราว์เซอร์ใหม่ แก้เรื่อง Safari กับ noopener และเพิ่ม details name
เวลาอ่าน
4 นาที
สรุปจาก
Marko Denic · markodenic.com
แท็ก
#CSS

ที่ผ่านมาเรามักหยิบ JavaScript หรือ library มาช่วยทำเรื่องเล็ก ๆ บนหน้าเว็บ ทั้งที่ HTML มี tag หรือ attribute ทำให้อยู่แล้ว โพสต์นี้รวมมาไว้ 10 ข้อ พร้อมสถานะการรองรับของเบราว์เซอร์ ณ ตุลาคม 2569

1. loading="lazy" ชะลอโหลดรูปที่ยังไม่โผล่บนจอ

ใส่ loading="lazy" ใน <img> แล้วเบราว์เซอร์จะยังไม่โหลดรูปนั้น จนกว่าผู้ใช้เลื่อนลงมาใกล้ หน้าที่มีรูปเยอะ ๆ จะเปิดเร็วขึ้นและเปลืองเน็ตน้อยลง

<img src="image.jpg" loading="lazy" width="800" height="600" alt="คำอธิบายรูป">

ใส่ width กับ height ไว้ด้วย เบราว์เซอร์จะกันที่ให้รูปไว้ก่อน หน้าเว็บจะไม่กระตุกตอนรูปโหลดเสร็จ และอย่าใส่ loading="lazy" ให้รูปที่เห็นทันทีตอนเปิดหน้า เช่นรูป banner ด้านบน เพราะจะทำให้รูปหลักขึ้นช้าลง (web.dev)

ตอนเขียนโพสต์นี้ครั้งแรก Safari ยังไม่รองรับ ตอนนี้รองรับแล้วตั้งแต่ Safari 15.4 (มี.ค. 65) ส่วน <iframe loading="lazy"> รองรับตั้งแต่ Safari 16.4 ดูตารางได้ที่ Can I use ทั้งของ รูป และ iframe เราจึงไม่ต้องใช้ library เสริมแล้ว

อ่านเพิ่มเรื่อง lazy loading ได้ที่ MDN

2. ลิงก์ <a> ส่งอีเมล โทรออก และส่ง SMS ได้

href ใน <a> ไม่จำเป็นต้องเป็นลิงก์เว็บ ใส่ scheme ด้านล่างนำหน้าแทนได้ (MDN)

mailto: เปิดโปรแกรมอีเมลพร้อมหัวเรื่อง

<a href="mailto:[email protected]?subject=Project%20inquiry&body=Hi">
    ส่งอีเมลหาเรา
</a>

ช่องว่างและภาษาไทยใน subject กับ body ต้อง encode ก่อน (RFC 6068) ถ้าสร้างลิงก์ใน Blade ใช้ rawurlencode() ได้เลย

<a href="mailto:[email protected]?subject={{ rawurlencode('สอบถามโปรเจกต์') }}">
    ส่งอีเมลหาเรา
</a>

tel: โทรออก

<a href="tel:+66812345678">
    081-234-5678
</a>

ใส่เบอร์แบบมีรหัสประเทศ (+66 แล้วตัด 0 ตัวหน้า) จะโทรได้ถูกไม่ว่าผู้ใช้อยู่ประเทศไหน

sms: ส่ง SMS

<a href="sms:+66812345678?body=Hello">
    ส่ง SMS หาเรา
</a>

tel: กับ sms: เหมาะกับผู้ใช้บนมือถือ กดแล้วเปิดแอปโทรศัพท์หรือแอปข้อความพร้อมเบอร์ให้เลย บนคอมพิวเตอร์จะเปิดโปรแกรมที่โทรได้แทน เช่น FaceTime ส่วน ?body= ของ SMS เขียนตาม RFC 5724 แต่แอปข้อความแต่ละเครื่องอ่านไม่เหมือนกัน ลองกดบนทั้ง iPhone และ Android จริงก่อนขึ้นเว็บ

3. <ol start> เริ่มนับเลขจากเลขไหนก็ได้

ใส่ start ใน <ol> เพื่อบอกว่าให้เริ่มนับจากเลขอะไร เหมาะกับรายการที่ต่อจากหน้าก่อน หรือแบ่งเป็นหลายช่วง

<ol start="5">
  <li>Laravel</li>
  <li>PHP</li>
  <li>Tailwind</li>
  <li>CSS</li>
  <li>Javascript</li>
</ol>

ผลลัพธ์: รายการที่เริ่มนับจากเลข 5

ถ้าอยากนับถอยหลัง ใส่ reversed เพิ่มได้ (MDN)

4. <meter> แสดงระดับค่าโดยไม่ต้องเขียน JavaScript หรือ CSS

<meter> แสดงค่าที่วัดได้ในช่วงที่รู้ขอบเขต เช่นพื้นที่ดิสก์ที่ใช้ไป หรือคะแนนสอบ low กับ high แบ่งช่วงเป็นต่ำ กลาง สูง ส่วน optimum บอกว่าช่วงไหนคือค่าที่ดี แล้วเบราว์เซอร์จะเปลี่ยนสีแถบให้เอง (MDN)

<label for="value1">Low</label>
<meter id="value1" min="0" max="100" low="30" high="75" optimum="80" value="25"></meter>

<label for="value2">Medium</label>
<meter id="value2" min="0" max="100" low="30" high="75" optimum="80" value="50"></meter>

<label for="value3">High</label>
<meter id="value3" min="0" max="100" low="30" high="75" optimum="80" value="80"></meter>

ผลลัพธ์: แถบ meter สามระดับ สีแดง เหลือง และเขียว

ตัวอย่างนี้ตั้ง optimum ไว้ที่ 80 ซึ่งอยู่ในช่วงสูง ค่า 80 จึงเป็นสีเขียว ค่า 50 อยู่ช่วงกลางเป็นสีเหลือง และค่า 25 ต่ำกว่า low เป็นสีแดง ถ้าจะแสดงความคืบหน้าของงาน เช่นอัปโหลดไฟล์ ให้ใช้ <progress> แทน

5. <datalist> ทำช่องค้นหาที่มีตัวเลือกให้

ผูก <input list="…"> เข้ากับ <datalist id="…"> แล้วช่องกรอกจะมีรายการให้เลือกตอนพิมพ์ เหมาะกับฟอร์มที่มีค่าไม่มากและเรารู้ค่าที่น่าจะกรอกอยู่แล้ว

<div class="wrapper">
  <h1>Native HTML Search</h1>

  <input list="items">

  <datalist id="items">
    <option value="Laravel">
    <option value="PHP">
    <option value="Tailwind CSS">
    <option value="CSS">
    <option value="Javascript">
    <option value="Alpine JS">
  </datalist>
</div>

ผลลัพธ์: ช่องกรอกที่มีรายการให้เลือกขณะพิมพ์

<datalist> เป็นแค่คำแนะนำ ผู้ใช้ยังพิมพ์ค่าอื่นที่ไม่อยู่ในรายการได้ ถ้าต้องบังคับให้เลือกจากรายการเท่านั้นให้ใช้ <select> และ Firefox บน Android ยังไม่แสดงรายการ (Can I use) ช่องกรอกจึงกลายเป็นช่องข้อความธรรมดา

6. <fieldset disabled> ปิดทุกช่องในกลุ่มทีเดียว

<fieldset> รวมช่องในฟอร์มเป็นกลุ่มเดียวกัน ใส่ disabled ที่ <fieldset> แล้วทุกช่องข้างในจะกดไม่ได้ ไม่ต้องไล่ใส่ทีละตัว

<form>
  <fieldset disabled>
    <legend>ที่อยู่จัดส่ง</legend>

    <input type="text" name="address">
    <select name="province">
      <option>กรุงเทพมหานคร</option>
      <option>เชียงใหม่</option>
    </select>
    <textarea name="note"></textarea>
    <label><input type="checkbox" name="gift"> ห่อของขวัญ</label>
  </fieldset>
</form>

ช่องที่ disabled จะไม่ส่งค่าไปกับฟอร์ม (MDN) ถ้ายังอยากให้ค่าส่งไปด้วยแต่ห้ามแก้ ใส่ readonly ที่ <input> แทน ส่วนช่องที่อยู่ใน <legend> จะไม่โดนปิดไปด้วย

7. target="_blank" ไม่ต้องใส่ rel="noopener" เองแล้ว

เดิมหน้าที่เปิดจากลิงก์ target="_blank" เข้าถึงหน้าเราได้ผ่าน window.opener เว็บปลายทางจึงสั่งเปลี่ยนหน้าเดิมของเราไปเป็นหน้าหลอกได้ เราเลยต้องใส่ rel="noopener" กันไว้ทุกลิงก์

ตอนนี้เบราว์เซอร์ทำให้ target="_blank" ทำงานเหมือนใส่ rel="noopener" ให้เองแล้ว (MDN) ตั้งแต่ Chrome 88, Firefox 79 และ Safari 12.1 (Can I use) ใส่ไว้ก็ไม่เสียหาย แต่ไม่ต้องไล่เติมในโค้ดเก่า

<a href="https://phattarachai.dev/" target="_blank" rel="noreferrer">
    phattarachai.dev (เปิดในแท็บใหม่)
</a>

ถ้าไม่อยากให้เว็บปลายทางรู้ว่าผู้ใช้มาจากหน้าไหน ใส่ rel="noreferrer" ซึ่งรวมผลของ noopener ไว้ด้วย (MDN) และบอกผู้ใช้ในข้อความลิงก์ว่าจะเปิดแท็บใหม่

8. <details name> ทำ accordion ที่เปิดได้ทีละอัน

<details> กับ <summary> ทำกล่องที่กดเปิดปิดได้อยู่แล้ว ถ้าใส่ name เดียวกันให้หลายกล่อง เปิดกล่องหนึ่งแล้วกล่องอื่นในกลุ่มจะปิดเอง ได้ accordion แบบหน้า FAQ โดยไม่ต้องเขียน JavaScript (MDN)

<details name="faq" open>
  <summary>จัดส่งกี่วัน</summary>
  <p>กรุงเทพฯ 1-2 วัน ต่างจังหวัด 2-3 วัน</p>
</details>

<details name="faq">
  <summary>ชำระเงินทางไหนได้บ้าง</summary>
  <p>โอนผ่านธนาคาร หรือสแกน QR พร้อมเพย์</p>
</details>

<details name="faq">
  <summary>เปลี่ยนสินค้าได้ไหม</summary>
  <p>เปลี่ยนได้ภายใน 7 วันหลังได้รับของ</p>
</details>

name ใช้ได้ตั้งแต่ Chrome 120, Firefox 130 และ Safari 17.2 (Can I use) เบราว์เซอร์รุ่นเก่ากว่านั้นก็ยังเปิดปิดได้ตามปกติ แค่เปิดพร้อมกันได้หลายกล่อง

9. <mark> ไฮไลต์ข้อความ

ใช้ <mark> ครอบข้อความที่อยากเน้น เบราว์เซอร์จะแสดงเป็นพื้นสีเหลือง

<p>ตัวอย่างข้อความที่ต้องการ<mark>ไฮไลต์</mark>บน HTML</p>

ตัวอย่างหน้าตาด้านล่างใช้ปากกาไฮไลต์ของเว็บนี้แทน <mark> จริง

ตัวอย่างข้อความที่ต้องการไฮไลต์บน HTML

10. download ให้ลิงก์ดาวน์โหลดไฟล์แทนเปิดดู

ใส่ download ใน <a> เพื่อบอกเบราว์เซอร์ให้ดาวน์โหลดไฟล์ แทนที่จะเปิดไฟล์ขึ้นมาดู ใส่ชื่อไฟล์เป็นค่าของ download ได้ด้วย

<a href="/files/report-2569.pdf" download="รายงานประจำปี.pdf">
    ดาวน์โหลดรายงาน
</a>

download ใช้ได้เฉพาะไฟล์ที่อยู่โดเมนเดียวกับหน้าเว็บ หรือ URL แบบ blob: กับ data: (MDN) ถ้าไฟล์อยู่ที่อื่น เช่นบน S3 ใน Laravel ให้ส่งไฟล์ผ่าน route ของเราด้วย Storage::download() แทน และถ้า server ส่ง header Content-Disposition ที่มีชื่อไฟล์มา เบราว์เซอร์จะใช้ชื่อนั้นแทนชื่อใน download

อ่านต่อ

ล่าสุด

ดูทั้งหมด →