ข้ามไปยังเนื้อหา

Display & Normal Flow

ก่อนที่คุณจะควบคุม layout ได้ คุณต้องเข้าใจว่าเกิดอะไรขึ้นเมื่อคุณ ไม่ทำอะไรเลย browser มีระบบในตัวสำหรับวาง elements บนหน้า เรียกว่า normal flow และไม่ใช่เรื่องสุ่ม แต่ทำตามกฎง่ายๆ สองข้อตาม display type ค่าเริ่มต้นของ element

ทุก HTML element เป็นแบบ block หรือ inline โดยค่าเริ่มต้น

Block elements ทำงานเหมือนชั้นวางแนวนอนที่ซ้อนกัน แต่ละอันใช้ความกว้างเต็มที่ และอันใหม่จะเริ่มในบรรทัดใหม่เสมอ ไม่ว่าเนื้อหาจะสั้นแค่ไหน คิดว่าเหมือน Figma frames ที่มีความกว้าง “Fill container” และความสูง “Hug contents” เรียงในแนวตั้งใน auto-layout

ตัวอย่าง: <div>, <p>, <h1><h6>, <section>, <article>

Inline elements ไหลตามข้อความ นั่งเคียงข้างกันและใช้เฉพาะความกว้างที่เนื้อหาต้องการ และไม่ขึ้นบรรทัดใหม่ คิดว่าเหมือนข้อความหรือไอคอนแต่ละตัวในบรรทัดข้อความ

ตัวอย่าง: <span>, <a>, <strong>, <em>, <img>

คุณสามารถแทนที่พฤติกรรมค่าเริ่มต้นของ element ใดก็ได้ด้วย property display:

ค่าสิ่งที่ทำ
blockชั้นวางเต็มความกว้าง ขึ้นบรรทัดใหม่
inlineไหลตามข้อความ ไม่สามารถควบคุมความกว้าง/ความสูงได้
inline-blockไหลตามข้อความ แต่ สามารถ ตั้งความกว้างและความสูงได้
flexเปิดใช้งาน Flexbox กับ children
gridเปิดใช้งาน Grid กับ children
noneซ่อน element อย่างสมบูรณ์ (ไม่ใช่แค่มองไม่เห็น — ถูกลบออกจาก layout)

ตัวอย่างที่แก้ไขได้ด้านล่างมีทั้ง block และ inline elements ลองเปลี่ยน .label จาก display: inline เป็น display: inline-block และเพิ่ม width: 100px — สังเกตว่าตอนนี้คุณสามารถควบคุมขนาดได้ แล้วลอง display: block เพื่อดู label กระโดดไปอยู่บรรทัดของตัวเอง

เมื่อคุณใช้ Flexbox หรือ Grid คุณกำลัง แทนที่ กฎ normal-flow สำหรับ children ของ element นั้น property display คือสวิตช์เปิด/ปิด การเข้าใจว่า normal flow มีหน้าตาอย่างไรทำให้เห็นชัดทันทีว่าทำไมการเพิ่ม display: flex ให้กับ container ถึงเปลี่ยนทุกอย่าง — คุณกำลังเลือกออกจากกฎการซ้อนค่าเริ่มต้น

  • ตั้ง position: absolute กับทุก element แทนปล่อยให้ flow ตามธรรมชาติ ทำให้ responsive พังหมด
  • ไม่เข้าใจว่า inline element ไม่รับ width/height โดยตรง จนกว่าจะเปลี่ยนเป็น inline-block หรือ block

Designer เห็น “element ลอยอยู่ตรงนี้” แต่ developer เห็นว่า default display (block/inline) กำหนดว่า element ไหลต่อกันยังไงโดยไม่ต้องเขียน code เพิ่มเลย

💡 ตัวอย่างจากของจริง

Notion’s block editor ใช้ normal flow (block-level element เรียงต่อกัน) เป็นพื้นฐาน ทำให้ content ยืด/หดตามจำนวนตัวอักษรได้เอง

block element ทำอะไรตามค่าเริ่มต้น?
ค่า display ใดที่ให้ element ไหลตามข้อความและรับความกว้างที่กำหนดได้?
`display: none` ทำอะไร?
ข้อใดคือ inline element ตามค่าเริ่มต้น?