【问题标题】:width:auto for <input> fields<input> 字段的宽度:自动
【发布时间】:2022-01-11 21:31:55
【问题描述】:

新手 CSS 问题。我认为width:autodisplay:block 元素意味着“填充可用空间”。但是对于&lt;input&gt; 元素,情况似乎并非如此。例如:

<body>
  <form style='background:red'>
    <input type='text' style='background:green; display:block; width:auto'>
  </form>
</body>

那么两个问题:

  1. width:auto 到底是什么意思有明确的定义吗? CSS 规范对我来说似乎含糊不清,但也许我错过了相关部分。

  2. 有没有办法实现我对输入字段的预期行为 - 即。像其他块级元素一样填充可用空间?

谢谢!

【问题讨论】:

标签: css


【解决方案1】:

&lt;input&gt; 的宽度由其size 属性生成。默认的size 是驱动自动宽度的原因。

您可以尝试width:100%,如下面的示例所示。

不填充宽度:

<form action='' method='post' style='width:200px;background:khaki'>
  <input style='width:auto' />
</form>

填充宽度:

<form action='' method='post' style='width:200px;background:khaki'>
  <input style='width:100%' />
</form>

尺寸更小,宽度更小:

<form action='' method='post' style='width:200px;background:khaki'>
  <input size='5' />
</form>

更新

