.::www.Chayoo.in.th::.

 ลืมรหัสผ่าน
 สมัครสมาชิก
ค้นหา
ดู: 168|ตอบกลับ: 0

(เก็บไว้อ่าน) CSS จัดตำแหน่ง https://www.babelcoder.com/blog/posts/flexbox-and-auto-margins

[คัดลอกลิงก์]
Flexbox เป็นหนึ่งสิ่งมหัศจรรย์ในยุครุ่งเรืองของ CSS อีลีเมนต์ไหนที่ใส่เป็น display: flex หรือ inline-flex ก็เปรียบเสมือนเป็นกล่อง ถ้ากล่องวางแนวนอนของในกล่องก็ไหลตามแนวนอน แต่ถ้าจับตั้งเสียของในกล่องก็จะวางซ้อนกันในแนวดิ่งนั่นเอง
เราทราบกันดีว่าการไหลของอีลีเมนต์ในกล่องจะมีทิศทางตามแกนหลักของมัน (main axis) เช่นถ้าวางกล่องแนวนอน แกนหลักก็จะเป็นแกนนอน เมื่อมีแกนหลักย่อมมีแกนตั้งได้ฉากกับแกนหลักเรียกว่า cross axis โดยเราสามารถจัดวางตำแหน่งของอีลีเมนต์ได้ทั้งสองแกน หากแต่แกนหลักนี่หละคือตัวปัญหาจึงเป็นที่มาของบทความนี้
สารบัญ


