CSS Flexbox คืออะไร + สอนวิธีใช้

รู้จักกับ CSS Flexible Box Layout Module

ใน CSS 2.1 เราจะใช้สิ่งที่เรียกว่า “Layout Mode” ในการกำหนดขนาด และจัดตำแหน่งของกล่องต่างๆ ซึ่ง layout mode นี้จะประกอบไปด้วย

  • blockใช้จัดตำแหน่งเนื้อหาให้อยู่ในรูปแบบของ block
  • inlineใช้จัดตำแหน่งเนื้อหาให้อยู่ในรูปแบบของ text
  • tableใช้จัดตำแหน่งเนื้อหาให้อยู่ในรูปแบบตาราง
  • positionใช้จัดตำแหน่งของ elements ต่างๆ ได้อย่างอิสระมากขึ้น

ด้วยความซับซ้อนที่มากขึ้นของ web สมัยใหม่ การใช้ layout mode แบบเดิมๆ อาจทำให้เราเขียนโค้ดได้ไม่ค่อยสะดวกนัก CSS 3 จึงได้เพิ่ม layout mode แบบใหม่ ที่เรียกว่า “Flex Layout” เข้ามา โดย flex layout นี้เอง ที่จะช่วยให้กล่องต่างๆ มีความยืดหยุ่นมากขึ้น (Flexible Box หรือเรียกสั้นๆ ว่า Flexbox)

flex layout จะมีความคล้ายคลึงกับ block layout เพียงแต่ว่ามันจะใช้ property บางอย่าง เช่น float ไม่ได้ ในทางกลับกัน มันจะมี property ใหม่ๆ เพิ่มเข้ามาให้เราใช้งาน โดยความสามารถหลักๆ ของ flex layout มีดังนี้

  • Orientationสามารถกำหนดแนวการเรียงของ flexbox ต่างๆ ได้ ไม่ว่าจะเป็น บนลงล่าง ล่างขึ้นบน ซ้ายไปขวา ขวาไปซ้าย
  • Sizingสามารถกำหนดขนาดของ flexbox ต่างๆ ให้พอดีกับพื้นที่ว่างที่เหลืออยู่ได้อย่างอัตโนมัติ
  • Orderingสามารถเลือกลำดับการแสดงผลของ flexbox ได้ ลำดับของ flexbox อาจแตกต่างกันไปในแต่ละขนาดของ viewport
  • Alignmentสามารถกำหนด alignment ของ flexbox ต่างๆ ได้ ไม่ว่าจะเป็น ชิดซ้าย กึ่งกลาง หรือชิดขวา ทั้งในแนวนอนและแนวตั้ง

จะใช้ Flexbox ต้องทำอย่างไร ?

มาดูคำศัพท์เกี่ยวกับ flexbox ที่ต้องรู้กันก่อน

  • Flex containerคือ html element ที่กำหนด property “display” ให้มีค่าเป็น “flex” หรือ “inline-flex”
  • Flex itemหมายถึง html elements ใดๆ ก็ตาม ที่เป็น child ของ flex container

ก่อนที่เราจะสามารถใช้ความสามารถต่างๆ flexbox ได้ เราจะต้องสร้าง “flex container” ขึ้นมาก่อน โดยปกติแล้ว เวลาเราจะใช้ layout mode กับ elements ไหน เราก็จะต้องใส่ property “display” เอาไว้ที่ elements นั้นๆ แต่การใช้ flexbox จะเปลี่ยนไปตรงที่ เราจะต้องกำหนด property “display” เอาไว้ที่ element ที่เป็น container แทน ลองดูตัวอย่างโค้ดต่อไปนี้

จากโค้ดด้านบน เรากำหนดให้ “.flex” เป็น “flex container” div ต่างๆ ที่อยู่ภายใน “.flex” ก็จะกลายเป็น “flex item” เพียงเท่านี้ เราก็จะสามารถใช้ความสามารถของ flexbox ได้แล้ว

