CSS3 box-sizing: margin-box; ทำไมจะไม่ล่ะ?


139

ทำไมเราไม่ได้box-sizing: margin-box;? โดยปกติเมื่อเราใส่box-sizing: border-box;สไตล์ชีทของเราเราหมายถึงอดีต


ตัวอย่าง:

สมมติว่าฉันมีเลย์เอาต์หน้าคอลัมน์ 2 ทั้งสองคอลัมน์มีความกว้าง 50% แต่พวกมันดูน่าเกลียดเพราะไม่มีรางน้ำ (ช่องว่างตรงกลาง); ด้านล่างนี้คือ CSS:

.col2 {
    width: 50%;
    float: left;
}


ในการใช้รางน้ำคุณอาจคิดว่าเราสามารถกำหนดระยะห่างที่เหมาะสมในคอลัมน์แรกของ 2 คอลัมน์; บางสิ่งเช่นนี้

.col2:first-child {
    margin-right: 24px;
}

แต่สิ่งนี้จะทำให้คอลัมน์ที่สองตัดเข้าบรรทัดใหม่เนื่องจากสิ่งต่อไปนี้เป็นจริง:

50% + 50% + 24px > 100%

box-sizing: margin-box;จะแก้ปัญหานี้โดยรวมส่วนต่างในความกว้างที่คำนวณได้ขององค์ประกอบ ฉันจะพบว่ามีประโยชน์มากถ้าไม่ได้มีประโยชน์มากกว่าbox-sizing: border-box;นี้


30
"ทำไมเราไม่มีbox-sizing: margin-box;" เนื่องจากในขณะที่ระยะขอบในแนวนอนไม่ยุบข้อเสนอเช่นนี้จะรบกวนการยุบขอบแนวตั้งอย่างจริงจัง อย่างไรก็ตามหากคุณต้องการเสนอบางสิ่งสำหรับการสร้างมาตรฐาน Stack Overflow ไม่ใช่ที่ที่ถูกต้อง ลองรายการจดหมาย
BoltClock

16
ในบางสถานการณ์คุณสามารถหลีกเลี่ยงปัญหานี้ได้โดยใช้border: xxx solid transparent;เนื่องจากมีการรวมเส้นขอบไว้border-boxด้วย นี้จะทำลายสิ่งอื่น ๆ box-shadowแม้ว่าบางเช่น
นาธานออสมัน

28
เรากำลังปิดคำถามทั้งหมดเกี่ยวกับมาตรฐานว่า "ไม่สร้างสรรค์" หรือไม่? มันเป็นคำถามที่ยุติธรรมที่จะถามและมันก็มีคำตอบที่ตรงไปตรงมา: เราไม่มีbox-sizing: margin-boxเพราะมันไม่ได้ผลกับการยุบขอบ
thomasrutter

@thomasrutter: ไม่มีเหตุผลที่ดีกว่าในตอนที่ฉันปิดมันซึ่งมากกว่าหนึ่งปีที่ผ่านมา อย่างไรก็ตามตอนนี้ "ไม่สร้างสรรค์" ได้หายไปแล้ว (หมายถึงไม่เราไม่ได้ปิดกั้นสิ่งที่ไม่ใช่เชิงสร้างสรรค์อีกต่อไป) และตั้งแต่ "ฉันมีความคิดนี่คือวิธีการทำงาน สิ่งถูกลบออกเนื่องจากถูกปิดครั้งล่าสุดตอนนี้ดูเหมือนจริง ๆ แล้วเป็นประโยชน์ "ทำไม X ไม่สามารถทำงานได้" คำถาม. มันยังคงเป็นคำถามเก็งกำไรอย่างไม่น่าเชื่อ (เหตุผลของฉันข้างต้นไม่มีอะไรมากไปกว่าการเดาที่มีการศึกษา) แต่ฉันไม่ควรแสดงความคิดเห็นเพิ่มเติมในเรื่องนั้น
BoltClock

ทำไมไม่เพียงแค่มีการตัดภายใน / div ถ้าคุณต้องการระยะห่าง: codepen.io/chriscoyier/pen/eGcLw
ashley

คำตอบ:


55

คุณใช้width: calc(50% - 24px);cols ของคุณไม่ได้เหรอ? จากนั้นตั้งค่าระยะขอบของคุณ


