อินพุตพร้อมจอแสดงผล: บล็อกไม่ใช่บล็อกเพราะเหตุใด


153

ทำไมการdisplay:block;width:auto;ป้อนข้อความของฉันไม่ทำงานเหมือน div และเติมความกว้างของคอนเทนเนอร์

ฉันรู้สึกว่า div เป็นเพียงองค์ประกอบของบล็อกที่มีความกว้างอัตโนมัติ ในรหัสต่อไปนี้ div และอินพุทไม่ควรมีขนาดเท่ากัน?

ฉันจะรับอินพุตเพื่อเติมความกว้างได้อย่างไร ความกว้าง 100% จะไม่ทำงานเนื่องจากอินพุตมีช่องว่างภายในและเส้นขอบ (ทำให้เกิดความกว้างสุดท้ายของ 1 พิกเซล + 5 พิกเซล + 100% + 5 พิกเซล + 1 พิกเซล) ความกว้างคงที่ไม่ใช่ตัวเลือกและฉันกำลังมองหาบางอย่างที่ยืดหยุ่นกว่า

ฉันต้องการคำตอบโดยตรงกับวิธีแก้ปัญหาโดยตรง ดูเหมือนว่าจะเป็นเรื่องแปลก ๆ และเข้าใจว่ามันอาจจะมีประโยชน์ในภายหลัง

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <title>width:auto</title>

        <style>
        div, input {
            border: 1px solid red;
            height: 5px;
            padding: 5px;
        }
        input, form {
            display: block;
            width: auto;
        }
        </style>
    </head>

    <body>
        <div></div>
        <form>
            <input type="text" name="foo" />
        </form>
    </body>
</html>

ฉันควรชี้ให้เห็นว่าฉันสามารถทำเช่นนี้กับการแก้ปัญหาเสื้อคลุม นอกเหนือจากการคาดคั้นกับความหมายของหน้าและความสัมพันธ์ตัวเลือก CSS ฉันพยายามที่จะเข้าใจลักษณะของปัญหาและไม่ว่าจะสามารถเอาชนะได้โดยการเปลี่ยนลักษณะของการป้อนข้อมูลตัวเอง

โอเคนี่มันแปลกจริง ๆ ! ฉันได้พบว่าการแก้ปัญหาก็คือการเพิ่มการป้อนข้อมูลที่มีmax-width:100% width:100%;padding:5px;อย่างไรก็ตามสิ่งนี้ทำให้เกิดคำถามมากขึ้น (ซึ่งฉันจะถามในคำถามที่แยกต่างหาก) แต่ดูเหมือนว่าความกว้างจะใช้รูปแบบกล่อง CSS ปกติและความกว้างสูงสุดใช้โมเดลกล่องชายแดนของ Internet Explorer ช่างแปลกเหลือเกิน

ตกลงว่าอันสุดท้ายดูเหมือนจะเป็นข้อบกพร่องใน Firefox 3 Internet Explorer 8 และ Safari 4 จำกัด ความกว้างสูงสุดไว้ที่ 100% + ช่องว่างภายใน + ขอบซึ่งเป็นสิ่งที่ข้อมูลจำเพาะบอก ในที่สุด Internet Explorer ก็มีบางอย่างที่ถูกต้อง

โอ้พระเจ้านี่ช่างยอดเยี่ยม! ในกระบวนการของการเล่นกับสิ่งนี้และด้วยความช่วยเหลือจากปรมาจารย์ผู้น่ายกย่องDean EdwardsและErik Arvidssonฉันได้รวมกันสามโซลูชันแยกกันเพื่อสร้าง cross-browser ความกว้าง 100% ที่แท้จริงด้วยองค์ประกอบที่มีช่องว่างภายในและขอบ ดูคำตอบด้านล่าง วิธีนี้ไม่ต้องใช้มาร์กอัป HTML พิเศษใด ๆ เพียงแค่คลาส (หรือตัวเลือก) และพฤติกรรมที่เป็นตัวเลือกสำหรับ Internet Explorer รุ่นเก่า



