css的line-height和vertical-align布局问题

  • line-height的数字值是和font-size大小相关的;
  • vertical-align的百分比是和line-height值相关的;

关于vertical-align:直接看例子

<div class="test">
      <img
        src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1585110714052&di=906a9fa97f793aef5f61cea620179001&imgtype=0&src=http%3A%2F%2Fa0.att.hudong.com%2F78%2F52%2F01200000123847134434529793168.jpg"
        alt=""
      />
      <span>Xx</span>
    </div>

效果图
在这里插入图片描述
为何图片下面多了一条线?
填充的Xx内容是填充了,把文字去掉了底线的线还是存在,这个多出来的线就叫它空白节点吧(肉眼看不到却影响布局)。我们关心的是这条线是怎么出来的,inline元素默认的垂直方向的对齐方式是什么样的?也就是vertical-align的默认值,它就是baseline
在这里插入图片描述
[
这里补充一下img元素:
img是替换内联元素 (replaced inline element),属于inline element类目。
和其它的内联元素有什么不同呢?它在计算height/margin/width等值或在绝对定位的时候,有一些额外的规则。(CSS2.1 第10章)比如设定了width但未设置height, img的height会根据比列缩放。]

下面来讨论vertical-align具体什么?
先了解它具有的属性:
baseline 默认。元素放置在父元素的基线上。
sub 垂直对齐文本的下标。
super 垂直对齐文本的上标
top 把元素的顶端与行中最高元素的顶端对齐
text-top 把元素的顶端与父元素字体的顶端对齐
middle 把此元素放置在父元素的中部。
bottom 把元素的顶端与行中最低的元素的顶端对齐。
text-bottom 把元素的底端与父元素字体的底端对齐。
length
% 使用 “line-height” 属性的百分比值来排列此元素。允许使用负值。
inherit 规定应该从父元素继承 vertical-align 属性的值。

描述
baseline 默认。元素放置在父元素的基线上
super垂直对齐文本的上标
top把元素的顶端与行中最高元素的顶端对齐
text-top把元素的顶端与父元素字体的顶端对齐
middle把此元素放置在父元素的中部。
bottom把元素的顶端与行中最低的元素的顶端对齐。
text-bottom把元素的底端与父元素字体的底端对齐。
length% 使用 “line-height” 属性的百分比值来排列此元素。允许使用负值。inherit 规定应该从父元素继承 vertical-align 属性的值。

这里我们探讨vertical-align的baseline属性:
css文档中说明:'inline-block’元素的基线是标准流中最后一个line box(行盒)的基线, 除非这个line box里面既没有in-flow line boxes(行内框)或者本身’overflow’属性的计算值不是’visible’, 这种情况下基线是该元素margin底边缘。

看到这我们知道img的表现形式和inline-block元素一样,它的基线就是margin底边缘,而inline元素本身是有高度的,两者基线对齐自然就是上面看到的效果了。

到这里我们发现,多了两个概念:inline元素的高度问题和标准里说的line box(IFC),

1、首先来看iline-height
CSS中起高度作用的只有height和line-height两个属性吧。如果一个元素没设置height那么其最终的高度一定是由line-height决定的。
看例子:

css:
    <style>
      .demo1 {
        font-size: 20px;
        line-height: 0;
        border: 1px solid blue;
        background: red;
      }
      .demo2 {
        font-size: 0;
        line-height: 20px;
        border: 1px solid red;
        background: yellow;
      }
    </style>

html

<div class="demo1">测试1</div>
<div class="demo2">测试2</div>

图1:
图1

图2:
图2
看图能清除的知道盒子的高度就是有height和ling-height决定的。

2、IFC
相较于BFC,IFC要复杂得多。
简单说下 BFC,即块级元素可能会触发块级格式上下文(BFC),块级格式上下文中,块级盒子竖直方向排列,不受上下文外部元素的影响自成一方世界。块级容器指的是包含元素的盒子,块容器可能包含其他块级盒,他可能生成一个行内格式上下文(IFC)

