ด้านล่างนี้คือห้าตัวเลือกในการบรรลุเลย์เอาต์นี้:
- ตำแหน่ง CSS
- Flexbox พร้อมองค์ประกอบ DOM ที่มองไม่เห็น
- Flexbox พร้อมองค์ประกอบหลอกที่มองไม่เห็น
- Flexbox กับ
flex: 1
- เค้าโครงตาราง CSS
วิธีที่ 1: คุณสมบัติการกำหนดตำแหน่ง CSS
นำposition: relative
ไปใช้กับภาชนะดิ้น
นำposition: absolute
ไปใช้กับรายการ D.
ตอนนี้รายการนี้อยู่ในตำแหน่งที่แน่นอนภายในคอนเทนเนอร์แบบยืดหยุ่น
โดยเฉพาะอย่างยิ่งรายการ D ถูกลบออกจากการไหลของเอกสาร แต่การเข้าพักภายในขอบเขตของบรรพบุรุษในตำแหน่งที่ใกล้ที่สุด
ใช้คุณสมบัติออฟเซ็ต CSS top
และright
เพื่อย้ายองค์ประกอบนี้ไปยังตำแหน่ง
li:last-child {
position: absolute;
top: 0;
right: 0;
background: #ddd;
}
ul {
position: relative;
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p {
text-align: center;
margin-top: 0;
}
span {
background-color: aqua;
}
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
ข้อแม้อย่างหนึ่งของวิธีนี้คือเบราว์เซอร์บางตัวอาจไม่สามารถลบรายการดิ้นที่อยู่ในตำแหน่งที่แน่นอนออกจากโฟลว์ปกติ สิ่งนี้จะเปลี่ยนการจัดแนวด้วยวิธีที่ไม่ได้มาตรฐานและไม่คาดคิด รายละเอียดเพิ่มเติม: รายการ flex ที่อยู่ในตำแหน่งที่แน่นอนจะไม่ถูกลบออกจากโฟลว์ปกติใน IE11
วิธีที่ # 2: Flex Auto Margins & Invisible Flex Item (องค์ประกอบ DOM)
ด้วยการรวมกันของauto
ระยะขอบและรายการเฟล็กซ์ที่มองไม่เห็นใหม่จะทำให้เลย์เอาต์ได้
รายการดิ้นใหม่จะเหมือนกับรายการ D และวางไว้ที่ปลายด้านตรงข้าม (ขอบด้านซ้าย)
โดยเฉพาะอย่างยิ่งเนื่องจากการจัดตำแหน่งแบบยืดหยุ่นขึ้นอยู่กับการกระจายของพื้นที่ว่างรายการใหม่จึงเป็นตัวถ่วงดุลที่จำเป็นเพื่อให้กล่องกลางทั้งสามอยู่ตรงกลางในแนวนอน รายการใหม่ต้องมีความกว้างเท่ากับรายการ D ที่มีอยู่มิฉะนั้นกล่องตรงกลางจะไม่อยู่ตรงกลางอย่างแน่นอน
visibility: hidden
รายการใหม่จะถูกลบออกจากมุมมองที่มี
ในระยะสั้น:
- สร้าง
D
องค์ประกอบที่ซ้ำกัน
- วางไว้ที่จุดเริ่มต้นของรายการ
- ใช้ดิ้น
auto
อัตรากำไรขั้นต้นที่จะให้A
, B
และC
เป็นศูนย์กลางที่มีทั้งD
องค์ประกอบสร้างความสมดุลเท่ากันจากปลายทั้งสอง
- นำ
visibility: hidden
ไปใช้กับรายการที่ซ้ำกันD
li:first-child {
margin-right: auto;
visibility: hidden;
}
li:last-child {
margin-left: auto;
background: #ddd;
}
ul {
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
<ul>
<li>D</li>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
วิธีที่ # 3: Flex Auto Margins & Invisible Flex Item (องค์ประกอบหลอก)
วิธีนี้คล้ายกับ # 2 ยกเว้นว่าจะสะอาดกว่าในเชิงความหมายและD
ต้องทราบความกว้าง
- สร้างองค์ประกอบหลอกที่มีความกว้างเท่ากับ
D
.
- วางไว้ที่จุดเริ่มต้นของภาชนะด้วย
::before
.
- ใช้ดิ้น
auto
อัตรากำไรขั้นต้นที่จะให้A
, B
และC
ตรงกลางพอดีกับหลอกและD
องค์ประกอบของการสร้างความสมดุลเท่ากันจากปลายทั้งสอง
ul::before {
content:"D";
margin: 1px auto 1px 1px;
visibility: hidden;
padding: 5px;
background: #ddd;
}
li:last-child {
margin-left: auto;
background: #ddd;
}
ul {
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
วิธีที่ # 4: เพิ่มflex: 1
รายการด้านซ้ายและขวา
เริ่มต้นด้วยวิธี # 2 หรือที่ 3 flex: 1
ข้างต้นแทนที่จะกังวลเกี่ยวกับความกว้างเท่ากันด้านซ้ายและขวาที่รายการเพื่อรักษาสมดุลเท่ากันเพียงแค่ให้แต่ละคน สิ่งนี้จะบังคับให้ทั้งคู่ใช้พื้นที่ว่างดังนั้นจึงทำให้รายการตรงกลางอยู่ตรงกลาง
จากนั้นคุณสามารถเพิ่มลงdisplay: flex
ในแต่ละรายการเพื่อจัดแนวเนื้อหาได้
หมายเหตุ เกี่ยวกับการใช้วิธีนี้กับmin-height
:ปัจจุบันอยู่ใน Chrome, Firefox, Edge และเบราว์เซอร์อื่น ๆ กฎชวเลขflex: 1
แบ่งออกเป็น:
flex-grow: 1
flex-shrink: 1
flex-basis: 0%
ที่หน่วยร้อยละ (%)ในflex-basis
สาเหตุวิธีนี้ในการหยุดพักเมื่อmin-height
ถูกนำมาใช้บนบรรจุภัณฑ์ เนื่องจากตามกฎทั่วไปเปอร์เซ็นต์ความสูงของเด็กต้องการการheight
ตั้งค่าคุณสมบัติที่ชัดเจนในพาเรนต์
นี่เป็นกฎ CSS แบบเก่าย้อนหลังไปถึงปี 1998 ( CSS ระดับ 2 ) ซึ่งยังคงมีผลในเบราว์เซอร์จำนวนมากในระดับหนึ่ง สำหรับรายละเอียดทั้งหมดดูได้ที่นี่และที่นี่
นี่คือภาพประกอบของปัญหาที่โพสต์ในความคิดเห็นโดยuser2651804 :
#flex-container {
display: flex;
flex-direction: column;
background: teal;
width: 150px;
min-height: 80vh;
justify-content: space-between;
}
#flex-container>div {
background: orange;
margin: 5px;
}
#flex-container>div:first-child {
flex: 1;
}
#flex-container::after {
content: "";
flex: 1;
}
<div id="flex-container">
<div>very long annoying text that will add on top of the height of its parent</div>
<div>center</div>
</div>
วิธีแก้คืออย่าใช้หน่วยเปอร์เซ็นต์ ลองpx
หรือไม่ทำอะไรเลย ( ซึ่งเป็นสิ่งที่สเป็คแนะนำจริง ๆแม้ว่าอย่างน้อยเบราว์เซอร์หลักบางตัวจะเพิ่มหน่วยเปอร์เซ็นต์ไม่ว่าด้วยเหตุผลใดก็ตาม)
#flex-container {
display: flex;
flex-direction: column;
background: teal;
width: 150px;
min-height: 80vh;
justify-content: space-between;
}
#flex-container > div {
background: orange;
margin: 5px;
}
#flex-container > div:first-child {
flex: 1;
flex-basis: 0;
}
#flex-container::after {
content: "";
flex: 1;
flex-basis: 0;
}
<div id="flex-container">
<div>very long annoying text that will add on top of the height of its parent</div>
<div>center</div>
</div>
วิธีที่ # 5: CSS Grid Layout
นี่อาจเป็นวิธีการที่สะอาดและมีประสิทธิภาพมากที่สุด ไม่จำเป็นต้องมีการวางตำแหน่งองค์ประกอบปลอมหรือแฮ็กเกอร์อื่น ๆ
เพียงสร้างตารางที่มีหลายคอลัมน์ จากนั้นวางตำแหน่งรายการของคุณในคอลัมน์กลางและท้าย โดยทั่วไปเพียงปล่อยคอลัมน์แรกว่างไว้
ul {
display: grid;
grid-template-columns: 1fr repeat(3, auto) 1fr;
grid-column-gap: 5px;
justify-items: center;
}
li:nth-child(1) { grid-column-start: 2; }
li:nth-child(4) { margin-left: auto; }
ul { padding: 0; margin: 0; list-style: none; }
li { padding: 5px; background: #aaa; }
p { text-align: center; }
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>| true center |</span></p>