【问题标题】:Vertical align all(!) elements in TD?垂直对齐TD中的所有(!)元素?
【发布时间】:2013-09-27 06:40:59
【问题描述】:

我有一个简单的table 和 1 TD vertical-align:middle;。这个TD 包含一个Image

table
{
  border:solid 1px red;
  width:300px;
}

td
{
  height:100px;
  vertical-align:middle;
  width:100%;
  border:solid 1px green;
}
img
{
  height:43px;width:43px;
}

span
{
  vertical-align:middle;
}
<!DOCTYPE html>
<html>
  <head>
    <meta charset=utf-8/>
    <title>JS Bin</title>
  </head>
  <body>
    <table>
      <tr>
        <td>
          <img src='http://static.jsbin.com/images/favicon.png'/>
        </td>
      </tr>
    </table>
  </body>
</html>

一切正常,IMG 垂直对齐。

但是如果我在该图片之后添加其他元素(例如 span):

table
{
  border:solid 1px red;
  width:300px;
}

td
{
  height:100px;
  vertical-align:middle;
  width:100%;
  border:solid 1px green;
}
img
{
  height:43px;width:43px;
}

span
{
  vertical-align:middle;
}
<!DOCTYPE html>
<html>
  <head>
    <meta charset=utf-8/>
    <title>JS Bin</title>
  </head>
  <body>
    <table>
      <tr>
        <td>
          <img src='http://static.jsbin.com/images/favicon.png'/>
          <span>aaa</span>
        </td>
      </tr>
    </table>
  </body>
</html>

问题

TD的垂直对齐不应该垂直对齐所有它的孩子吗?

我怎样才能使span 居中以及

注意

我不想添加另一个 TD ,也不想将 float 与填充/边距一起使用。 IE8+。

编辑:

想要的结果:

【问题讨论】:

  • 跨度是否有固定高度(或)会增加吗?
  • @Harry 跨度确实有一个固定的高度(比如说上限)并且不会增加。这是一个标题。
  • 您可以检查解决方案是否合适。虽然有人无缘无故投了反对票。 :)
  • 这里有一个解决方案 => stackoverflow.com/a/57590933/2736742

标签: html css vertical-alignment


【解决方案1】:

在所有情况下,td 上的 vertical-align: middle; 都符合预期。也就是说,将td 与该行的中心对齐,并将td 的全部内容与垂直中间对齐(默认情况下),在顶部和底部留出相等的空间。

W3 Spec 是这么说的 vertical-align: middle

单元格的中心与其跨越的行的中心对齐。

行高计算:

“table-row”元素框的高度是在用户代理获得该行中的所有单元格后计算的:它是该行计算的“高度”中的最大值,每个单元格的计算“高度”行,以及单元格所需的最小高度 (MIN)。

在 CSS 2.1 中,单元格框的高度是内容所需的最小高度。表格单元格的 'height' 属性可以影响行高(见上文),但不会增加单元格框的高度。

小于行高的单元格框会获得额外的顶部或底部填充。

由于上述原因,trtd 的高度变为 100px,但单元格框仅占用内容所需的高度(img 高度 = 43px)。现在,由于单元格框小于行高,因此添加了额外的填充,如上图框 5 所示,从而使内容也对齐到中间。


TD只有图片:

当只有img时,内容高度等于img的高度。所以它被定位到中间。

从上图中可以看出,这不需要在img 上显式添加vertical-align: middle,因为td 将其内容与中间对齐。


TD 只有内联数据:

td 只有一个spanspan 加上一个内联div 时,内容的高度等于文本的默认line-height(或任何指定的line-height)。在这种情况下,td 也会正确对齐。

当文字内容超出第一行时(参考demo),可以看到td自动向上推first-line(青色背景标注),保证内容整体对齐到中间(不仅仅是一行)。


TD 有一个图像和一个跨度:

当我们在td 中放置imgspan(内嵌文本)时,内容高度等于img 加上第二行和后续行的line-height 的高度。

在这种情况下,有两种可能的情况,如下所述:

案例 1 - img 标签没有 vertical-align 指定