7
@SleepyCod ที่ไม่ซ้ำกันแน่นอน คำถามนี้เกี่ยวข้องกับปัญหาของinputองค์ประกอบที่เห็นได้ชัดว่าไม่สอดคล้องกับข้อกำหนดของ CSS 2.1 ในขณะที่คำถามที่คุณเชื่อมโยงเพื่อถามถึงวิธีการป้องกันกล่องที่ล้นซึ่งเกิดขึ้นอย่างสมบูรณ์ภายในขอบเขตของข้อกำหนดเฉพาะของ CSS 2.1 ทั้งคำถามและวิธีแก้ปัญหาของพวกเขาทับซ้อนกัน แต่การเรียกซ้ำซ้อนกันนั้นผิด
พฤศจิกายน

คำตอบ:


130

ลองดูสิ่งที่ฉันคิดขึ้นมาซึ่งเป็นโซลูชันที่ใช้box-sizing:border-boxสไตล์ที่ไม่รู้จักจาก CSS 3 ซึ่งจะช่วยให้มีความกว้าง 100% ที่แท้จริงในองค์ประกอบใด ๆ โดยไม่คำนึงถึงช่องว่างภายในและ / หรือขอบขององค์ประกอบนั้น

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8">

        <title>Cross-browser CSS box-sizing:border-box</title>

        <style type="text/css">
            form {display:block; margin:0; padding:0; width:50%; border:1px solid green; overflow:visible}
            div, input {display:block; border:1px solid red; padding:5px; width:100%; font:normal 12px Arial}

            /* The voodoo starts here */
            .bb {
                box-sizing: border-box; /* CSS 3 rec */
                -moz-box-sizing: border-box; /* Firefox 2 */
                -ms-box-sizing: border-box; /* Internet Explorer 8 */
                -webkit-box-sizing: border-box; /* Safari 3 */
                -khtml-box-sizing: border-box; /* Konqueror */
            }
        </style>

        <!-- The voodoo gets scary. Force Internet Explorer 6 and Internet Explorer 7 to support Internet Explorer 5's box model -->
        <!--[if lt IE 8]><style>.bb {behavior:url("boxsizing.htc");}</style><![endif]-->
    </head>

    <body>
        <form name="foo" action="#">
            <div class="bb">div</div>
            <input class="bb" size="20" name="bar" value="field">
        </form>
    </body>
</html>

โซลูชันนี้รองรับ Internet Explorer 6 และ Internet Explorer 7 ผ่านพฤติกรรมที่เขียนโดย Erik Arvidsson ด้วยการปรับแต่งเล็กน้อยจาก Dean Edwards เพื่อสนับสนุนเปอร์เซ็นต์และความกว้างที่ไม่ใช่พิกเซล

ตัวอย่างการทำงาน
พฤติกรรม (boxsizing.htc)


ดูเหมือนว่าเป็นโซลูชันที่น่าอัศจรรย์ แต่ไม่สามารถใช้งานได้ใน IE8 (กล่อง div & field ไม่กว้างพอ) คุณรู้หรือไม่ว่ามีการอัพเดทใด ๆ กับวิธีนี้หรือไม่? ขอบคุณ!
rocketmonkeys

2
โพลีฟิลล์นี้โดย Schepp อัปเดตโพลีฟิล IE6 / 7 เพื่อจัดการเคสที่มีขอบมากขึ้นและทำงานกับ IE8 ได้ที่ github: github.com/Schepp/box-sizing-polyfill
nicjohnson