但块容器盒要么只包含行内盒,要么只包含块级盒。但通常会同时包含两者。在这种情况下,将创建匿名块盒来包含毗邻的行内级盒。
例子


//demo1
<div>
  Some inline text 
  <p>followed by a paragraph</p> 
  followed by more inline text.
</div>
// demo2
<p>
  Some inline text 
  <span>followed by a paragraph</span> 
  followed by more inline text.
</p>

通过上面的代码我们得知:
(1)demo1会创建两个匿名的块盒,一个包含p前面的文本(Some inline text ) 一个在p后面的文本( followed by more inline text.)

(2)demo2 生成行内格式上下文,生成一个匿名行盒(line box),里面包含两个匿名行内盒子(line box),Some inline text和followed by more inline text.和一个span行内盒。

结论:
1、当元素的 CSS 属性display 的计算值为inline, inline-block 或 inline-table 时,称它为行内级元素。
行内级元素生成行内级盒(inline-level boxes),参与行内格式化上下文(inline formatting context)。同时参与生成行内格式化上下文的行内级盒称为行内盒(Inline boxes)。
2、如果一个矩形区域,包含着一些排成一条线的盒子,称为line box。
一个line box的宽度,由他的包含块(containg block)和floats的存在情况决定。line box的高度,由你给出的代码决定。(line-height),即所有inline box的最大高度差。
当盒子的高度小于父级盒子高度时,垂直方向的对齐’vertical-align’属性决定。

二、
看完baseline的属性,再来看vertical-align的其他属性,里面提到父级的低端和顶端。下面就来看看什么事低端顶端。

例子:

//html
<div class="demo">
  <span class='line-box'>
    <img src="https://sfault-avatar.b0.upaiyun.com/344/542/3445428434-5631776c183b2_huge256" alt=""><span>Xx</span>
  </span>
</div>
//css
    <style>
      .demo {
        background: red;
      }
      .line-box {
        background: blue;
        line-height: 200px;
      }
      .line-box img {
        vertical-align: text-bottom;
        width: 50px;
      }
      .line-box span {
        margin-left: 20px;
        color: yellow;
      }
    </style>

效果图
在这里插入图片描述

通过IFC知道,之前的例子会生成一个匿名盒子(line box),虽然它可以继承父级的属性,但我们没法直观的操作它,所以把这个匿名行盒变成可控的span元素就好了
我们通过line box 的line-height来控制lin-box的高度,然后设置img的vertical-align属性值,来观察具体的对齐方式。
但这里很容易有个误区,就是父元素的middle,top这些值是怎么确定的?如上,我们通过更改img元素的vertical-align的值,来观察区别,表面上看着好像是父元素根据Xx内容来进行确定的,实则不然。我们来改变上面例子的line-box span样式:
添加样式代码:

.line-box span {
  margin-left: 20px;
  color: yellow;
  vertical-align: text-bottom;
  /* 请自行更改属性值: top, text-top, bottom, text-bottom观察效果 */
}

通过更改了Xx的对齐方式,发现当Xx设置为text-bottom或是text-top的时候父元素(ling box)被撑大了,但这另一方面这也证明了,父元素的基线和中线等并不是由文本Xx决定的,谁决定的呢?前面提过的那个空白节点决定的!
这个空白节点实际上是理解内联元素布局的重点!不知道它的存在,很多问题是搞不清楚的。那么这个空白节点又到底是怎么影响布局的呢?前面说过基线的决定着是小写字母x,但是不同的字体font-family,它的基线是不一样的。。。

结论
所有的内联元素都有两个高度

  1. 基于字体度量的 content-area
  2. virtual-area(也就是 line-height )
    内联元素都有一个空白节点存在着来确定基线等概念;
    基线的确定和字体有关,和内部的内联元素无关;
    IFC很难懂;
    line-box(行盒) 的高度的受其子元素的 line-height 和 vertical-align 的影响;
    我们貌似没法用CSS来更改字体度量

以上是参考别的文献,自己也实际操作,再感悟出来的,写的比较粗糙,还有很多可以探究了,未来再继续补充和完善

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值