在这种情况下,imgbaseline 对齐(默认)。然后td 将整个内容对齐到中间。这意味着 td 在内容的顶部和底部留下大约 28.5px (= (100-43)/2) 间隙。同样,td 上的 vertical-align 完成了这项工作,它将内容放在中间(也就是说,在顶部和底部留下相等的间隙)。但是文字被下推,因为img 高度更高。

如果我们将img 的高度降低到小于行高(比如10px),我们可以看到即使img + span 它也会对齐到中间。


案例 2 - img 标签有 vertical-align: middle

在这种情况下,td 上的 vertical-align 也与情况 1 中的相同。但是,这种情况下的文本是 near the middle,因为 img 也与 middle 对齐行的。

table {
  border: solid 1px red;
}
td {
  height: 100px;
  width: 200px;
  vertical-align: middle;
  border: solid 1px green;
}
img {
  height: 43px;
  width: 43px;
  border: solid 1px green;
}
.one td + td img {
  vertical-align: middle;
}
.three td + td img {
  height: 10px;
  width: 10px;
}
.four img {
  vertical-align: middle;
}
.five img + img{
  height: 50px;
  width: 50px;
}
td:first-line {
  background-color: cyan;
}
div {
  display: inline;
}
<table>
  <tr class='one'>
    <td>
      <img src='http://static.jsbin.com/images/favicon.png' />
    </td>
    <td>
      <img src='http://static.jsbin.com/images/favicon.png' />
    </td>
  </tr>
  <tr class='two'>
    <td>
      <div>aaa</div>
      <span>aaa</span>
    </td>
    <td>
      <div>aaa</div>
      <span>aaa aaaaaaa aaaaaaaa aaaaaaaa</span>
    </td>
  </tr>
  <tr class='three'>
    <td>
      Case 1
      <img src='http://static.jsbin.com/images/favicon.png' />
      <span>Image + Span</span> 
    </td>
    <td>
      Case 1
      <img src='http://static.jsbin.com/images/favicon.png' />
      <span>Image + Span</span> 
    </td>
  </tr>
  <tr class='four'>
    <td>
      Case 2
      <img src='http://static.jsbin.com/images/favicon.png' />
      <span>Image + Span</span> 
    </td>
    <td>
      <img src='http://static.jsbin.com/images/favicon.png' />
      <span>Image + Span + more text.......</span> 
    </td>
  </tr>
  <tr class='five'>
    <td>
      Case 3
      <img src='http://static.jsbin.com/images/favicon.png' />
      <img src='http://static.jsbin.com/images/favicon.png' />
      <span>Image + Span text...</span> 
    </td>
    <td>
      <img src='http://static.jsbin.com/images/favicon.png' />
      <span>Image + Span + more text.......</span> 
    </td>
  </tr>  
</table>

【讨论】:

  • nikhil 的回答是什么?它指出对齐的是 td 而不是它的内容
  • 哈利,你的第一个长评论有矛盾。有 td 和 content 。没有细胞。别管它,它只是令人困惑....现在 - 据我所知 - img 保持静止,没有任何对齐(默认为基线),并且 td 本身垂直对齐到最大内容(!!!)高度td现在我是对的吗?
  • @RoyiNamir:我一直使用它的方式是td = cell。我认为这与 Nikhil 使用它的方式相同,也从 单元格的高度,即 td 判断。来到第二部分。是的,你是对的。 vertical-align: middle on tdtd 的内容与中间对齐。因此,例如,如果td 高度为 100 像素,我们有两行 20px 高度,每行,我们将在顶部和底部有 30 像素 ((100-40)/2) 的空间。 imgtd 中的任何其他元素不会与包含它的行的中间对齐,除非也为其设置了 vertical-align。 (顺便说一句,感谢您的赏金:))
  • 你又这样做了:-)。设置垂直对齐中间到 td - 对齐 td(!!不是它的内容!)到其最大内容高度的中间。请确认。我要说的是,如果我站着并且房间与我的肚子对齐,那是有区别的……与……我与房间的中间高度对齐
【解决方案2】:

这是一个 JS fiddle 解决方案

fiddle

这是css

  table
{
  border:solid 1px red;
  width:300px;
}

