【问题标题】:CSS Input with width: 100% goes outside parent's boundCSS 输入宽度:100% 超出父级范围
【发布时间】:2013-05-30 05:45:50
【问题描述】:

我正在尝试制作一个由两个带有插入填充的输入字段组成的登录表单,但是这两个字段最终总是超出其父项的边界;问题源于添加的 inset 填充。可以做些什么来纠正这个问题?

JSFiddle sn-p:http://jsfiddle.net/4x2KP/

注意:代码可能不是最干净的。例如,可能根本不需要封装文本输入的 span 元素。

    #mainContainer {
    	line-height: 20px;
    	font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
        background-color: rgba(0,50,94,0.2);
    	margin: 20px auto;
    	display: table;
    	-moz-border-radius: 15px;
    	border-style: solid;
    	border-color: rgb(40, 40, 40);
    	border-radius: 2px 5px 2px 5px / 5px 2px 5px 2px;
    	border-radius: 2px;
    	border-radius: 2px 5px / 5px;
    	box-shadow: 0 5px 10px 5px rgba(0,0,0,0.2);
    }
    
    .loginForm {
    	width: 320px;
    	height: 250px;
    	padding: 10px 15px 25px 15px;
    	overflow: hidden;
    }
    
    .login-fields > .login-bottom input#login-button_normal {
    	float: right;
    	padding: 2px 25px;
    	cursor: pointer;
    	margin-left: 10px;
    }
    
    .login-fields > .login-bottom input#login-remember {
    	float: left;
    	margin-right: 3px;
    }
    
    .spacer {
    	padding-bottom: 10px;
    }
    
    /* ELEMENT OF INTEREST HERE! */
    input[type=text],
    input[type=password] {
        width: 100%;
    	height: 20px;
    	padding: 5px 10px;
    	background-color: rgb(215, 215, 215);
        line-height: 20px;
        font-size: 12px;
        color: rgb(136, 136, 136);
        border-radius: 2px 2px 2px 2px;
        border: 1px solid rgb(114, 114, 114);
    	box-shadow: 0 1px 0 rgba(24, 24, 24,0.1);
    }
    
    input[type=text]:hover,
    input[type=password]:hover,
    label:hover ~ input[type=text],
    label:hover ~ input[type=password] {
     	background:rgb(242, 242, 242) !important;
    }
    
    input[type=submit]:hover {
      box-shadow:
        inset 0 1px 0 rgba(255,255,255,0.3),
        inset 0 -10px 10px rgba(255,255,255,0.1);
    }
    <div id="mainContainer">
        <div id="login" class="loginForm">
            <div class="login-top">
            </div>
            <form class="login-fields" onsubmit="alert('test'); return false;">
                <div id="login-email" class="login-field">
                    <label for="email" style="-moz-user-select: none;-webkit-user-select: none;" onselectstart="return false;">E-mail address</label>
                    <span><input name="email" id="email" type="text"></input></span>
                </div>
                <div class="spacer"></div>
                <div id="login-password" class="login-field">
                    <label for="password" style="-moz-user-select: none;-webkit-user-select: none;" onselectstart="return false;">Password</label>
                    <span><input name="password" id="password" type="password"></input></span>
                </div>
                <div class="login-bottom">
                    <input type="checkbox" name="remember" id="login-remember"></input>
                    <label for="login-remember" style="-moz-user-select: none;-webkit-user-select: none;" onselectstart="return false;">Remember my email</label>
                    <input type="submit" name="login-button" id="login-button_normal" style="cursor: pointer" value="Log in"></input>
                </div>
            </form>
        </div>
    </div>