Workshop – ลงมือใช้ Flexbox กันเลย !

สมมติเราต้องการจะสร้าง layout ของหน้าเว็บแบบง่ายๆ ขึ้นมา โค้ด html ของเราจะหน้าตาประมาณนี้

เมื่อลองพรีวิวดู ที่ viewport ขนาด 320×480 ก็จะได้หน้าตาแบบนี้

flex_320_column

เริ่มด้วยการสร้าง Flex Container

ทีนี้เราจะลองมาใช้ flex layout ในการจัดการกับหน้าเว็บนี้ ให้เรากำหนด “.flex-container” ให้เป็น “flex container”

flex_320_row

เมื่อลองพรีวิวดูอีกที จะเห็นว่าหน้าตาของ layouts เปลี่ยนไป เราจะพบว่า flex items ทั้ง 3 เปลี่ยนมาเรียงตามแนวนอนแทน ที่เป็นเช่นนี้เพราะว่าค่า orientation เริ่มต้นของ flex container จะเป็น row หรือในแนวนอนนั่นเอง

Orientation

ที่ viewport ขนาดเล็ก เราต้องการให้ flex items ทั้ง 3 เรียงต่อกันในแนวตั้ง เราสามารถทำได้โดยการใช้ property “flex-direction” ในการกำหนดทิศทางการไหลของ flex items ให้เป็นแบบ column หรือในแนวตั้ง

flex_320_column

เราก็จะได้ layouts ตามที่ต้องการ ต่อมาให้เราลองขยาย viewport มาที่ขนาด 800×600 หน้าตาของ layouts ก็จะกลายเป็นแบบนี้

flex_800_column

ที่ viewport ขนาดนี้ เราอยากปรับ layouts ใหม่ จากเดิม 1 คอลัมน์ มาเป็นแบบ 3 คอลัมน์ แทน ให้เราเขียน media queries ขึ้นมาแบบนี้

จากโค้ดด้านบน จะได้ว่า ตั้งแต่ viewport ขนาด 800px เป็นต้นไป flex items จะไหลไปตาม row หรือในแนวนอนนั่นเอง เมื่อลองพรีวิวดู ก็จะได้ layouts แบบนี้

flex_800_row

Sizing

จากผลการพรีวิวล่าสุด จะเห็นว่าขนาดของ flex items ทั้ง 3 นั้นจะกางไม่เต็มพื้นที่ของ flex container ให้เราใช้ property “flex-grow” เข้ามาช่วย ลองเพิ่มโค้ดดังนี้

ตัวเลขของ “flex-grow” จะหมายถึงขนาดของ flex item นั้นๆ ว่าจะกางใน flex container แค่ไหน เมื่อเทียบกับ flex items อื่นๆ ในทีนี้ เรากำหนดให้ทุกๆ flex items มี flex-grow เท่ากันหมดคือ 1 เมื่อลองพรีวิวดู จะพบว่าขนาดของ flex items จะเท่ากันหมด และกางเต็ม flex container

flex_800_row_grow

Ordering

ในบางครั้ง เราอาจต้องการให้ลำดับการแสดงผลใน mobile ต่างจากใน desktop จะเห็นว่าใน mobile เราเลือกแสดง “.content” ขึ้นมาแรกสุด แต่ถ้าเป็น desktop เราอาจจะอยากให้ “.primary” แสดงผลขึ้นมาก่อน แล้วค่อยตามมาด้วย “.content” ปัญหานี้แก้โดยการใช้ property “order” เข้ามาช่วยในการกำหนดลำดับของการแสดงผล โดยตัวเลขของ order จะเป็นตัวกำหนดว่า flex items ไหนจะแสดงผลขึ้นมาก่อน

เมื่อลองพรีวิวดู จะพบว่า “.primary” นั้นแสดงผลขึ้นมาก่อน ตามมาด้วย “.content” และสุดท้ายคือ “.secondary”