td
{
  height:100px;
  vertical-align:middle;
  width:100%;
  border:solid 1px green;
}
img
{
  display: inline;
height: 43px;
width: 43px;
  position: relative !important;
float: left;
}

span
{
  height: auto !important;
width: 80%;
float: right;
position: relative;
vertical-align: middle !important;
text-align: left;
}

【讨论】:

  • 感谢您的反对,因为我可以看到很多人被 -1 反对。请尝试提供 SO 建议的原因。
  • 可能是因为 vertical-align: middle; 是您在 &lt;img&gt; 类中所需要的。我没有对你投反对票,但看起来你为这么简单的事情做了太多的工作。
  • 尽我所能将其置于中心位置。实际上是在点燃这件事。所以没有再看要保留什么。如果可能存在一些额外的样式,这可能会有所帮助:)
  • 有人连续投了每一票。也许:) 谁在乎只需要一个适当的解释。 :) 因为小提琴说的答案是正确的:)
【解决方案3】:

你可以使用 vertical-align: middle; 到你的跨度

img
{
  height:43px;width:43px;
  display: inline;
  vertical-align: middle;
}

span
{
  vertical-align:middle;
  display: inline;
  
}

your jsbin


根据评论


您可能认为如果 td 被赋予vertical-align: middle; 那么它应该对齐其中的所有内容但是有一个图像和浏览器理解图像的跨度是什么? : 这个是 inline 还是 inline-block,所以需要设置 display: inline 还是 inline-block;然后你可能会看到它只为图像应用显示属性。 demo

编辑

img 标签:来源:display inline vs inline-block

它们是“块”元素,因为它们具有宽度和高度。

确实,它们都是——或者更准确地说,它们是“内联块”元素。这意味着它们像文本一样内联流动,但也像块元素一样具有宽度和高度。

Also check this:

替换元素

替换元素是其外观和尺寸由外部资源定义的任何元素。示例包括图像(标签)、插件(标签)和表单元素(、、、和标签)。所有其他元素类型都可以称为不可替换元素。

被替换的元素可以具有固有尺寸——宽度和高度值由元素本身定义,而不是由其在文档中的周围环境定义。例如,如果图像元素的宽度设置为自动,则将使用链接图像文件的宽度。内在维度还定义了一个内在比率,用于确定元素的计算维度,应该只指定一个维度。例如,如果只为图像元素指定宽度(例如 100 像素),而实际图像是 200 像素宽和 100 像素高,则元素的高度将按相同的量缩放,达到 50 像素。

被替换的元素也可以有由元素强加的视觉格式要求,不受 CSS 的控制;例如,为表单元素呈现的用户界面控件。

在内联格式化上下文中,您还可以将替换元素视为一个用于包装和布局的单个大字符。可以为替换的内联元素指定宽度和高度,在这种情况下,放置元素的行框的高度足够高以容纳替换的元素,包括任何指定的框属性。

【讨论】:

  • TD 的垂直对齐是否应该垂直对齐其所有子项? (ps span 和 Img 默认是内联的)
  • vertical-align 需要内联显示。
  • 我不明白你的回答。 (您的最后一条评论)您能详细说明一下,以便我和其他人可以从中学习吗?
  • 我的意思是:IMG 默认是内联的。那么为什么将verticalalign 放在TD 上并不适用于所有孩子?你能解释一下吗?
  • 不! img 默认不是内联的。
【解决方案4】:
<style>
table
{
  border:solid 1px red;
  width:300px;
}

td
{
  height:100px;  
  width:100%;
  border:solid 1px green;
  vertical-align:middle;
  line-height:100px;
}
img
{
  height:43px;width:43px;
  vertical-align:middle;
}
</style>

