เลย์เอาต์ Flex / Grid ไม่ทำงานบนปุ่มหรือองค์ประกอบ fieldset


91

ฉันพยายามที่จะศูนย์องค์ประกอบภายในของ<button>-tag กับ justify-content: centerflexbox แต่ Safari ไม่ได้อยู่ตรงกลาง ฉันสามารถใช้สไตล์เดียวกันกับแท็กอื่น ๆ และทำงานได้ตามที่ต้องการ (ดู<p>แท็ก -tag) มีเพียงปุ่มเท่านั้นที่จัดชิดซ้าย

ลองใช้ Firefox หรือ Chrome แล้วคุณจะเห็นความแตกต่าง

มีลักษณะตัวแทนผู้ใช้ที่ฉันต้องเขียนทับหรือไม่? หรือวิธีแก้ปัญหาอื่น ๆ สำหรับปัญหานี้?

div {
  display: flex;
  flex-direction: column;
  width: 100%;
}
button, p {
  display: flex;
  flex-direction: row;
  justify-content: center;
}
<div>
  <button>
    <span>Test</span>
    <span>Test</span>
  </button>
  <p>
    <span>Test</span>
    <span>Test</span>
  </p>
</div>

และ jsfiddle: http://jsfiddle.net/z3sfwtn2/2/


คำตอบ:


134

ปัญหา

ในเบราว์เซอร์บาง<button>องค์ประกอบไม่ยอมรับการเปลี่ยนแปลงของdisplayมูลค่าเกินกว่าการสลับระหว่างและblock inline-blockซึ่งหมายความว่า<button>องค์ประกอบไม่สามารถเป็นคอนเทนเนอร์แบบยืดหยุ่นหรือกริดหรือ a <table>ได้

นอกเหนือไปจาก<button>องค์ประกอบที่คุณอาจพบข้อ จำกัด นี้การนำไปใช้<fieldset>และ<legend>องค์ประกอบรวม

ดูรายงานข้อบกพร่องด้านล่างสำหรับรายละเอียดเพิ่มเติม

หมายเหตุ: แม้ว่าจะไม่สามารถเป็นคอนเทนเนอร์แบบยืดหยุ่นได้ แต่<button>องค์ประกอบสามารถเป็นรายการที่ยืดหยุ่นได้


การแก้ไขปัญหา

มีวิธีแก้ปัญหาข้ามเบราว์เซอร์ที่ง่ายและสะดวกสำหรับปัญหานี้:

ห่อเนื้อหาของbuttonใน a spanและทำspanภาชนะดิ้น

HTML ที่ปรับแล้ว (รวมbuttonเนื้อหาใน a span)

<div>
    <button>
        <span><!-- using a div also works but is not valid HTML -->
            <span>Test</span>
            <span>Test</span>
        </span>
    </button>
    <p>
        <span>Test</span>
        <span>Test</span>
    </p>
</div>

CSS ที่ปรับแล้ว (กำหนดเป้าหมายspan)

button > span, p {
    display: flex;
    flex-direction: row;
    justify-content: center;
}

ปรับปรุงการสาธิต


การอ้างอิง / รายงานข้อบกพร่อง

Flexbox บน<button>บล็อกจะระบุเนื้อหา แต่ไม่ได้สร้างบริบทการจัดรูปแบบแบบยืดหยุ่น

ผู้ใช้ (Oriol Brufau): ลูก ๆ ของพวกเขา<button>ถูกปิดกั้นตามที่กำหนดข้อกำหนดของ flexbox อย่างไรก็ตาม<button>ดูเหมือนว่าจะสร้างบริบทการจัดรูปแบบบล็อกแทนที่จะเป็นแบบยืดหยุ่น

ผู้ใช้ (Daniel Holbert): นั่นคือสิ่งที่ข้อกำหนด HTML ต้องการอย่างมีประสิทธิภาพ องค์ประกอบคอนเทนเนอร์ HTML หลายรายการเป็น "พิเศษ" และไม่สนใจdisplayค่าCSS ใน Gecko [นอกเหนือจากว่าเป็นระดับอินไลน์กับระดับบล็อก] <button>เป็นหนึ่งในนี้ <fieldset>& <legend>เช่นกัน.

