【问题标题】:Text input on Chrome: line-height seems to have a minimumChrome 上的文本输入:行高似乎有最小值
【发布时间】:2016-01-16 01:49:13
【问题描述】:

我正在尝试使用值设置文本输入的样式,使用占位符和跨度设置文本输入的样式,在 Chrome 中也是如此。具体来说,我想独立于字体大小来控制行高。

但是,输入值似乎有某种最小行高(或引起类似影响的东西),这似乎会以某种方式将文本向下推,从而阻止相同的样式。

示例 HTML:

<div>
  <input type="text" value="Text">
  <input type="text" placeholder="Text">
  <span>Text</span>
</div>

CSS:

div {
  line-height: 50px;
  font-family: Arial;
}

input,
span {
  font-size: 50px;
  line-height: 50px;
  height: 50px;
  width: 100px;
  padding: 0;
  min-height: 0;
  display: inline-block;
  font-family: inherit;
  border: 2px solid red;
  overflow: hidden;
  vertical-align: top;
}

结果可见

http://plnkr.co/edit/oHbhKDSPTha8ShWVOC7N?p=preview 在 Linux 上的 Chrome 44.0.2403.155(64 位)的以下屏幕截图中:

奇怪的是,占位符的样式似乎具有所需的行高,而输入的文本值的位置不同。我现在不关心占位符的颜色。

如何设置所有 3 个元素的样式,使文本位于相同的位置,我正在使用自定义行高?

我知道我可以将 line-height 设置为 normal1.2,或减小字体大小,以使元素看起来相同,但它们不会具有我正在寻找的视觉外观。

【问题讨论】:

  • 问题似乎源于line-height 不知何故——尝试line-height:56px,它就消失了,而line-height:26px 例如显着增加它……可能是干扰其他属性——我试图查看“计算”选项卡中的所有 -webkit-* 值,但到目前为止我无法发现任何显着差异。
  • 我在原始 plunkr 示例中注意到的另一件事 - 当您单击第一个文本字段时,插入符号光标出现在字母之间,然后移动插入符号 f.e。通过左/右键,然后文本向上移动一点点 - 你能确认吗?
  • @CBroe 是的,然后它向上移动一两个像素
  • 如果你显着增加line-height,告诉66px——那么这个效果(移动插入符号时)会变得更加强大。看起来可能会执行某种“自动居中”……?
  • 是否特别需要设置行高??为什么你不能省略行高并用填充替换它们? @MichalCharemza 使用填充为每个对象创建相同的效果:Plunker

标签: html css google-chrome


【解决方案1】:

我想我做到了!!!

在我的测试中,似乎 line-height 必须至少为 font-size 的 ~115%,所以如果你想要 50px 高的元素,你必须有 ~43px 的东西才能对齐:

图 1. 字体大小为 50px 行高的 86%。排列整齐,但不符合 OP 要求的 50px 字体大小。

input, span {
    border: 2px solid red;
    display: inline-block;
    font: 43px Arial;
    line-height: 50px;
    padding: 0;
    vertical-align: middle;
	width: 100px;
    outline-style:none;
    box-shadow:none;
    overflow:hidden;
    /* optional - to include the borders in the element size: 
    box-sizing:border-box;
    */
}
<input type="text" value="Text">
<input type="text" placeholder="Text">
<span>Text</span>

如果您将字体大小增加到所需的 50 像素,则输入框遵循的最小行高约为 58 像素。任何通过垂直对齐来抵消这一点的尝试对输入没有影响,但我们可以修复元素高度并隐藏溢出以提供一致的(尽管不是完全可观的)外观:

图 2. 50px 文本强制行高为 58px,并被溢出隐藏。

input, span {
    border: 2px solid red;
    display: inline-block;
    font: 50px Arial;
    line-height: 58px;
    padding: 0;  
    height:50px;
    vertical-align: top;
    width: 100px;
    outline-style:none;
    box-shadow:none;
    overflow:hidden;
    /* optional - to include the borders in the element size: 
    box-sizing:border-box;
    */
}
<input type="text" value="Text">
<input type="text" placeholder="Text">
<span>Text</span>