ขอบคุณ! ฉันไม่ทราบสาเหตุว่าทำไม <input type = text> และ <input type = submit> มีความกว้างต่างกันเมื่อฉันตั้งค่าทั้งสองให้เป็นความกว้าง 300px วิธีนี้แก้ไขได้! โปรดทราบว่าสองปีต่อมาคุณยังคงต้องใช้คำนำหน้า -moz- สำหรับ Firefox เวอร์ชันล่าสุด caniuse.com/#feat=css3-boxsizing
Darren Cook

4
น่าเสียดายที่วิธีการนี้ไม่สามารถใช้เพื่อกำจัด div wrapper หากคุณต้องการเพิ่มระยะขอบ (เนื่องจากระยะขอบไม่ทำงานบนองค์ประกอบใด ๆ หากคุณใช้ความกว้าง: 100%)
SystemParadox

6
แต่นั่นไม่ได้แก้ปัญหาแม้ว่า ใช่มันใช้งานได้ถ้าคุณใช้width:100%แต่ไม่ได้ถ้าคุณใช้width:autoให้ดูที่นี่: jsfiddle.net/hGuzE
nimrod

8

สาเหตุที่เกิดขึ้นคือขนาดของตัวอักษรถูกกำหนดโดยขนาดคุณลักษณะ เพิ่ม size = "50" ภายในแท็ก <input> จากนั้นเปลี่ยนเป็นขนาด = "100" - ดูว่าฉันหมายถึงอะไร

ฉันสงสัยว่าจะมีวิธีแก้ปัญหาที่ดีกว่า แต่สิ่งเดียวที่นึกได้คือสิ่งที่ฉันพบในคำถาม "คุณสมบัติที่ซ่อนของ HTML" ใน SO: ใช้ div ที่แก้ไขเนื้อหาได้แทนที่จะเป็นอินพุต การส่งผ่านอินพุตของผู้ใช้ไปยังแบบฟอร์มการปิดล้อม (ถ้านั่นคือสิ่งที่คุณต้องการ) อาจจะยุ่งยากเล็กน้อย

คุณสมบัติที่ซ่อนของ HTML


8
ฉันอยากรู้ว่าคน CSS มีเหตุผลในเรื่องนี้อย่างไร หากความกว้างสามารถแทนที่ขนาดอย่างชัดเจนด้วยพิกเซล / เปอร์เซ็นต์ฉันไม่เห็นว่าทำไมมันจึงควรให้เกียรติเมื่อองค์ประกอบเป็นบล็อก
SpliFF

1
อย่างไรก็ตามสิ่งเดียวกันนี้เกิดขึ้นbuttonเช่นกันซึ่งไม่มีsizeแอตทริบิวต์
zanona

1
คำถามที่มุ่งเน้นเพิ่มเติมเกี่ยวกับส่วน "เพราะเหตุใดมาตรฐานเช่นนี้" เช่นคำตอบนี้: stackoverflow.com/questions/4567988/…การอ้างสิทธิ์สูงสุดคือเนื่องจากinputเป็นองค์ประกอบที่ถูกแทนที่
Ciro Santilli 郝海东冠状病六四事件法轮功

7

ทางออกที่ดีที่สุดของคุณคือการตัดอินพุตใน div ด้วยเส้นขอบระยะขอบ ฯลฯ และมีอินพุตภายในที่มีความกว้าง 100% และไม่มีขอบไม่มีขอบ ฯลฯ

ตัวอย่างเช่น,

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <title>width:auto</title>

        <style>
            div {
                border: 1px solid red;
                padding: 5px;
            }
            input, form {
                display: block;
                width: 100%;
            }
        </style>
    </head>

    <body>
        <form>
            <div><input type="text" name="foo" /></div>
        </form>
    </body>
</html>

1
ใช่มันใช้งานได้ แต่มันมีวิธีแก้ปัญหามากกว่าคำตอบ ฉันพยายามระบุสาเหตุที่อินพุตดูเหมือนจะไม่สนใจพฤติกรรมบล็อก
SpliFF