flex_800_row_grow_order

Alignment

alignment ของ flexbox จะมีอยู่หลายแบบด้วยกัน ดังนี้

  • justify-contentกำหนดการจัดตำแหน่งของ flex items เมื่อเทียบกับทิศทางการไหลของ flexbox เช่น ชิดซ้าย กึ่งกลาง ชิดขวา เป็นต้น
  • align-itemsกำหนดการจัดตำแหน่งของ flex items เมื่อเทียบกับทิศทางที่ตรงข้ามกับการไหลของ flexbox เช่น บนสุด กึ่งกลาง ล่างสุด เป็นต้น
  • align-selfคล้ายกับ align-items แต่จะสามารถกำหนดที่แต่ละ flex item ได้เลย

ลองมาดูอีกตัวอย่างหนึ่ง สมมติว่าโค้ด html ของเราเป็นแบบนี้

เมื่อลองพรีวิวดู ก็จะได้หน้าตาแบบนี้

flex_800_box_start

ทีนี้ให้เราลองใช้ property “justify-content” ในการจัดตำแหน่งของ flex items ทั้งหลายดู

flex_800_box_justify_content

จะเห็นว่า property “justify-content” จะช่วยให้เราสามารถจัดตำแหน่งของ flex items ทั้งหลายให้ชิดซ้าย กึ่งกลาง หรือชิดขวา ได้อย่างง่ายดาย ต่อมาให้เราลองเปลี่ยนมาใช้ property “align-items” ในการจัดตำแหน่งของ flex items ทั้งหลายดูบ้าง

flex_800_box_align_items

ในทำนองเดียวกัน property “align-items” จะช่วยให้เราสามารถจัดตำแหน่งของ flex items ทั้งหลายให้อยู่บนสุด กึ่งกลาง หรือล่างสุด ได้ และสุดท้ายจะเป็น property “align-self” การใช้ property นี้ จะคล้ายกับการใช้ “align-items” แต่จะต่างกันตรงที่ “align-items” จะต้องกำหนดที่ตัว flex container ซึ่งมันจะส่งผลไปถึงทุกๆ flex items เลย ส่วน “align-self” นั้น เราสามารถกำหนดที่ตัว flex item ที่ต้องการจะจัดตำแหน่งเลย ลองดูตัวอย่างต่อไปนี้

เมื่อลองพรีวิวดู เราก็จะได้หน้าตาแบบนี้

flex_800_box_center_start_center_end

ข่าวร้าย! Spec ของ Flexbox มีหลายเวอร์ชั่น

specifications ของ flexbox นั้นเริ่มมีมาตั้งแต่ปี 2009 หลังจากนั้น ได้มีการปรับใหม่ในเดือนมีนาคม ปี 2012 และยังมีการปรับเพิ่มอีกครั้งจนกลายมาเป็น recommendation ในเดือนกันยายน ปี 2012

specs ทั้ง 3 เวอร์ชั่นนี้ มี syntax ที่ต่างกันออกไป และยังถูกนำไปใช้กับ web browsers ในรุ่นที่ต่างกันอีกด้วย web browsers รุ่นเก่าๆ ก็จะรองรับ spec ในปี 2009 ส่วน web browsers รุ่นใหม่หน่อยก็จะรองรับ spec ในช่วงต้นปี 2012 และ web browsers รุ่นล่าสุด ก็จะรองรับ spec ที่เป็น recommendation

การใช้ flexbox นั้นไม่ใช่เรื่องยาก แต่การจะทำให้ flexbox สามารถใช้ได้กับทุก web browsers นั้นเป็นเรื่องที่ยากกว่า สมมติว่าเราต้องการจะกำหนดให้ “.flex-container” เป็น flex container เราจำเป็นจะต้องเขียนแบบนี้