มาตรฐาน Flex ไม่มี justify-self
กำหนดให้หน้าเพจของเรามีก้อน HTML ดังนี้
<div id="container">  <div class="box" id="box1">1</div>  <div class="box" id="box2">2</div>  <div class="box" id="box3">3</div></div>
เราสามารถจัดตำแหน่งของอีลีเมนต์ตามทิศทางการไหลในแกนหลักได้ผ่าน justify-content เช่นจัดสิ่งของให้อยู่กลางด้วย justify-content: center
#container {  display: flex;  justify-content: center;  background: #37BC9B;  height: 200px;}.box {  width: 50px;  height: 50px;  line-height: 50px;   background: #434A54;  color: #F5F7FA;  border: 1px solid #CCD1D9;  text-align: center; }
เช่นเดียวกันกลุ่มของอีลีเมนต์ยังสามารถจัดตำแหน่งตามแกนรอง (cross axis) ได้ด้วยผ่าน align-items เช่นการจัดกลางตามแนวดิ่งด้วย align-items: center
#container {  display: flex;  justify-content: center;  align-items: center;  background: #37BC9B;  height: 200px;}
สำหรับแกนรองยังมี align-content และ align-self โดย align-self จะอนุญาตให้เราสามารถกำหนดตำแหน่งแยกตัวของแต่ละอีลีเมนต์ให้ผิดแผกไปจากชาวบ้านได้ เช่นให้กล่องหมายเลข 1 วางตำแหน่งตนให้อยู่ที่จุดเริ่มต้นของแกนรองผ่าน align-self: flex-start
#box1 {  align-self: flex-start;}
คำถามครับ แล้วถ้าเราอยากให้กล่องหมายเลข 1 อยู่ชิดมุมซ้ายบน หรืออีกนัยคือให้กล่องจัดตำแหน่งตามแกนหลักไปอยู่ที่จุดเริ่มต้นจะทำได้หรือไม่?
หลายคนอาจคิดว่าการจัดเดี่ยวตามแนวแกนรองนั้นเรามี align-self งั้นถ้าจัดตามแกนหลักก็ใช้ justify-self ซิ นั่นเป็นคำตอบที่ผิดครับ เพราะ justify-self เป็นมาตรฐานของ CSS Box Alignment Module
พลานุภาพของ margin กับ flexbox
เคล็ดการแก้ปัญหานี้อยู่ที่ Auto Margins เมื่อเราระบุ margin เป็น auto ในทิศทางใด พฤติกรรมสัตว์ป่าของมันจะเริ่มปรากฎด้วยการกลืนกินและครอบครองพื้นที่ว่างในทิศทางนั้น ๆ เช่นเราระบุ margin-left: auto จะทำให้เกิดการจองพื้นที่ด้านซ้ายไว้
สมมติเราต้องการสร้าง navbar ให้เมนูส่วนอื่นอยู่ชิดซ้ายเว้นปุ่มลอคอินที่ให้อยู่ชิดขวา เราสามารถใช้ auto margins แก้ปัญหานี้ได้ ดังนี้
<div id="container">  <div class="box" id="box1">Articles</div>  <div class="box" id="box2">Courses</div>  <div class="box" id="box3">Login</div></div>
ค่าเริ่มต้นอีลีเมนต์จะถูกจัดให้อยู่ที่จุดเริ่มต้น (flex-start) เราจึงผลักเฉพาะกล่องสุดท้ายไปไว้ขวาสุด
#container {  display: flex;  background: #37BC9B;  height: 200px;}.box {  width: 50px;  height: 50px;  padding: 0 10px;  line-height: 50px;   background: #434A54;  color: #F5F7FA;  border: 1px solid #CCD1D9;  text-align: center; }#box3 {  margin-left: auto;}
กลับมาที่ปัญหาเดิมของเรา หากเราต้องการให้กล่องหมายเลข 1 จากรูปด้านล่างนี้อยู่ชิดมุมซ้ายบน ด้วยพลานุภาพของ auto margins เราสามารถแก้ปัญหานี้ได้อย่างไร?
ง่ายมากครับ ตอนนี้แกนหลักของเราอีลีเมนต์อยู่ตรงกลาง เราอยากให้กล่องแรกไปชิดซ้าย เราต้องจองพื้นที่ด้านขวาของกล่องเอาไว้ จึงต้องใส่ margin-right: auto
#box1 {  align-self: flex-start;  margin-right: auto;}
Auto margins นั้นไม่จำเป็นต้องใช้กับแกนหลักเท่านั้น การนำมันมาใช้กับ flex items ก็เหมือนกับการใช้กับ block เหตุนี้ auto margins จึงใช้กับแกนรองได้เช่นกัน
ตอนต้นของบนความเราใช้ justify-content: center และ align-items: center เพื่อกำหนดให้อีลีเมนต์อยู่กลางจอ
หากเราต้องการให้อีลีเมนต์ต่าง ๆ อยู่กลางจอด้วยและกระจายตามแนวนอนด้วย เราไม่ต้องมานั่งใส่ justify-content และ align-items ให้วุ่นวาย เพียงใช้ margin: auto ชีวิตก็ดี๊ดีขึ้น
.box {  width: 50px;  height: 50px;  line-height: 50px;   background: #434A54;  color: #F5F7FA;  border: 1px solid #CCD1D9;  text-align: center;   margin: auto;}
flexbox และ absolute position
margin: auto ช่วยให้อีลีเมนต์จัดกลางจอ กรณีที่จำนวนอีลีเมนต์เป็นเลขคี่ อีลีเมนต์ตัวกลางจะอยู่หน้าจอพอดี
ทว่าการใช้ margin: auto ไม่การันตีเสมอไปว่าตัวกลางจะอยู่ตรงกลางเสมอ หากอีลีเมนต์ตัวอื่นขนาดไม่เท่ากันทุกอย่างก็พังพินาศ
นอกจาก auto margins แล้ว absolute position ก็เป็นอีกหนึ่งปัจจัยแห่งการเคลื่อนย้ายตำแหน่งของ flex items ได้ด้วย เราจึงสามารถใช้ position: absolute เพื่อเคลื่อนกล่องหมายเลข 2 ให้อยู่ตรงกลางหน้าจออย่างแท้จริง
#container {  display: flex;  align-items: center;  position: relative;  background: #37BC9B;  height: 200px;}.box {  width: 50px;  height: 50px;  line-height: 50px;   background: #434A54;  color: #F5F7FA;  border: 1px solid #CCD1D9;  text-align: center;   margin: auto;}#box1 {  width: 100px;}#box2 {  position: absolute;  left: 50%;  transform: translate(-50%, 0);}
รู้จัก space-evenly ใน CSS Box Alignment Module
เมื่อพูดถึงการจัดอีลีเมนต์ตามแนวนอน การจัดกลาง จัดชิดซ้ายหรือขวา อาจไม่ใช่คำตอบสุดท้าย บางครั้งเราอยากจัดตำแหน่งให้แต่ละกล่องมีช่องว่างเว้นไว้เท่า ๆ กัน เราจึงเลือก justify-content: space-around มาแก้ปัญหา
#container {  display: flex;  align-items: center;  justify-content: space-around;  background: #37BC9B;  height: 200px;}
space-around จะเพิ่มช่องว่างด้านซ้ายและขวาของแต่ละกล่องเท่า ๆ กัน หากช่องว่างด้านซ้ายของกล่องหมายเลข 1 มีขนาด 1 หน่วย ด้านซ้ายของมันก็จะมีขนาด 1 หน่วยเช่นกัน สำหรับกล่องหมายเลข 2 ก็เป็นเช่นเดียวกับกล่องหมายเลข 1
เมื่อพิจารณาตรงนี้ปัญหาจึงเกิดขึ้น ด้านขวาของกล่องแรกเพิ่มช่องว่าง 1 หน่วย แต่ด้านซ้ายของกล่องสองก็เพิ่มอีก 1 หน่วย ผลลัพธ์ที่ตาเห็นจึงกลายเป็นด้านชิดขอบจอมีขนาด 1 หน่วย แต่พื้นที่ว่างระหว่างกล่องกลับมีค่าเป็น 2 หน่วยแทน นี่ไม่ใช่การกระจายเท่ากันอย่างแท้จริง!
วิธีการแก้ปัญหานี้ง่ายมากด้วยการแสร้งทำเป็นมีกล่องโผล่ขึ้นหน้าและหลังอย่างละใบด้วย ::before และ ::after แล้วเปลี่ยนจาก space-around ที่เพิ่มช่องว่างด้านขอบเป็นการใช้ space-between ที่มีช่องว่างเพราะด้านที่ติดกันของกล่อง เพียงเท่านี้ก็เป็นอันเสร็จพิธี
#container {  display: flex;  align-items: center;  justify-content: space-between;  background: #37BC9B;  height: 200px;}#container::before {  content: ''}#container::after {  content: ''}
แม้วิธีนี้จะดูดิบเถื่อนไปหน่อย แต่มันก็ได้ผลใช่ไหมหละ! ข่าวดีก็คือ CSS Box Alignment Module มีมาตรฐานสำหรับการกระจายแบบเท่ากันเช่นที่ว่าผ่าน justify: space-evenly ส่วนข่าวร้ายหนะรึ มันยังใช้ไม่ได้ในทุกเบราเซอร์นั่นเอง โถคุณพระ
#container {  display: flex;  align-items: center;  justify-content: space-evenly;  background: #37BC9B;  height: 200px;}
สรุป
การใช้งาน flexbox นั้นยืดหยุ่นมากและไม่จำกัดเพียงแค่การจัดทิศทางตามแกนเท่านั้น เรายังสามารถจัดตำแหน่งของแต่ละ flex items ด้วยการใช้ auto margin และ absolute positioning ได้เช่นกัน
นอกเหนือจาก flexbox ที่เป็นการจัดตำแหน่งในทิศทางเดียวแล้ว CSS ยังมีการจัดอีลีเมนต์ในสองมิติด้วยนั่นคือมาตรฐานของ CSS Grid Layout เพื่อน ๆ ที่สนใจสามารถอ่านเพิ่มเติมได้จาก CSS Grid Layout คืออะไร? รู้จักมาตรฐานการออกแบบเลย์เอาท์ใน 2 มิติกันเถอะ!
เอกสารอ้างอิง
Center and bottom-align flex items. Retrieved Mar, 26, 2018, from https://stackoverflow.com/questions/36191516/center-and-bottom-align-flex-items
W3C CSS Flexible Box Layout Module Level 1. Retrieved Mar, 26, 2018, https://www.w3.org/TR/css-flexbox-1/#auto-margins
W3C Distributed Alignment: the stretch, space-between, space-around, and space-evenly keywords. Retrieved Mar, 26, 2018, https://www.w3.org/TR/css-flexbox-1/#auto-margins
Michael_B. (2017) Equal space between flex items. Retrieved Mar, 26, 2018, from https://stackoverflow.com/questions/45134400/equal-space-between-flex-items
Michael_B. (2015) Methods for Aligning Flex Items along the Main Axis. Retrieved Mar, 26, 2018, https://stackoverflow.com/questions/32551291/in-css-flexbox-why-are-there-no-justify-items-and-justify-self-properties/33856609

ขออภัย! คุณไม่ได้รับสิทธิ์ในการดำเนินการในส่วนนี้ กรุณาเลือกอย่างใดอย่างหนึ่ง ลงชื่อเข้าใช้ | สมัครสมาชิก

รายละเอียดเครดิต

ประวัติการแบน|Mobile|รูปแบบข้อความล้วน|www.Chayoo.in.th

GMT+8, 2020-7-11 18:20 , Processed in 0.045151 second(s), 14 queries , Gzip On.

Powered by Discuz! X3.4 R20180101, Rev.59

© 2001-2017 Comsenz Inc.

ตอบกระทู้ ขึ้นไปด้านบน ไปที่หน้ารายการกระทู้