用 display:block 输入不是块,为啥不呢?

Posted

技术标签:

【中文标题】用 display:block 输入不是块,为啥不呢?【英文标题】:Input with display:block is not a block, why not?用 display:block 输入不是块,为什么不呢? 【发布时间】:2010-11-05 01:44:12 【问题描述】:

为什么我的文本输入中的 display:block;width:auto; 不像 div 并填充容器宽度?

我的印象是 div 只是一个具有自动宽度的块元素。在下面的代码中,div 和 input 的尺寸不应该相同吗?

如何获取输入以填充宽度? 100% 宽度不起作用,因为输入具有填充和边框(导致最终宽度为 1 像素 + 5 像素 + 100% + 5 像素 + 1 像素)。固定宽度不是一个选项,我正在寻找更灵活的东西。

我更喜欢直接回答解决方法。这似乎是一个 CSS 怪癖,理解它以后可能会有用。

<!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 选择器关系搞砸之外,我还试图了解问题的性质以及是否可以通过改变 INPUT 本身的性质来克服它。

好吧,这真是太奇怪了!我发现解决方案是简单地将max-width:100% 添加到带有width:100%;padding:5px; 的输入中。然而,这引发了更多问题(我将在一个单独的问题中提出),但似乎 width 使用了普通的 CSS 框模型,而 max-width 使用了 Internet Explorer 边框框模型。多么奇怪。

好的,最后一个似乎是 Firefox 3 中的错误。Internet Explorer 8 和 Safari 4 将最大宽度限制为 100% + padding + border,这是规范所说的。终于,Internet Explorer 做对了。

天哪,这太棒了!在玩这个的过程中,在可敬的大师Dean Edwards 和Erik Arvidsson 的大力帮助下,我设法拼凑了三个独立的解决方案,以在具有任意填充和边框的元素上实现真正的跨浏览器 100% 宽度。请参阅下面的答案。此解决方案不需要任何额外的 HTML 标记,只需要一个类(或选择器)和旧版 Internet Explorer 的可选行为。

【问题讨论】:

http://***.com/questions/628500/can-i-stop-100-width-text-boxes-from-extending-beyond-their-containers 的完全相同的副本 @SleepyCod 这不是完全重复的。这个问题涉及input 元素显然不遵守 CSS 2.1 规范的问题,而您链接到的问题询问如何防止溢出框,顺便说一下,溢出框完全在 CSS 2.1 规范的范围内发生。问题及其解决方案都重叠,但称它们完全重复是完全错误的。 【参考方案1】:

将此添加到您的样式中:

box-sizing: border-box;

【讨论】:

【参考方案2】:

看看我想出什么,一个使用 CSS 3 中相对未知的 box-sizing:border-box 样式的解决方案。这允许任何元素的“真实”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>

此解决方案通过 Erik Arvidsson 编写的行为支持 Internet Explorer 6 和 Internet Explorer 7,并由 Dean Edwards 进行了一些调整以支持百分比和其他非像素宽度。

Working exampleBehaviour (boxsizing.htc)

【讨论】:

这看起来是一个了不起的解决方案,但在 IE8 中不起作用(div 和字段框不够宽)。你知道这个方法有没有更新?谢谢! Schepp 的这个 polyfill 更新了 IE6/7 polyfill 以处理更多的边缘情况并在 github 上使用 IE8:github.com/Schepp/box-sizing-polyfill 谢谢!当我将它们都设置为 300px 宽时,我无法弄清楚为什么 的宽度不同。这解决了它!请注意,两年后您仍然需要为最新版本的 Firefox 使用 -moz- 前缀。 caniuse.com/#feat=css3-boxsizing 不幸的是,如果您还需要添加边距,这种方法不能用于消除包装器 div(因为如果您使用 width: 100%,边距在任何元素上都不起作用) 但这并不能解决问题。是的,如果你使用width:100%,它就可以工作,但如果你使用width:auto,它就不行,见这里:jsfiddle.net/hGuzE【参考方案3】:

你也可以伪造它,像这样:

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

【讨论】:

与上述相同的可能性,您有一个 100% 宽度的内部填充。那会溢出的。 你可以用javascript做到这一点【参考方案4】:

最好的办法是用你的边框、边距等将输入包装在一个 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>

【讨论】:

是的,它会起作用,但这更像是一种解决方法而不是答案。我试图确定为什么输入似乎忽略了块行为。 乔纳森,请原谅我在这里明显的粗鲁,但我来这里是为了寻找正确的(tm)答案,也很高兴阅读@SpliFF 特别提到他更喜欢“直接回答解决方法,但是您仍然添加另一个冗余(如在 SO 和 Internet 上的其他地方重复多次)答案,似乎忽略了问题的合同。请问您 - 为什么?谢谢提前。-很好奇你的。【参考方案5】:

试试这个:

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

【讨论】:

您省略了输入填充和边框。我正要说你错了,直到我意识到你在做什么。现在我明白了 merkuro 想要做什么(他的代码仍然是错误的,但这个概念几乎就在那里)。 padding-right 将 100% 的含义更改为 12px(边框加上输入的填充)。但是这种方法的缺点是所有其他的 form 子元素也会受到 padding 的影响,并且也需要进行补偿。【参考方案6】:

你可以像这样伪造它:

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

【讨论】:

我过去做过假的方法,但老实说我已经厌倦了。我最终得到了各种迟钝的技巧,比如使用 99% 的宽度来获取输入并选择匹配。我真的想要一种将输入视为 div 的方法,我希望我只是忽略了一些东西。 你的输入也会溢出 inputWrapper 因为它仍然有 width:100% 的内部填充。【参考方案7】:

发生这种情况的原因是文本输入的大小由其大小属性决定。在 标签内添加 size="50"。然后将其更改为 size="100" -- 明白我的意思吗?

我怀疑有更好的解决方案,但我想到的唯一一个是我在 SO:使用内容可编辑的 div,而不是输入的“HTML 的隐藏功能”问题上发现的。将用户输入传递给封闭的表单(如果这是您需要的)可能有点棘手。

Hidden features of HTML

【讨论】:

我很想知道 CSS 人员如何证明这一点。如果宽度可以用像素/百分比显式覆盖大小,我不明白为什么当元素是块时它应该继续尊重它。 但是同样的情况也发生在没有size 属性的button 上? 一个更关注“为什么是这样的标准”部分的问题,比如这个答案:***.com/questions/4567988/… 最重要的说法是因为input 是一个被替换的元素。跨度>

以上是关于用 display:block 输入不是块,为啥不呢?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 bootstrap 在 .span 上使用浮点数而不是 display: inline-block?

display属性

有关display在IE谷歌的兼容性问题

display:inline-block

如何理解CSS中的display:inline-block属性?

关于ie6块元素行内元素转换