Đầu vào với màn hình: khối không phải là một khối, tại sao không?


153

Tại sao display:block;width:auto;trên đầu vào văn bản của tôi không hoạt động như một div và điền vào chiều rộng vùng chứa?

Tôi đã có ấn tượng rằng một div chỉ đơn giản là một yếu tố khối với chiều rộng tự động. Trong đoạn mã sau không nên div và đầu vào có kích thước giống hệt nhau?

Làm thế nào để tôi có được đầu vào để lấp đầy chiều rộng? Chiều rộng 100% sẽ không hoạt động, vì đầu vào có phần đệm và đường viền (gây ra chiều rộng cuối cùng là 1 pixel + 5 pixel + 100% + 5 pixel + 1 pixel). Độ rộng cố định không phải là một tùy chọn và tôi đang tìm kiếm thứ gì đó linh hoạt hơn.

Tôi muốn một câu trả lời trực tiếp cho một cách giải quyết. Điều này có vẻ giống như một trò chơi CSS và hiểu nó có thể hữu ích sau này.

<!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>

Tôi nên chỉ ra rằng tôi đã có thể làm điều này với cách giải quyết của trình bao bọc. Ngoài vấn đề liên quan đến ngữ nghĩa trang và bộ chọn CSS, tôi đang cố gắng tìm hiểu bản chất của vấn đề và liệu nó có thể được khắc phục hay không bằng cách thay đổi bản chất của chính INPUT.

Ok, đây là SỰ THẬT kỳ lạ! Tôi thấy rằng giải pháp đơn giản là thêmmax-width:100% vào một đầu vào width:100%;padding:5px;. Tuy nhiên, điều này đặt ra nhiều câu hỏi hơn (mà tôi sẽ hỏi trong một câu hỏi riêng), nhưng có vẻ như chiều rộng sử dụng mô hình hộp CSS bình thường và chiều rộng tối đa sử dụng mô hình hộp viền Internet Explorer. Làm thế nào rất kỳ quặc.

Ok, cái cuối cùng có vẻ là một lỗi trong Firefox 3. Internet Explorer 8 và Safari 4 giới hạn chiều rộng tối đa đến 100% + phần đệm + viền, đó là những gì thông số kỹ thuật nói. Cuối cùng, Internet Explorer đã có một cái gì đó đúng.

Ôi chúa ơi, điều này thật tuyệt vời! Trong quá trình chơi với điều này, và với nhiều sự giúp đỡ từ các bậc thầy đáng kính là Dean EdwardsErik Arvidsson , tôi đã xoay sở để ghép ba giải pháp riêng biệt để tạo ra một trình duyệt chéo thực sự 100% trên các phần tử với phần đệm và đường viền tùy ý. Xem câu trả lời dưới đây. Giải pháp này không yêu cầu bất kỳ đánh dấu HTML bổ sung nào, chỉ cần một lớp (hoặc bộ chọn) và một hành vi tùy chọn cho Internet Explorer cũ.



7
@SaddyCod đó không phải là một bản sao chính xác. Câu hỏi này liên quan đến vấn đề các inputyếu tố dường như không tuân theo đặc tả CSS 2.1, trong khi câu hỏi bạn liên kết với hỏi làm thế nào để ngăn chặn các hộp tràn xảy ra hoàn toàn trong giới hạn của thông số CSS 2.1. Cả hai câu hỏi và giải pháp của chúng trùng nhau nhưng gọi chúng là trùng lặp chính xác chỉ đơn giản là sai.
Amn

Câu trả lời:


130

Kiểm tra những gì tôi đã đưa ra, một giải pháp sử dụng kiểu tương đối không rõ box-sizing:border-boxtừ CSS 3. Điều này cho phép độ rộng 100% 'đúng' trên bất kỳ phần tử nào, bất kể phần đệm và / hoặc viền của phần tử đó.

<!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>

Giải pháp này hỗ trợ Internet Explorer 6 và Internet Explorer 7 thông qua hành vi được viết bởi Erik Arvidsson với một số điều chỉnh từ Dean Edwards để hỗ trợ tỷ lệ phần trăm và độ rộng không pixel khác.

Ví dụ làm việc
Hành vi (boxsizing.htc)


Đây có vẻ là một giải pháp tuyệt vời, nhưng không hoạt động trong IE8 (hộp div & field không đủ rộng). Bạn có biết nếu có bất kỳ cập nhật về phương pháp này? Cảm ơn!
lửa

2
Polyfill này của Schepp cập nhật polyfill IE6 / 7 để xử lý nhiều trường hợp cạnh hơn và làm việc với IE8 tại github: github.com/Schepp/box-sizing-polyfill
nicjohnson

Cảm ơn! Tôi không thể tìm ra lý do tại sao <input type = text> và <input type = submit> có độ rộng khác nhau khi tôi đặt cả hai chiều rộng 300px. Điều này đã giải quyết nó! Lưu ý rằng hai năm sau bạn vẫn cần sử dụng tiền tố -moz- cho phiên bản Firefox mới nhất. caniuse.com/#feat=css3-boxsizing
Darren Cook