5
มันขึ้นอยู่กับเบราว์เซอร์สูง น่าจะประมาณปี 2020 แล้วที่ ie15 จะให้การสนับสนุนและคุณจะได้รับอนุญาตให้ใช้งานของคุณได้เช่นกัน :-(
peterh - Reinstate Monica

1
ดูเหมือนว่าจะทำงานได้ไม่ดีนักใน Firefox ใช่ไหม (หรืออย่างอื่นที่ฉันทำไม่ได้)
Laurengineer

@ Morgan Feeney: ใช่ แต่การปรับขนาดกล่องไม่มีค่าที่เรียกว่า margin-box (ซึ่งเป็นจุดรวมของคำถามนี้) แม้ว่าค่าดังกล่าวจะถูกนำมาใช้ในตอนนี้คุณจะเสนอแพทช์ / โพลีฟิลลิ่ง / ปรับให้เป็นเบราว์เซอร์ที่มีอยู่ได้อย่างไร
BoltClock

ใช่ แต่ ... ตอบกลับโดยเฉพาะกับคำตอบที่แนะนำ calc () เป็นวิธีแก้ปัญหา
Morgan Feeney

ไม่แน่ใจว่าสิ่งนี้นำไปใช้กับตัวอย่างที่เฉพาะเจาะจง แต่สิ่งสำคัญที่เป็นลบต่อการใช้ calc () ในสถานการณ์ของเรา (ณ ที่ FF 53.0.3) คือพฤติกรรมของมันไม่คล้ายกับความกว้าง: X%; จากสิ่งที่เราเห็น "แคลอรี่" ถูกสร้างขึ้นในช่วงเวลาของการเรนเดอร์เริ่มต้นจนถึงสแตติก Xpx ซึ่งหมายความว่าไม่เหมือนกับความกว้าง: X% คอลัมน์ calc'ed จะไม่ปรับขนาดโดยอัตโนมัติด้วยการปรับขนาดคอนเทนเนอร์
Pancho

16

box-sizing: margin-boxผมคิดว่าเราอาจมี รูปแบบกล่อง css แสดงให้เห็นอย่างชัดเจนว่าตำแหน่งของระยะขอบของเฟรมคืออะไร

มีปัญหาเล็กน้อย - ตัวอย่างเช่นกล่องมาร์จิ้นสามารถทับซ้อนกัน - แต่ก็ไม่ยากที่จะแก้ไข

ฉันคิดว่าสถานการณ์เหมือนกันอย่างที่เราเห็นด้วยoverflow-x& การoverflow-yรวมกันโดยตำแหน่ง divs ที่ไม่แน่นอนในตารางเซลล์ด้วยการรวมกันของ min | max-width | height กับขนาดของกล่องและอื่น ๆ

มีคุณสมบัติเป็นคุณสมบัติที่เรียบง่ายจริงๆที่นักพัฒนาเบราว์เซอร์ไม่พัฒนา

IMHO box-sizing: margin-boxเป็นคุณสมบัติที่มีประโยชน์มาก คุณสมบัติที่มีประโยชน์อีกอย่างคือbox-sizing: padding-boxมันมีอยู่อย่างน้อยในมาตรฐาน แต่ไม่ได้นำไปใช้กับเบราว์เซอร์หลัก ๆ ไม่ได้อยู่ในโครเมียมใหม่ล่าสุด!


หมายเหตุ: ความคิดเห็นของ @Oriol: Firefox ใช้การปรับขนาดของกล่อง: ช่องว่างภายใน แต่คนอื่นไม่ได้และมันถูกลบออกจากสเป็ค Firefox จะลบออกในเวอร์ชัน 50 เศร้า


2
Firefox box-sizing: padding-boxไม่ดำเนินการ แต่คนอื่นไม่ได้และมันถูกลบออกจากสเป็ค Firefox จะลบออกในเวอร์ชัน 50 เศร้า
Oriol

6

คนที่อยู่ด้านบนถามถึงการเพิ่มระยะขอบให้กับความกว้างโดยรวมรวมถึงการขยายและขอบ border-boxสิ่งที่เป็นขอบถูกนำไปใช้นอกกรอบและช่องว่างภายในและชายแดนไม่ได้เมื่อใช้

ฉันพยายามที่จะบรรลุborder-marginความคิด สิ่งที่ฉันได้พบคือถ้าใช้มาร์จิ้นคุณสามารถเพิ่มคลาสของ.lastรายการสุดท้าย (ด้วยมาร์จิ้นแล้วใช้ระยะขอบเป็นศูนย์หรือใช้:last-child/:last-of-type) หรือเพิ่มระยะขอบที่เท่ากันตลอดทาง (คล้ายกับเวอร์ชัน padding ด้านบน)

ดูตัวอย่างได้ที่นี่: http://codepen.io/mofeenster/pen/Anidc

border-boxคำนวณความกว้างขององค์ประกอบ + การเติมเต็ม + ขอบของมันเป็นความกว้างทั้งหมด ดังนั้นถ้าคุณมี 2 วิdivซึ่งกว้าง 50% พวกมันจะอยู่ติดกัน ถ้าคุณเพิ่มช่องว่างให้กับพวกเขาแล้วคุณจะมีท่อของ8px 16pxรวมเข้ากับองค์ประกอบห่อซึ่งมีช่องว่างภายใน8pxคุณจะมีกริดที่จัดวางอย่างสวยงามพร้อมรางระบายน้ำที่เท่ากันตลอดทาง

ดูตัวอย่างนี้ได้ที่นี่: http://codepen.io/mofeenster/pen/vGgje

วิธีหลังเป็นวิธีที่ฉันโปรดปราน


4

ฉันแน่ใจว่าทั้งหมดนี้ชัดเจน แต่ฉันจะพิมพ์ออกมาเพราะ ... ดีฉันต้องการการออกกำลังกาย ผลลัพธ์ต่อไปนี้จะไม่มีประสิทธิภาพเท่ากับbox-sizing: margin-box;:

.col2 {
    width: 45%;
    height: 90%;
    margin: 5% 2.5%;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    float: left;
}

http://jsfiddle.net/Fg3hg/

box-sizingใช้ในการควบคุมว่าจุดใดที่ช่องว่างภายในและขอบจะถูกประเมินขนาดโดยรวมขององค์ประกอบ ดังนั้นแม้ว่าจะไม่เพียว ๆ ที่จะรวมpxระยะขอบที่มี%ความกว้าง (ตามปกติจะเป็นทุกกรณี) แต่ก็ง่ายกว่าที่จะคำนวณจำนวนเปอร์เซ็นต์สัมพัทธ์ที่ควรจะเป็นเพราะคุณไม่จำเป็นต้องรวมช่องว่างภายในและความกว้างที่กำหนดไว้


9
กรณีการใช้งานบางอย่างเช่นกล่องระยะขอบคือการเปิดใช้งานการผสมความกว้างร้อยละที่มีระยะขอบพิกเซล หากคุณต้องการกล่อง 50% สองกล่องที่มีระยะห่าง 1px ระหว่างสองกล่องสิ่งนี้ไม่สามารถทำได้ด้วยอัตรากำไรขั้นต้นร้อยละ 1 ที่คล้ายคลึงกันขนาดหน้าจอขนาดเล็กบางอย่างจะปัดเศษลง 1% เป็น 0 พิกเซลและในทันทีคุณไม่มีระยะขอบ สิ่งที่เราต้องการจริงๆคือการสนับสนุนเบราว์เซอร์เพิ่มเติมสำหรับ calc () ตามที่ @Slouch แสดงหรือรูปแบบ flexbox

1
ถ้านั่นคือการดูแลคอนเทนเนอร์หลักจะน้อยกว่า 100px และฉันหวังว่าองค์ประกอบการออกแบบบางอย่างจะถูกนำมาคิดใหม่ ณ จุดนั้น มีสิ่งอื่น ๆ ที่คุณสามารถทำกับองค์ประกอบที่ซ้อนกันและไม่ชอบ แต่ใช่มีการคำนวณตัวแปรจะเป็นยาเสพติดสวย หากคุณเป็นคนที่ชอบเขหรือน้อยกว่าฉันคิดว่าพวกเขาทำสิ่งนี้มากมาย ฉันเล่นไปกับพวกเขาแล้ว แต่ยังไม่มีเจได
Plummer

2
สิ่งที่คุณแนะนำคือการแก้ไข มันไม่ใช่วิธีที่เหมาะในการเขียน CSS เมื่อคุณทำงานกับเค้าโครงที่ซับซ้อน คุณสมมติว่าผู้ออกแบบหรือผู้แต่งต้องการใช้เปอร์เซ็นต์ในการออกแบบ แม้ว่าคุณจะใช้ฟังก์ชั่น calc () เพื่อหาระยะห่างโดยใช้ระยะขอบของพิกเซลมันก็ยัง จำกัด นักออกแบบเพราะพวกเขาจะต้องกำหนดล่วงหน้าว่าการ guttering นั้นคืออะไรแทนที่จะปล่อยให้มันถูกเขียนทับโดยใช้ CSS
limitlessloop

ฉันไม่เข้าใจประเด็นของคุณ ปัญหาในมือคือการรวม px และ% ทำให้เกิดการขึ้นบรรทัดใหม่เนื่องจากส่วนต่างไม่รวมอยู่ในการคำนวณขนาด ระยะขอบไม่รวมอยู่ในขนาดขององค์ประกอบ แต่เป็นพื้นที่ที่คุณต้องการให้ปรากฏรอบองค์ประกอบ นอกจากนี้จะmargin-boxจัดการการคำนวณระยะขอบหลายมิติได้อย่างไร @mediaเบรกพอยต์max-widthและmin-widthทำงานได้ดี ฉันเดาว่าmargin-boxอาจลดการขยายตัวลงบ้าง แต่ฉันก็ได้รับเหตุผลว่าทำไมอาจมีการพิจารณาซ้ำซ้อน
Plummer

ทำไมไม่มีใครพูดถึงว่าขอบนี้เปอร์เซ็นต์ VALUE เป็นเปอร์เซ็นต์ของความกว้างด้วยเหตุผลบางอย่าง ... ไม่สำคัญหรือสูง ใช้ความกว้างของพาเรนต์ Bizzare ไหนที่จะพูดน้อย .. ดังนั้นโค้ดด้านบนไม่สามารถใช้งานได้และใช้งานไม่ได้ นอกเสียจากคุณจะทำให้ความสูงและความกว้างเท่ากัน
มูฮัมหมัดอูเมอ

4

นี่เป็นเพราะแอตทริบิวต์การปรับขนาดกล่องอ้างถึงขนาดขององค์ประกอบหลังจากคำนวณค่าเฉพาะมิติที่กำหนด (การขยาย, ขอบ) "box-sizing: border-box" ตั้งค่าความสูง / ความกว้างขององค์ประกอบและคำนึงถึงการขยายเช่นเดียวกับความกว้างของเส้นขอบ ขอบเขตขององค์ประกอบขององค์ประกอบนั้นมากกว่าองค์ประกอบของตัวเองซึ่งหมายความว่ามันจะปรับเปลี่ยนการไหลของหน้าและองค์ประกอบโดยรอบดังนั้นการเปลี่ยนแปลงโดยตรงกับองค์ประกอบที่เหมาะสมภายในองค์ประกอบของผู้ปกครองเมื่อเทียบกับองค์ประกอบพี่น้อง ในที่สุดค่าแอตทริบิวต์ "กล่องกำไร" จะทำให้เกิดปัญหาที่สำคัญและเป็นหลักเช่นเดียวกับการตั้งค่าองค์ประกอบความสูง / ความกว้างโดยตรง


1
คำขอโทษของฉัน แต่ฉันไม่เข้าใจว่าการรวมช่องว่างภายในขอบและระยะขอบในการคำนวณพิเศษด้วย "กล่องขอบ" จะแตกต่างจากแนวคิดรวมถึงช่องว่างภายในและขอบผ่าน "กล่องเส้นขอบ" แน่นอนมันเป็นเพียงการเปลี่ยนแปลงในชุดรูปแบบเดียวกันหรือไม่
Pancho

1

ในCodropsมีบทความที่ดีสองเรื่องเกี่ยวกับผลกระทบของระยะขอบและแถวบังคับให้ล้น พวกเขาแนะนำให้ใช้หน่วย rem หรือ em ด้วยขนาดตัวอักษร css การตั้งค่าปกติเป็น 100% สำหรับเบราว์เซอร์ทั้งหมดจากนั้นเมื่อคุณตั้งค่าความกว้างและระยะขอบมันง่ายต่อการติดตามผลกระทบต่อความกว้างของแถวโดยการจดบันทึกในข้อคิดเห็นสำหรับ ความกว้างทั้งหมด การแปลง 16px เป็น 1 em เป็นวิธีการคำนวณจำนวนการดูเป้าหมายทั้งหมดด้วย witdh

ทำงานอย่างนั้นสำหรับขั้นตอนการพัฒนาอย่างน้อยจากนั้นถ้าคุณต้องการเทมเพลต 'ตอบสนอง' คุณสามารถแปลงความกว้างเป็น% รวมถึงความกว้างของระยะขอบ

อีกวิธีที่ง่ายกว่าและบ่อยกว่าที่พวกเขาแนะนำให้จัดการกับท่อระบายน้ำคือการใช้หลอกหลังจากและcontent: '';ในแต่ละคอลัมน์ของคุณที่ฉันพบว่าทำงานได้ดีจริงๆ หากคุณตั้งคลาส div ที่เป็นคอลัมน์สุดท้ายที่กำหนดไว้เช่นสิ้นสุดคุณสามารถกำหนดเป้าหมายคลาสนั้นเพื่อไม่ให้มีการหลอกหลังจากหรือเพื่อให้มีวงกว้างขึ้น ที่เหมาะกับรูปแบบของคุณมากที่สุด

โบนัสเพิ่มของการใช้วิธีการหลอกนี้ก็ให้เป้าหมายสำหรับเงาที่ให้เอฟเฟกต์ 3 มิติและความลึกที่มากขึ้นสำหรับภาพแบนบนจออ่านของผู้อ่านเช่นกัน ฉันกำลังทดลองกับเอฟเฟกต์นี้ในขณะนี้โดยการปรับเอฟเฟกต์ที่ใช้กับปุ่ม 'ปรับแต่ง' การไล่ระดับสีและดัชนีซี


1

ขนาดขององค์ประกอบระดับบล็อกไม่ถูกแทนที่ในการไหลปกติจะต้องตอบสนอง

ระยะขอบซ้าย + ความกว้างขอบด้านซ้าย + ช่องว่างภายในซ้าย + ความกว้าง + ช่องว่างด้านขวา + ความกว้างขอบด้านขวา + ระยะขอบขวา = ความกว้างของบล็อกที่มี

เมื่อ จำกัด มากเกินไปเบราว์เซอร์จะต้องปรับระยะขอบซ้ายหรือขวา ฉันคิดว่านั่นหมายถึงความกว้างของกล่องมาร์จิ้นจะต้องเท่ากับความกว้างของบล็อกที่มี (เช่น 100%)

สำหรับกรณีของคุณชายแดนโปร่งใสด้วยbox-sizing: border-boxการทำงานสามารถมากเช่นอัตรากำไรขั้นต้น


1

บางทีตั้งค่าความทึบเป็น 0% โดยใช้ RGBA และใช้เส้นขอบเป็นระยะขอบ


ฟังดูเหมือนแฮ็ค แต่จะทำงาน
Morgan Feeney

สิ่งนี้สามารถพิสูจน์ได้ว่ามีประโยชน์หากคุณไม่ต้องการใช้เครื่องห่อเพื่อให้งานสำเร็จ
limitlessloop

... เว้นแต่คุณจะต้องการชายแดนจริงๆ
FrancescoMM

@ FrancescoMM - "noisy" นิดหน่อย แต่คุณสามารถสร้างกล่องที่มีเส้นขอบโปร่งใส "margin-width" (และไม่ต้องเว้นระยะห่างแน่นอน) และภายในกล่องนั้นที่มีเส้นขอบที่มองเห็นได้ของความกว้างที่คุณต้องการแสดงอีกครั้ง ระยะขอบ)
Pancho