จากโค้ดด้านบน เราจำเป็นจะต้องกำหนด fallbacks สำหรับ web browsers ที่ยังไม่รองรับ spec ล่าสุดด้วย จะเห็นว่า syntax ในการสร้าง flex container นั้นแตกต่างกันไปในแต่ละเวอร์ชั่น ที่สำคัญคือ ในบาง properties นั้น ไม่ใช่แค่ต้องเพิ่ม prefix แต่กลับเปลี่ยนชื่อไปเลย ลองดูตัวอย่างต่อไปนี้

ตัวอย่างด้านบนจะเป็นการกำหนดลำดับการแสดงผลของ flex item ให้ใช้ได้ในทุก web browsers จะเห็นว่าชื่อของ properties นั้น แตกต่างกันไปในแต่ละเวอร์ชั่น ด้วยเหตุนี้เอง การจะเขียนให้ใช้ได้ทุก web browsers นั้น จึงเป็นเรื่องที่ค่อนข้างจะยุ่งยาก

ชีวิตสบายขึ้น เมื่อมี LESS

วิธีแก้ปัญหาก็คือ การใช้ “CSS Preprocessors” อย่าง “LESS” เข้ามาช่วย ให้เรากำหนด properties ต่างๆ ที่จะใช้กับ flexbox ให้เป็น “mixins” ไปเลย (หากยังไม่คุ้นเคยกับ LESS สามารถอ่านวิธีใช้ได้ที่บทความ “สอนวิธีเขียน CSS3 ง่ายๆ ด้วย LESS“)

จากนี้ไป เราก็จะสามารถเขียนสั้นๆ แบบนี้ได้แล้ว

การเขียน mixins สำหรับ properties อื่นๆ ของ flexbox สามารถดูรายละเอียดเพิ่มเติมได้ที่ ProLoser/Flexbox.less · GitHub

บทสรุปการใช้ Flexbox

specifications ของ flexbox ถูกเพิ่มเข้ามาก็เพื่อที่จะทำให้การสร้าง layouts ที่ซับซ้อนเป็นเรื่องที่ง่ายขึ้น การจะใช้ flexbox นั้นไม่ใช่เรื่องยาก แต่การทำให้ flexbox สามารถใช้ได้กับทุก web browsers นั้นเป็นเรื่องที่ยากกว่า เนื่องจาก web browsers ต่างๆ ยังรอบรับ spec คนละเวอร์ชั่นกัน ซึ่ง CSS Preprocessors จะสามารถช่วยเราในส่วนนี้ได้ จริงๆ แล้ว ความสามารถของ flexbox ยังมีนอกเหนือจากที่กล่าวไว้ในบทความ เราสามารถเข้าไปอ่านรายละเอียดทั้งหมดได้ที่ CSS Flexible Box Layout Module

(Visited 12,268 times, 1 visits today)

7 Responses to “CSS Flexbox คืออะไร + สอนวิธีใช้”

  1. SemicoloN07 says:

    ยังไม่ได้อ่าน แต่มาขอบคุณสำหรับการแบ่งปันครับ ยาวฝุดๆ
    ได้ความรู้อีกแล้ว เดี๋ยวมาอ่านทีหลัง อิอิ^^

    • Siam HTML says:

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

  2. วราโชติ ยัน อยาก เซ says:

    ง่ายขึ้นจริงๆ ขอบคุณครับ

  3. Slatong says:

    ยอดเยี่ยมมากครับ ขอบคุณสำหรับบทความดีๆครับ

  4. วัฒนา says:

    แล้วถ้าเปิดกะ ie จะเปิดปัญหาหรือเปล่าครับ

    • Siam HTML says:

      flexbox ใช้ได้ตั้งแต่ IE10+ ขึ้นไปครับ(ใส่ -ms-) แต่ยังรองรับไม่ครบทุกๆ properties นะครับ คงต้องรอดู IE11 อีกทีครับ

  5. แหล่มเลยครับ

Leave a Reply