4
Thật không may, cách tiếp cận này không thể được sử dụng để loại bỏ div trình bao bọc nếu bạn cũng cần thêm lề (vì lề không hoạt động đúng với bất kỳ phần tử nào nếu bạn sử dụng chiều rộng: 100%)
SystemParadox

6
Điều đó không khắc phục vấn đề mặc dù. Có, nó hoạt động nếu bạn sử dụng width:100%nhưng nó không hoạt động nếu bạn sử dụng width:auto, xem tại đây: jsfiddle.net/hGuzE
nimrod

8

Lý do điều này xảy ra là kích thước của đầu vào văn bản được xác định bởi thuộc tính kích thước của nó. thêm kích thước = "50" bên trong thẻ <input>. Sau đó thay đổi nó thành size = "100" - xem ý tôi là gì?

Tôi nghi ngờ có một giải pháp tốt hơn, nhưng cách duy nhất nảy ra trong đầu tôi là một câu hỏi tôi tìm thấy trong câu hỏi "Các tính năng ẩn của HTML" trên SO: Sử dụng div có thể chỉnh sửa nội dung, thay vì nhập liệu. Chuyển đầu vào của người dùng vào biểu mẫu kèm theo (nếu đó là những gì bạn cần) có thể hơi khó.

Các tính năng ẩn của HTML


8
Tôi tò mò muốn biết làm thế nào những người CSS biện minh cho điều này. Nếu chiều rộng có thể ghi đè kích thước một cách rõ ràng bằng pixel / phần trăm, tôi không hiểu tại sao nó nên tiếp tục tôn vinh nó khi phần tử là một khối.
SpliFF

1
Tuy nhiên, điều tương tự cũng xảy ra với buttoncái không có sizethuộc tính?
zanona

1
Một câu hỏi tập trung nhiều hơn vào phần "tại sao tiêu chuẩn như thế này" lại giống như câu trả lời này: stackoverflow.com/questions/4567988/ chủ Yêu cầu hàng đầu cho rằng đó là vì inputlà một yếu tố thay thế.
Ciro Santilli 郝海东 冠状 病 事件

7

Đặt cược tốt nhất của bạn là bọc đầu vào trong một div với đường viền, lề, v.v. và có đầu vào bên trong với chiều rộng 100% và không có viền, không có lề, v.v.

Ví dụ,

<!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
Vâng, nó sẽ hoạt động nhưng đó là một cách giải quyết hơn là một câu trả lời. Tôi đang cố gắng thiết lập lý do tại sao đầu vào dường như bỏ qua hành vi chặn.
SpliFF

2
Jonathan, xin vui lòng tha thứ cho sự thô lỗ rõ ràng của tôi ở đây, nhưng tôi đến đây để tìm câu trả lời đúng (tm), và cũng sẵn sàng đọc phần mà @SpliFF đề cập cụ thể rằng anh ta sẽ thích "câu trả lời trực tiếp hơn cho cách giải quyết, nhưng bạn vẫn thêm một câu thừa (như trong, lặp đi lặp lại nhiều lần ở cả SO và các nơi khác trên Internet) câu trả lời, dường như bỏ qua các hợp đồng của câu hỏi tôi có thể hỏi bạn -. ? tại sao . Cảm ơn bạn trước bạn -Curiously.
Amn

1

Bạn có thể giả mạo nó, như thế này:

<!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
Tôi đã thực hiện phương pháp giả mạo trong quá khứ nhưng thành thật mà nói tôi đang phát bệnh về nó. Tôi kết thúc với tất cả các loại hack bị trì hoãn như sử dụng chiều rộng 99% để có được đầu vào và chọn để khớp. Tôi thực sự muốn một cách để đối xử với một đầu vào như một div và tôi đã hy vọng tôi sẽ bỏ qua một cái gì đó.
SpliFF

2
Ngoài ra, đầu vào của bạn sẽ tràn vào inputWrapper vì nó vẫn có chiều rộng: 100% với phần đệm bên trong.
SpliFF

1

Thử cái này:

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

1
bạn rời khỏi phần đệm đầu vào và đường viền. Tôi đã định nói rằng bạn sai cho đến khi tôi nhận ra những gì bạn đang làm. Bây giờ tôi có được những gì merkuro đã cố gắng làm (mã của anh ta vẫn sai, nhưng khái niệm đã gần như ở đó). Quyền đệm thay đổi ý nghĩa của 100% x 12px (viền cộng với phần đệm của đầu vào). Tuy nhiên, nhược điểm của phương pháp này là tất cả những đứa trẻ khác cũng bị ảnh hưởng bởi phần đệm và cũng cần phải bù đắp.
SpliFF

1

Ngoài ra, bạn có thể giả mạo nó, như thế này:

<!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
tương tự như trên, bạn có phần đệm bên trong trên chiều rộng 100%. Điều đó sẽ tràn ra.
SpliFF

bạn có thể làm điều này với javascript
AlexC

1

Thêm điều này vào phong cách của bạn:

box-sizing: border-box;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.