2
โจนาธานโปรดยกโทษให้กับความหยาบคายของฉันที่นี่ แต่ฉันมาที่นี่เพื่อค้นหาคำตอบที่เหมาะสม (tm) และยังยินดีที่ได้อ่าน @SpliFF โดยเฉพาะที่กล่าวถึงว่าเขาต้องการ "คำตอบโดยตรงกับวิธีแก้ปัญหาโดยตรง (อย่างเช่นทำซ้ำหลายครั้งทั้งที่ SO และที่อื่น ๆ บนอินเทอร์เน็ต) คำตอบดูเหมือนจะเพิกเฉยต่อสัญญาของคำถามฉันขอให้คุณ - ทำไม?ขอบคุณล่วงหน้า - ของคุณจริง ๆ
amn

1

คุณสามารถปลอมได้เช่นนี้

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <title>width:auto</title>

        <style>
        div, #inputWrapper {
            border: 1px solid red;
        }
        #topDiv {
            padding: 5px;
            height: 5px;
        }
        form {
            display: block;
        }
        #inputWrapper {
            overflow: hidden;
            height: 15px;
        }
        input {
            display: block;
            width: 100%;
            border-style: none;
            padding-left: 5px;
            padding-right: 5px;
            height: 15px;
        }
        </style>
    </head>

    <body>
        <div id="topDiv"></div>
        <form>
          <div id="inputWrapper">
            <input type="text" name="foo" />
          </div>
        </form>
    </body>
</html>

1
ฉันได้ทำวิธีการปลอมในอดีต แต่จะซื่อสัตย์ฉันเบื่อมัน ฉันจบด้วยแฮ็คปัญญาอ่อนทุกประเภทเช่นใช้ความกว้าง 99% เพื่อรับอินพุตและเลือกให้ตรงกัน ฉันต้องการวิธีที่จะปฏิบัติกับอินพุตเช่น div และฉันหวังว่าฉันจะมองข้ามบางสิ่งบางอย่าง
SpliFF

2
การป้อนข้อมูลของคุณจะล้น inputWrapper เพราะมันยังมีความกว้าง: 100% กับการขยายภายใน
SpliFF

1

ลองสิ่งนี้:

form { padding-right: 12px; overflow: visible; }
input { display: block; width: 100%; }

1
คุณออกจากช่องว่างภายในและชายแดน ฉันกำลังจะบอกว่าคุณผิดจนกว่าฉันจะรู้ว่าคุณกำลังทำอะไรอยู่ ตอนนี้ฉันได้สิ่งที่ merkuro พยายามทำอยู่ (โค้ดของเขายังผิด แต่แนวคิดก็ใกล้จะถึงแล้ว) ช่องว่างทางขวาเปลี่ยนความหมายของ 100% เป็น 12px (เส้นขอบบวกกับช่องว่างภายในของอินพุต) ข้อเสียเปรียบของวิธีการนี้แม้ว่าจะเป็นลูกคนอื่น ๆ ทุกคนในรูปแบบได้รับผลกระทบจากช่องว่างภายในและจำเป็นต้องชดเชยเช่นกัน
SpliFF

1

นอกจากนี้คุณสามารถปลอมมันเช่นนี้

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <title>width:auto</title>

        <style>

            .container {
                width:90%;
            }

            .container div{
                border: 1px solid red;
                padding: 5px;
                font-size:12px;
                width:100%;
            }

            input{
                  width:100%;
                border: 1px solid red;
                font-size:12px;
                padding: 5px;
            }

            form {

                margin:0px;
                padding:0px;
            }

        </style>
    </head>

    <body>
        <div class="container">
            <div>
                asdasd
            </div>
            <form action="">
                <input type="text" name="foo" />
            </form>
        </div>
    </body>
</html>

1
ความน่าจะเป็นแบบเดียวกันข้างต้นคุณมีช่องว่างภายในที่ความกว้าง 100% ที่จะล้น
SpliFF

คุณสามารถทำได้ด้วย javascript
AlexC

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