เพิ่มการสนับสนุนสำหรับการแสดงผล: flex / grid และ columnet layout ภายใน<button>องค์ประกอบ

ผู้ใช้ (Daniel Holbert):

<button>ไม่สามารถใช้งานได้ (โดยเบราว์เซอร์) ใน CSS ที่บริสุทธิ์ดังนั้นพวกเขาจึงเป็นกล่องดำเล็กน้อยจากมุมมองของ CSS ซึ่งหมายความว่าพวกเขาไม่จำเป็นต้องตอบสนองในลักษณะเดียวกับที่<div> ต้องการ

สิ่งนี้ไม่เฉพาะเจาะจงสำหรับ flexbox - เช่นเราจะไม่แสดงแถบเลื่อนหากคุณใส่overflow:scrollปุ่มและเราจะไม่แสดงเป็นตารางหากคุณวางdisplay:tableไว้

<button>ก้าวกลับยิ่งขึ้นนี้ไม่ได้เฉพาะเจาะจงกับ พิจารณา<fieldset>และ<table>ที่ยังมีพฤติกรรมการแสดงผลพิเศษ

และองค์ประกอบ HTML แบบเก่า ๆ เช่น<button>และ<table>และ<fieldset>ไม่สนับสนุนdisplayค่าที่กำหนดเองนอกจากเพื่อวัตถุประสงค์ในการตอบคำถามระดับสูงของ "is this element block-level or inline-level" สำหรับการส่งต่อเนื้อหาอื่น ๆ รอบ ๆ องค์ประกอบ .

ดูเพิ่มเติมที่:


3
ฉันเข้าใจว่าทำไมมันถึงใช้ไม่ได้<button>แต่ทำไมบนโลกนี้ถึงใช้ไม่ได้<fieldset>? องค์ประกอบนั้นไม่ควรถือเป็นองค์ประกอบระดับบล็อกปกติที่ใช้ได้กับคอนเทนเนอร์แบบยืดหยุ่นหรือไม่
fritzmg

3
@fritzmg. เห็นด้วย กฎนี้น่าจะมีอยู่ก่อนเทคโนโลยี CSS3 เช่น Flex และ Grid และควรได้รับการประเมินอีกครั้ง
Michael Benjamin

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

1
@Michael_B พิจารณาเพิ่มการอ้างอิงไปยังข้อความจริงที่คุณทำการยืนยัน ไม่จำเป็นต้องตอบกลับความคิดเห็นของฉัน - ถ้าคุณเพิ่มลงในข้อความที่คุณยืนยันฉันจะโหวตให้คุณ
mikemaccana

2
A divไม่สามารถเป็นลูกของ a ได้buttonเพราะถ้าคุณคิดว่ามันเป็น HTML ของโรงเรียนเก่าองค์ประกอบระดับบล็อกจะไม่สามารถเป็นลูกขององค์ประกอบแบบอินไลน์ได้ แต่วันนี้กับ HTML5, คำตอบที่ถูกต้องในทางเทคนิคคือว่าองค์ประกอบสามารถยอมรับได้เฉพาะสิงห์เนื้อหา A แสดงถึงเนื้อหาที่เป็นวลีแต่ไม่ได้ หมายถึงเนื้อหาการไหล รายละเอียดเพิ่มเติมbuttonspandivdiv
Michael Benjamin


1

เริ่มต้น Chrome 83 buttonตอนนี้ใช้งานได้inline-grid/grid/inline-flex/flexแล้วคุณสามารถดูเพิ่มเติมเกี่ยวกับคุณลักษณะใหม่นี้ได้ที่นี่

นี่คือตัวอย่าง (สำหรับผู้ที่ใช้ Chrome 83 ขึ้นไป)

button {
  display: inline-flex;
  height: 2rem;
  align-items: flex-end;
  width: 4rem;
  -webkit-appearance: none;
  justify-content: flex-end;
}
<!-- 

The align-items keyword should fail in Chrome 81 or earlier, but work in Chrome 83 or later. To see the error, the button needs styles that make it more of an extrinsic container. In other words, it needs a height or width set. 
 
-->
<button>Hi</button>
<input type="button" value="Hi">

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