关闭,但没有雪茄。但这让我开始思考——也许伪元素的限制可能更少?我发现您甚至可以在 input 中设置 input::first-line 伪样式,并且这尊重高度、字体大小、行高和垂直对齐方式!

这样瞧!

图 3. 获胜的第一行伪元素!

input, span {
    border: 2px solid red;
    display: inline-block;
    font: 50px Arial;
    line-height: 50px;
    height: 50px;
    padding: 0;
    vertical-align: middle;
    width: 100px;
    outline-style:none;
    box-shadow:none;
    overflow:hidden;
    /* optional - to include the borders in the element size: 
    box-sizing:border-box;
    */
}
input::first-line, span::first-line {
    vertical-align: middle;
}
/* weirdly the placeholder goes black so we have to recolour the first-line */
input::-webkit-input-placeholder::first-line {
    color:grey;
}
<input type="text" value="Text">
<input type="text" placeholder="Text">
<span>Text</span>

这里有很多 jsFiddle,所以你可以看到我的工作。 ;)

https://jsfiddle.net/romz58cc/4/

【讨论】:

  • 最新答案看起来不错...整理一下,去掉之前的可以吗?当然,如果您觉得它们对其他人有帮助,请随时将它们作为单独的答案发布。
  • @MichalCharemza 谢谢。我已经按照建议整理了我的答案。
  • 一切都很好,谢谢。我注意到只要 line-height 至少 font-size 就可以了。如果行高较小,则输入中的文本值似乎被裁剪并且与占位符和跨度情况 jsfiddle.net/romz58cc/6 相比处于不同的位置。 (我不得不承认,我没有使用小于字体大小的输入中的行高,所以这真的只是一个好奇心)
  • 鉴于无法控制插入符号的高度,垂直对齐文本本身是个好主意!你得到了我的投票。
  • "图 3. 获胜的第一行伪元素!"通过利用 Chrome 独有的其他东西来修复 Chrome 独有的错误是多么合适。这就是float: left; display: inline for IE6
【解决方案2】:

为什么会这样?

这种错位是由插入符号引起的,因此如果font-sizeline-height 相同,我认为您不会找到对齐文本的方法。

为什么插入符号有问题?

插入符号的height 大于导致对齐倾斜的文本。

有几件事支持这一点:

1.您可以看到插入符号的大小

  • 单击input 并按住鼠标左键。上下拖动,你会看到文字会移动
  • input, span 中删除height: 50px;input 的大小现在将增加到插入符号的 height

div {
  line-height: 50px;
  font-family: Arial;
}
input, span {
  font-size: 45px;
  line-height: 50px;
  width: 100px;
  padding: 0;
  min-height: 0;
  display: inline-block;
  font-family: inherit;
  border: 2px solid red;
  overflow: hidden;
  vertical-align: top;
}
<div>
  <input type="text" value="Text">
  <input type="text" placeholder="Text">
  <span>Text</span>
</div>

2。占位符文本正确对齐

  • 占位符文本不受插入符号的影响,因此正确对齐
  • 将文本添加到 input 后,对齐就会被取消

插入符号具有更大的height 的结果是line-height 被人为增加导致文本脱节。

这可以通过以下方式证明:

  • line-height 更改为58px。占位符文本和span 的对齐方式将与input 相同

div {
  line-height: 50px;
  font-family: Arial;
}
input, span {
  font-size: 50px;
  line-height: 58px;
  height: 50px;
  width: 100px;
  padding: 0;
  min-height: 0;
  display: inline-block;
  font-family: inherit;
  border: 2px solid red;
  overflow: hidden;
  vertical-align: top;
}
<div>
  <input type="text" value="Text">
  <input type="text" placeholder="Text">
  <span>Text</span>
</div>
  • font-size 更改为45px。插入符号现在将适合 50px height