【问题讨论】:

    标签: css forms input width


    【解决方案1】:

    填充实际上是添加到宽度上,因此当您说width:100%padding: 5px 10px 时,实际上是在 100% 宽度上增加了 20px。

    【讨论】:

    • 我该如何解决这个问题?我已经尝试了好几个小时了:/
    • 移除 100% 的宽度,因为输入是内联块元素,所以没有必要。
    【解决方案2】:

    您希望输入字段居中吗? 居中元素的技巧:指定元素的宽度并将边距设置为自动,例如:

    margin : 0px auto;
    width:300px
    

    更新的小提琴的链接:

    http://jsfiddle.net/4x2KP/5/

    【讨论】:

    • 不是真的,我试图让它们自动调整为“.loginForm”的宽度。例如:jsfiddle.net/4x2KP/7
    • 您可以更改 .loginForm 的宽度并且输入应保持居中
    • 是的,这是可行的,但我添加了“插入”填充是有原因的:我不希望文本“从头开始”开始。看这张图:d.pr/i/xSH1(比较邮箱输入和密码一)
    【解决方案3】:

    填充添加到整体宽度。因为你的容器有一个像素宽度,你最好也给输入一个像素宽度,但记住要从你设置的宽度中删除填充和边框以避免同样的问题。

    【讨论】:

      【解决方案4】:

      根据CSS basic box model,元素的宽度和高度应用于其内容框。内边距位于该内容框之外并增加了元素的整体大小。

      因此,如果您将一个元素的内边距设置为 100% 宽度,则其内边距将使其宽度超过其包含元素的 100%。在您的上下文中,输入变得比它们的父更宽。

      您可以更改盒子模型处理内边距和宽度的方式。将box-sizing CSS property 设置为border-box 以防止填充影响元素的宽度或高度:

      border-box : width 和 height 属性包括填充和边框,但不包括边距...注意填充和边框将在框内。

      注意browser compatibility of box-sizing (IE8+)。
      在此编辑时,no prefixes are necessary


      Paul IrishChris Coyier 推荐下面的“继承”用法:

      html {
        box-sizing: border-box;
      }
      *, *:before, *:after {
        box-sizing: inherit;
      }
      

      如需参考,请参阅:
      * { Box-sizing: Border-box } FTW
      Inheriting box-sizing Probably Slightly Better Best-Practice


      这是您特定环境中的演示:

      #mainContainer {
        line-height: 20px;
        font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
        background-color: rgba(0, 50, 94, 0.2);
        margin: 20px auto;
        display: table;
        -moz-border-radius: 15px;
        border-style: solid;
        border-color: rgb(40, 40, 40);
        border-radius: 2px 5px 2px 5px / 5px 2px 5px 2px;
        border-radius: 2px;
        border-radius: 2px 5px / 5px;
        box-shadow: 0 5px 10px 5px rgba(0, 0, 0, 0.2);
      }
      .loginForm {
        width: 320px;
        height: 250px;
        padding: 10px 15px 25px 15px;
        overflow: hidden;
      }
      .login-fields > .login-bottom input#login-button_normal {
        float: right;
        padding: 2px 25px;
        cursor: pointer;
        margin-left: 10px;
      }
      .login-fields > .login-bottom input#login-remember {
        float: left;
        margin-right: 3px;
      }
      .spacer {
        padding-bottom: 10px;
      }
      input[type=text],
      input[type=password] {
        width: 100%;
        height: 30px;
        padding: 5px 10px;
        background-color: rgb(215, 215, 215);
        line-height: 20px;
        font-size: 12px;
        color: rgb(136, 136, 136);
        border-radius: 2px 2px 2px 2px;
        border: 1px solid rgb(114, 114, 114);
        box-shadow: 0 1px 0 rgba(24, 24, 24, 0.1);
        box-sizing: border-box;
      }
      input[type=text]:hover,
      input[type=password]:hover,
      label:hover ~ input[type=text],
      label:hover ~ input[type=password] {
        background: rgb(242, 242, 242);
        !important;
      }
      input[type=submit]:hover {
        box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), inset 0 -10px 10px rgba(255, 255, 255, 0.1);
      }
      .login-top {
        height: auto;/*85px;*/
      }
      .login-bottom {
        padding: 35px 15px 0 0;
      }
      <div id="mainContainer">
        <div id="login" class="loginForm">
          <div class="login-top">
          </div>
          <form class="login-fields" onsubmit="alert('test'); return false;">
            <div id="login-email" class="login-field">
              <label for="email" style="-moz-user-select: none;-webkit-user-select: none;" onselectstart="return false;">E-mail address</label>
              <span><input name="email" id="email" type="text" /></span>
            </div>
            <div class="spacer"></div>
            <div id="login-password" class="login-field">
              <label for="password" style="-moz-user-select: none;-webkit-user-select: none;" onselectstart="return false;">Password</label>
              <span><input name="password" id="password" type="password" /></span>
            </div>
            <div class="login-bottom">
              <input type="checkbox" name="remember" id="login-remember" />
              <label for="login-remember" style="-moz-user-select: none;-webkit-user-select: none;" onselectstart="return false;">Remember my email</label>
              <input type="submit" name="login-button" id="login-button_normal" style="cursor: pointer" value="Log in" />
            </div>
          </form>
        </div>
      </div>

      或者,与其为&lt;input&gt; 元素本身添加填充,不如为包裹输入的&lt;span&gt; 元素设置样式。这样,&lt;input&gt; 元素可以设置为width:100%,而不受任何其他填充的影响。示例如下:

      #login-form {
        font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
        background-color: rgba(0, 50, 94, 0.2);
        margin: 20px auto;
        padding: 10px 15px 25px 15px;
        border: 4px solid rgb(40, 40, 40);
        box-shadow: 0 5px 10px 5px rgba(0, 0, 0, 0.2);
        border-radius: 2px;
        width: 320px;
      }
      label span {
        display: block;
        padding: .3em 1em;
        background-color: rgb(215, 215, 215);
        border-radius: .25em;
        border: 1px solid rgb(114, 114, 114);
        box-shadow: 0 1px 0 rgba(24, 24, 24, 0.1);
        margin: 0 0 1em;
      }
      label span:hover {
        background: rgb(242, 242, 242);
        box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), inset 0 -10px 10px rgba(255, 255, 255, 0.1);
      }
      input[type=text],
      input[type=password] {
        background: none;
        border: none;
        width: 100%;
        height: 2em;
        line-height: 2em;
        font-size: 12px;
        color: rgb(136, 136, 136);
        outline: none;
      }
      .login-bottom {
        margin: 2em 1em 0 0;
      }
      input#login-button {
        float: right;
        padding: 2px 25px;
      }
      input#login-remember {
        float: left;
        margin-right: 3px;
      }
      <form id="login-form">
        <label>E-mail address
          <span><input name="email" type="text" /></span>
        </label>
        <label>Password
          <span><input name="password" type="password" /></span>
        </label>
        <div class="login-bottom">
          <label>
            <input type="checkbox" name="remember" id="login-remember" />Remember my email
          </label>
          <input type="submit" name="login-button" id="login-button" value="Log in" />
        </div>
      </form>

      【讨论】:

        【解决方案5】:

        您的 css 中也有错误,此行中有感叹号:

        background:rgb(242, 242, 242);!important;
        

        去掉前面的分号。但是,!important 应该很少使用,并且可以在很大程度上避免使用。

        【讨论】:

        • 啊,谢谢,我一定错过了,而且 !important 标记甚至不是必需的。
        【解决方案6】:

        尝试将box-sizing 更改为border-boxpadding 将添加到您的 input 元素的 width

        See Demo here

        CSS

        input[type=text],
        input[type=password] {
            width: 100%;
            margin-top: 5px;
            height: 25px;
            ...
        }
        
        input {
            box-sizing: border-box;
        }
        

        +box-sizing

        【讨论】:

          【解决方案7】:

          其他答案似乎告诉您对宽度进行硬编码或使用特定于浏览器的 hack。我认为有一个更简单的方法。

          通过计算宽度并减去填充(导致字段重叠)。 20px 来自 10px 的左内边距和 10px 的右内边距。

          input[type=text],
          input[type=password] {
              ...
              width: calc(100% - 20px);
          }
          

          【讨论】:

          • 我不能相信我以前从未见过。非常适合我的用例,而其他答案却没有。谢谢
          • 为我工作。 min/max-width: 100%; 没有,box-sizing: border-box; 没有。我想把我的整个网站放到一个容器中并给它填充会起作用,但我不想仅仅为了这个简单的修复而这样做。
          • 我不认为box-sizing 是“特定于浏览器的黑客”。如果它不起作用,您可能面临与 OP 不同的情况。找出差异并了解为什么有效的原因会很有趣。
          • 这个修复也对我有用,另一个没有。向作者致敬!
          【解决方案8】:

          如果以上所有方法都失败,请尝试为您的输入设置以下属性,使其占用最大空间但不会溢出:

          input {
              min-width: 100%;
              max-width: 100%;
          }
          

          【讨论】:

          • 这对我有用,非常简单的解决方案,谢谢
          • 这也对我有用,而上述带边框的解决方案不起作用 - 谢谢!!
          【解决方案9】:

          我尝试了这些解决方案,但从未得到结论性的结果。最后,我使用了正确的语义标记和字段集。它省去了添加任何宽度计算和任何盒子大小的麻烦。

          它还允许您根据需要设置表单宽度,并且输入保持在边缘所需的填充内。

          在这个例子中,我在表单和字段集上设置了一个边框,在图例和字段集上设置了一个不透明的背景,这样您就可以看到它们是如何重叠和相互放置的。

          <html>
            <head>
            <style>
              form {
                width: 300px;
                margin: 0 auto;
                border: 1px solid;
              }
              fieldset {
                border: 0;
                margin: 0;
                padding: 0 20px 10px;
                border: 1px solid blue;
                background: rgba(0,0,0,.2);
              }
              legend {
                background: rgba(0,0,0,.2);
                width: 100%;
                margin: 0 -20px;
                padding: 2px 20px;
                color: $col1;
                border: 0;
              }
              input[type="email"],
              input[type="password"],
              button {
                width: 100%;
                margin: 0 0 10px;
                padding: 0 10px;
              }
              input[type="email"],
              input[type="password"] {
                line-height: 22px;
                font-size: 16px;
              }
              button {
              line-height: 26px;
              font-size: 20px;
              }
            </style>
            </head>
            <body>
            <form>
                <fieldset>
                    <legend>Log in</legend>
                    <p>You may need some content here, a message?</p>
                    <input type="email" id="email" name="email" placeholder="Email" value=""/>
                    <input type="password" id="password" name="password" placeholder="password" value=""/>
                    <button type="submit">Login</button>
                </fieldset>
            </form>
            </body>
          </html>
          

          【讨论】:

            【解决方案10】:

            试试这个代码

            *, ::after, ::before {
              box-sizing: border-box;
            }
            

            【讨论】:

              猜你喜欢
              • 2011-11-02
              • 1970-01-01
              • 1970-01-01
              • 2016-04-17
              • 1970-01-01
              • 2014-02-08
              • 1970-01-01
              • 2014-10-22
              • 2017-11-08
              相关资源
              最近更新 更多