1
ฉันไม่สามารถทำตามความคิดเช่นนี้ได้ มีอะไรที่เป็นธรรมชาติมากกว่าที่บอกว่าฉันต้องการกล่องสอง1pxชิ้นแยกกันแต่ละอันใช้50%พื้นที่ว่างหรือไม่? นั่นคือสิ่งที่margin-boxจะทำ หรือลืมกล่องขอบและคิดเกี่ยวกับพื้นที่ว่าง ไม่ใช่คอนเทนเนอร์หลัก 50% แต่เหลือ 50% ของสิ่งที่เหลือ ไม่ "เผา" ไม่มี "อัตรากำไร 5%" ไม่มีระเบียบดังกล่าว ...
35717

0

มีสถานการณ์ที่น่าสนใจเมื่อใช้ขนาดกล่องภายในเนื้อหาของร่างกาย

ไม่มีเนื้อหาใด ๆ ที่ไม่มีขอบกล่องให้ค่าใด ๆ กับการนับ% ขอบซ้ายขวาของ Algoritms นับสองกล่องนี้

  .body{
    box-sizing: border-box;
    margin:0 3%;
  }

Firefox เวอร์ชันก่อน 57 ยังรองรับค่า padding-box สำหรับการปรับขนาดกล่องแม้ว่าค่านี้จะถูกลบออกจากข้อมูลจำเพาะและเบราว์เซอร์เวอร์ชันที่ใหม่กว่า

ดังนั้นกล่องเงินทุนแม้จะไม่ได้วางแผน ...

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.