div {
  line-height: 50px;
  font-family: Arial;
}
input, span {
  font-size: 45px;
  line-height: 50px;
  height: 50px;
  width: 100px;
  padding: 0;
  min-height: 0;
  display: inline-block;
  font-family: inherit;
  border: 2px solid red;
  overflow: hidden;
  vertical-align: top;
}
<div>
  <input type="text" value="Text">
  <input type="text" placeholder="Text">
  <span>Text</span>
</div>

可以做什么?

由于无法设置插入符号本身的样式(使其更小),确保文本对齐的最有效方法是使用小于line-heightfont-size。这反过来会使插入符号更小,并阻止它人为地增加 line-heightinput

div {
  line-height: 50px;
  font-family: Arial;
}
input, span {
  font-size: 45px;
  line-height: 50px;
  height: 50px;
  width: 100px;
  padding: 0;
  min-height: 0;
  display: inline-block;
  font-family: inherit;
  border: 2px solid red;
  overflow: hidden;
  vertical-align: top;
}
<div>
  <input type="text" value="Text">
  <input type="text" placeholder="Text">
  <span>Text</span>
</div>

或者您可以删除 height 并指定一个等于插入符号的 heightline-height

div {
  line-height: 50px;
  font-family: Arial;
}
input, span {
  font-size: 50px;
  line-height: 58px;
  width: 100px;
  padding: 0;
  min-height: 0;
  display: inline-block;
  font-family: inherit;
  border: 2px solid red;
  overflow: hidden;
  vertical-align: top;
}
<div>
  <input type="text" value="Text">
  <input type="text" placeholder="Text">
  <span>Text</span>
</div>