这是几分钟后我能做的最好的事情。它在 FF、Chrome 和 Safari 中是 1 像素,在 IE 中完美。 (问题是#^&* IE 应用边框的方式与其他人不同,因此不一致。)

<div style='padding:30px;width:200px;background:red'>
  <form action='' method='post' style='width:200px;background:blue;padding:3px'>
    <input size='' style='width:100%;margin:-3px;border:2px inset #eee' />
    <br /><br />
    <input size='' style='width:100%' />
  </form>
</div>

【讨论】:

  • 谢谢。 width:100% 不是一回事。如果有边距或边框,它将溢出父框。
  • 您可以明确设置这些以调整您想要的方式,例如border:2px inset #eee; margin:-2px。虽然我自己还没有测试过,但是类似的东西。
  • 谢谢史蒂夫。您还应该查看stackoverflow.com/questions/1030793/…,它还有一些其他有趣的想法。
  • 通过 css 在输入字段上实现一致宽度的史诗解决方案,+1
  • 您可以使用将输入框大小属性设置为边框框来阻止边框与容器重叠。
【解决方案2】:

“有没有明确定义 width:auto 的含义?CSS 规范对我来说似乎含糊不清,但也许我错过了相关部分。”

没有人真正回答原始发帖人问题的上述部分。

答案如下: http://www.456bereastreet.com/archive/201112/the_difference_between_widthauto_and_width100/

只要width的值为auto,元素就可以有水平的 边距、内边距和边框不会变得比其容器更宽...

另一方面,如果指定 width:100%,则元素的总 宽度将是其包含块的 100% 加上任何水平边距, 填充和边框...这可能是您想要的,但很可能不是。

为了可视化差异,我举了一个例子: http://www.456bereastreet.com/lab/width-auto/

【讨论】:

  • 不错的答案/链接,我建议用“box-sizeing:border-box”放第三个例子......
  • 这不是输入,因为 auto 是默认设置,我看不出它有什么用
【解决方案3】:

因为inputwidth 由它的size 属性控制,这就是我初始化 input width 的方式内容:

<input type="text" class="form-list-item-name" [size]="myInput.value.length" #myInput>

更新 (10/01/2022):我最初的答案是从我学习 Angular 时开始的。如果您需要纯 JavaScript,则解决方案更简单:

<input type="text" oninput="this.size = this.value.length">

或者向你的输入 html 元素添加一个“输入”事件监听器并运行如下代码:

const myInput = document.querySelector('input');
myInput.addEventListener('input', this.typing);

(...)

typing(e) {
  e.target.setAttribute('size', e.target.value.length);
}

Obs:根据浏览器的不同,如果/当size 获得0 值时,输入可能会恢复到其默认大小,介于 150 像素和 250 像素之间。在这种情况下,只需将+1 添加到value.length

<input type="text" oninput="this.size = this.value.length + 1">

或者:

typing(e) {
  e.target.setAttribute('size', e.target.value.length + 1);
}

【讨论】:

  • 虽然这个 #angular 的具体答案不是对 OP 问题的有效答案(我也不赞成),但我确实来到这个话题只是为了找到这个特殊的想法。
  • 完美地与 VueJs 一起工作:&lt;input :size="value.length" :value="value" &gt;
  • 小心[size]="0" 会报错。对于任何解决方案设置大小,您可能希望使用font-family: monospace,因为.....WWWWW 窄很多,size 不考虑内容,只考虑当前字体大小的长度。
  • 你可以添加一个以避免错误(myInput.value?.length ?? 0) + 1
  • 请注意,size 属性仅对emailpasswordteltext 输入类型有效。 developer.mozilla.org/en-US/docs/Web/HTML/Element/…。其他输入类型必须使用 CSS width (developer.mozilla.org/en-US/docs/Web/HTML/Element/input/…) 控制。
【解决方案4】:

正如另一个答案中所述,宽度:auto 不起作用,因为输入的 size 属性生成的宽度不能设置为“auto”或类似的东西。

您可以使用一些变通方法使其与盒子模型很好地配合,但据我所知没有什么了不起的。

首先,您可以使用百分比设置字段中的填充,确保宽度加起来为 100%,例如:

input {
  width: 98%;
  padding: 1%;
}

您可以尝试的另一件事是使用绝对定位,将左右设置为 0。使用此标记:

<fieldset>
    <input type="text" />
</fieldset>

还有这个 CSS:

fieldset {
  position: relative;
}

input {
    position: absolute;
    left: 0;
    right: 0;
}

这种绝对定位将导致输入水平填充父字段集,而不管输入的填充或边距如何。然而,这样做的一个巨大缺点是您现在必须处理字段集的高度,除非您设置它,否则它将为 0。如果您的输入都是相同的高度,这对您有用,只需将字段集的高度设置为输入的高度即可。

除此之外还有一些 JS 解决方案,但我不喜欢用 JS 应用基本样式。

【讨论】:

    【解决方案5】:

    这可能不是您想要的,但我的解决方法是将自动宽度样式应用于包装 div - 然后将您的输入设置为 100%。

    【讨论】:

      【解决方案6】:

      如果您愿意包含一些 JavaScript 来解决这个问题,您可以获得精确的大小。这不依赖于sizeems 的近似宽度,不依赖于任何硬编码的元素宽度,并且适用于不接受size 属性的type="number"

      诀窍是让您的input 的大小与具有相同内容的span 完全相同,实际上是具有相同内容的不可见span

      将您的input 与反映input 值的span 一起放入div。给inputspan 提供相同的样式,给input 100% width,然后隐藏span 并将input 绝对定位到span 的顶部。

      这样,容器(以及 input)会根据不可见 span 的内容的视觉外观自动调整大小。

      https://codepen.io/spiffytech/pen/abwWRqo

      <div id="relative-parent">
        <span id="size-calibration"></span>
        <input id="autosized-input" />
      </div>
      
      <style>
        #relative-parent {
          position: relative;
          /* Have some width if the input is empty */
          min-width: 1em;
          /* Adjust size to match the span */
          width: min-content;
        }
      
        #size-calibration {
          visibility: hidden;
          /* Prevent the span from wrapping the text when input value has multiple words, or collapsing multiple spaces into one */
          white-space: pre;
        }
      
        #autosized-input {
          position: absolute;
          left: 0;
          width: 100%;
        }
        
        #size-calibration, #autosized-input {
          /* Normalize styles that the browser sets differently between spans and inputs. 
          Ideally, use a "CSS reset" here. */
          font-family: "Arial";
          padding: 0;
          /* Demonstrate that this works for input with custom styles */
          font-size: 24px;
        }
      </style>
      
      <script>
        function updateSize() {
          const span = document.getElementById('size-calibration');
          const input = document.getElementById('autosized-input')
          span.innerText = input.value;
        }
        document.addEventListener('DOMContentLoaded', () => {
          const input = document.getElementById('autosized-input');
          input.oninput = updateSize;
          
          // Provide some initial content
          input.value = "I'm sized exactly right!"
          updateSize();
        })
      </script>
      

      【讨论】:

      • hacky,但实际上很聪明)
      【解决方案7】:

      我能想到的唯一选择是使用width:100%。如果您也想在输入字段上添加填充,而不仅仅是在其周围放置一个容器label,而是将格式移动到该标签,同时还指定标签的填充。输入字段是固定的。

      【讨论】:

        【解决方案8】:

        Answer 1 - “response” 给出了一个很好的答案/链接。简而言之,“auto”是默认值,所以它就像删除元素宽度的任何变化

        答案 2 - 改用 width: 100%。它将填充 100% 的父容器,在本例中为“表单”。

        【讨论】:

          【解决方案9】:

          现在,flex 或 grid 让它变得更容易

          flex/flex-grow
            <form style='background:red;display:flex;'>
              <input type='text' style='background:green; flex-grow:1'>
            </form>
          grid
            <form style='background:red;display:grid;'>
              <input type='text' style='background:green;'>
            </form>

          【讨论】:

            【解决方案10】:

            使用 JQuery

            $(document).on('input', '.input-fit-width', (e) => {
                 $(e.currentTarget).attr('size',e.currentTarget.value.length);
            })
            

            【讨论】:

              猜你喜欢
              • 2019-02-01
              • 2021-04-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多