【讨论】:

    【解决方案5】:

    CSS 属性不适用于任何其他类型的元素。当新手开发者将垂直对齐应用于普通块元素(如标准)时,大多数浏览器都会将该值设置为继承给该元素的所有内联子元素。

    您只需将vertical-align: middle 添加到&lt;img&gt; 类。

    你的 CSS 应该是这样的......

    table
    {
      border:solid 1px red;
      width:300px;
    }
    
    td
    {
      height:100px;
      vertical-align:middle;
      width:100%;
      border:solid 1px green;
    }
    img
    {
      height:43px;width:43px;
      vertical-align: middle;
    }
    

    您可以查看Sample Fiddle...

    【讨论】:

      【解决方案6】:

      我想我们都快到了,但是

      td img,
      td span {
      display:inline-block;
      vertical-align:middle;
      }
      

      似乎有效。

      Codepen Example

      还是我错过了什么?

      【讨论】:

        【解决方案7】:

        只需将您的垂直对齐:中间从跨度移动到图像。

        图像将在文本上对齐;比相反的效果更好;)

        img
        {
          height:43px;width:43px;
          vertical-align:middle;
        }
        

        http://jsfiddle.net/ZnpNF/1/

        【讨论】:

          【解决方案8】:

          问题
          TD的垂直对齐不应该垂直对齐它的所有孩子吗?


          当您将vertical-align 应用于td 时,它仅应用于td,并且被其任何子级继承。

          如果我有一个只有跨度的 TD - 它将垂直对齐。如果我的 TD 里面只有 IMG - 它也会对齐。

          这是因为vertical-align for td 的工作方式。计算单元格的总高度,即td,并且整个单元格垂直对齐。

          如果有单个img,那么td的高度与img的高度相同,所以似乎imgvertical-align也是@987654335 @。但实际上,td 与中间垂直对齐,imgvertical-align : baseline

          只有一个span时也是如此。

          但如果我两者都有 - 它没有。这是为什么 ?

          因为现在,tdheightheight 的组合 img + span。所以,实际上,td 在中间垂直对齐,但不是imgspan

          如何使跨度也居中?

          你需要应用这个 CSS :

          td > * {
              vertical-align : middle;
          }
          

          这会将 CSS 应用到所有子级。

          查看JSFiddle 以获得更好的图片。

          希望,这回答了你的问题。

          【讨论】:

          • 您是说在我的第一张图片中,img 与基线对齐吗?根据this,如果我有2个不同的jsfiddle,1个用于img,1个用于span,它们应该在对齐中重叠......
          • 是的,img 与基线对齐。您可以检查img 元素的vertical-align 属性;)
          • 嗯,它都与基线对齐:i.stack.imgur.com/E0LmR.png
          • 查看我的JSFiddle。可以看到通过 jQuery 获取的 CSS 属性。
          • 对于您的图片,请确保您已重置所有marginpadding。不过对我来说看起来不错。
          【解决方案9】:

          DEMO

          只需添加这个类:

          td *{
            vertical-align:middle
          }
          

          编辑:

          问题是为什么当您将图片添加到 td 时,文字会出现在图片的底部,而不是 td 的中间。

          这是我的回答:

          当您将td vertical-align 设置为middle 时,不应将所有内容vertical-align 设置为middle,它们仍然是baseline。而当你在文字中添加图片时,行高会上升到图片的高度,而文字在这个高度的底部,所以你需要将vertical-align设置为middle来解决这个问题。

          在这里你可以看到我说的:DEMO

          抱歉我的英语不好

          【讨论】:

          • 你什么都不解释,你回答我已经知道的。再次阅读问题。
          • @RoyiNamir:图片的vertical-align默认值为baseline
          • 但我将垂直对齐设置为 td,它应该垂直对齐其所有内容!阅读我的赏金说明。
          • @RoyiNamir 不,这不是真的。当默认值为inherit 时,孩子只会获取父属性值。看看这个:DEMO
          • 你不懂。看看this 这是对齐的纯img。现在看看 this :这是 2 个也对齐的标签。 他们不是
          【解决方案10】:

          只需将vertical-align:middle; 添加到您的 img 样式中即可?

          Demo

          【讨论】:

            【解决方案11】:

            这是你的意思吗? http://jsfiddle.net/JFVNq/

            原因是跨度被视为内联,因此您需要将它们设置为阻塞。

            跨度的 CSS:

            td.vert span
            {
                vertical-align: middle;
                display: block;
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-09-05
              • 2018-03-30
              • 1970-01-01
              • 2011-11-16
              • 2014-04-02
              • 2015-07-15
              • 2013-05-29
              • 1970-01-01
              相关资源
              最近更新 更多