【讨论】:

    【解决方案3】:

    我已经对输入框中的行高进行了一些试验,并认为我已经得出了某种结论。

    如果输入框中的字体大小等于或超过行高,则该框会更改大小,并且其内容(但不是占位符)也会更改以适应。如果您从示例中删除高度,这一点很明显。

      input, span {
        padding: 0;
        margin: 0;
        width: 100px;
        padding: 0;
        min-height: 0;
        display: inline-block;
        font-family: inherit;
        border: 2px solid red;
        vertical-align: middle;
      }
    
      input, input::-webkit-input-placeholder, span {
        line-height: 50px;
        font-size: 50px;
      }
      
    
    <input type="text" value="Text">
    <input type="text" placeholder="Text">
    <span>Text</span>

    如果您将font-size 设置为小于行高,您将不再看到奇怪的行高效果,并且所有文本都位于同一行:

      input, span {
        padding: 0;
        margin: 0;
        width: 100px;
        padding: 0;
        min-height: 0;
        display: inline-block;
        font-family: inherit;
        border: 2px solid red;
        vertical-align: middle;
      }
    
      input, input::-webkit-input-placeholder, span {
        line-height: 50px;
        font-size: 45px;
      }
       
      
    
    <input type="text" value="Text">
    <input type="text" placeholder="Text">
    <span>Text</span>

    这是一个并排的例子:http://codepen.io/Jivings/pen/OyOKOV

    我希望这会有所帮助,至少能让您更接近自己的 CSS 解决方案!

    【讨论】:

    • 我在两个例子中都看到了同样的问题...:/
    • @Victor 嗯,我换了不同的屏幕尺寸,它又不能工作了。但是,如果我进一步减小文本大小,那么一切都会再次正常。也许我的诊断并不准确。文本框中确实出现了一些奇怪的垂直对齐
    【解决方案4】:

    这样试试

    根据链接:Firefox line-height issue with input fields

    输入的行高不会改变,除非你改变字体大小

    所以将 font-size:50px 减小到 45px 看起来会很好。

    代码如下

       div { 
    line-height: 50px; 
    font-family: Arial; 
    } 
    
    span,input[type="text"],input[placeholder]{ 
    height: 50px; 
    width: 100px; 
    padding: 0; 
    min-height: 0; 
    display: inline-block; 
    font-family: inherit; 
    border: 2px solid red; 
    overflow: hidden; 
    vertical-align: top; 
    font-size:45px; 
    
    } 
    
    ::-webkit-input-placeholder { 
    color:#000000; 
    
    }
    

    【讨论】:

    • 这似乎并没有用值 plnkr.co/edit/lcbOZskQ2lAaj57JRtyx?p=preview 固定输入元素中文本的位置。注意:我不是在问占位符的颜色。
    • 这似乎试图设置跨度的样式以匹配输入。我想反过来:设置输入以匹配跨度。
    • 好的,我也会尝试其他方式,到目前为止我只尝试过这个。如果有其他方式我会更新吗?
    • 如果您请求我允许尝试回答这个问题,您可以:-)
    • 如果你减小字体大小,它看起来会很好。你能改变字体大小:50px;字体大小:40px?
    【解决方案5】:

    行高为 1.2 值(即字体大小的 120%)在 chrome 中完美运行

    http://plnkr.co/edit/rJmXLRrGFpi46Vv5THm5?p=preview

      div, input, span {
          line-height: 1.2;
      }
    

    我所做的唯一更改是将两个 50 像素的行高更改为 1.2。 它不会破坏布局,并且三个元素对齐良好。

    所以您的原始代码在 Firefox 中运行良好。

    【讨论】:

    • 但它没有居中。如果你将 line-heght 设置为 1,你会遇到同样的问题。
    • 我看到它居中... :(
    【解决方案6】:

    根据下面的 cmets 更新了基础

    为了对每个元素使用相同的line-height,我将 CSS 更新为:

    *,
    *:before,
    *:after {
      -moz-box-sizing: border-box;
      -webkit-box-sizing: border-box;
      box-sizing: border-box;
    }
    
    div {
      line-height: 50px;
      font-family: Arial;
    }
    
    input, span {
        border: 2px solid red;
        display: inline-block;
        font: 50px Arial;
        height: 60px;
        line-height: 60px;
        padding: 0;
        vertical-align: middle;
        width: 100px;
    }
    input {
        padding-top: 3px;
    }
    

    基本上,如果您使用相同的包含heightline-height,即使您更改字体大小,文本也会正确显示在彼此旁边。字体大小必须至少比高度和行高大 10px 左右,否则会再次倾斜。

    您可以see my updated JS.Fiddle here。希望对您有所帮助。

    【讨论】:

    • 我怀疑它在您的示例中看起来更好的原因是您在输入或跨度上没有自定义行高。如果你把它放回去,将 line-height 设置为 font-size,如 jsfiddle.net/q3g4n8ef/1 ,那么文本位置就会关闭。即使保留border-boxbox-sizing 也是如此。
    • @MichalCharemza 是的。如果您使用 58px 的行高,它们将正确显示。问题是,如果您想使用任何其他行高,则必须重新计算所有属性才能正确显示。
    【解决方案7】:

    所以问题 - 33185205

    OP

    DEMO

    FORK

    说明: &lt;input&gt; 是一个被替换的元素,所以它的内容不会 由用户代理渲染。

    详情参考:HTML5: Non-replaced vs. replaced element?

    解决方案

    参见FORK 或片段

    html {
      height: 100vh;
      width: 100vw;
      font: 400 10px'Arial';
    }
    body {
      height: 100%;
      width: 100%;
      background-color: grey;
      color: #111;
    }
    #form {
      display: inline-table;
    }
    .box {
      display: table-row;
    }
    span,
    input {
      font: inherit;
      font-size: 40px;
      /* */
      height: 50px;
      /* */
      line-height: 50px;
      /* */
      width: 100px;
      display: table-cell;
      outline: 2px solid red;
      border: 5px solid transparent;
      /* */
      padding: 0;
    }
    <!DOCTYPE html>
    <html>
    
    <head>
      <link rel="stylesheet" href="style.css">
    
    </head>
    
    <body>
      <form id="form">
        <div class="box">
          <input id="in1" type="text" placeholder="Text" value="Text">
          <input id="in2" type="text" placeholder="Text" value="">
          <span>Text</span>
        </div>
      </form>
    </body>
    
    </html>
    1. 同样设置&lt;input&gt;s 的heightline-height。 (例如 50 像素)

    2. font-size 设置为小于heightline-height 的大小。 (例如 40 像素)

    3. paddingborder 中的topbottom 设置为先前值除以2 的差值。(例如((50px - 40px) / 2) = 5px)

    【讨论】:

    • @klaar 你能解释一下为什么吗? Fork:plnkr.co/edit/fFm4nWajybHtLdMRQuFa?p=preview 是解决方案(sn-p 是重复的),而不是 Demo。
    • 如果 font-size 等于 line-height,那么奇怪的事情就会发生,要么输入改变它的高度,要么输入内的文本被推下。我在 Windows 上的 Fx 41 和 Android AOSP 浏览器中看到了这一点。
    • @klaar 在第 2 步。*将 font-size 的大小设置为 小于 小于 heightline-height。 * 我什么时候建议font-size 应该等于 line-height
    • 啊,是的,但据我了解,OP 要求字体大小与行高一样大,而不是更小。
    • @klaar OP:如何设置所有 3 个元素的样式,以便文本位于同一位置,我使用自定义行高? 如果简单遵循公式,line-height 可以是 OP 想要的任何东西。
    【解决方案8】:

    因为变音符号不是字体大小的传统定义的一部分,所以你永远不可能有行高 = 字体大小。甚至ASCII 也包含一些变音符号(例如 U0060)。变音符号也可以应用于大写字母,你甚至不需要晦涩的 unicode 扩展,latin1 就足够了(例如 U00C0)。

    当字体设计正确并包含box drawing 块时,这可以很容易地检查 - 画框线应该是联合的,因此例如 U2502 将为您提供字体使用的实际确切的最大高度。它的高度大于 A 或通常用于定义字体大小的其他拉丁大写字母之一。 (不幸的是,因为水平线也应该是联合的,所以方框图块只能在等宽字体中找到。

    在分配字体高度后,文本堆栈仍然必须保留一些放置变音符号的位置(字体格式中的元数据定义了特定字体的消耗量以及变音符号的字体大小)。通常这个地方与行距重叠。当只有一行时,显示为行高>字体大小

    计算字体大小的精确最小行高需要深入了解所使用的字体(通过特定的库,例如 opentype.js)以及用于渲染每个元素的文本引擎的特性。根据这个文本引擎的进步,它将使用更多(或更少)opentype 规范允许的技巧,以最大限度地减少复杂国际情况下的空间浪费。

    例如,除非文本堆栈实现对 opentype 基表opentype spec 的处理,否则实际添加的间距可能会增长到巨大的值(超过西方拉丁语的 15/20% 典型值,并在其他答案中给出)使用支持Vietnamese的字体,或其他喜欢将许多变音符号堆叠在一起的脚本(即使您的浏览器设法使用通用字体呈现此页面,与越南字体相比,它可能会垂直压缩变音符号已安装)

    同样,文本堆栈知道您放在页面上的文本是否包含复杂的变音符号。但是对于输入元素,它没有这样的信息,这取决于用户输入的内容。所以需要保守一点,为你选择的字体支持的脚本保留最坏情况下的行高。

    垂直输入高度分配不足的损坏网站设计很常见,因为网站/js lib/浏览器的作者生活在一个 96dpi 无变音符号的拉丁世界中,并且认为最小化垂直高度很漂亮。一旦以另一种语言查看该网站,这种情况就会中断,其 unicode 字形稍微复杂一些,字体略有不同,或者文本缩放级别略有不同(由于 hidpi 或只是用户近视)。普通文本通常没问题,因为设计者没有试图将其强制放入尺寸过小的固定像素框内。

    输入字段大小被破坏也很常见,当它出于某种原因使用等宽字体时,网页设计师假设无衬线字体和等宽字体之间存在某种比例并试图“修复”它(通常通过扩大等宽字体因为一些浏览器出于模糊的遗留原因而附带了一个小的默认等宽空间,即使它不是一般规则)。

    【讨论】:

      猜你喜欢
      • 2013-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多