内联盒子模型,行高,垂直居中

522 阅读5分钟

内联盒子模型

块状元素里面通常放置的是一行一行 行内元素,内联盒子模型决定了这一行一行的行内元素应该如何摆放。

<p>这是一行普通的文字,里面有一个<em>em</em>标签。</p>

上面这些代码浏览器分成了3个盒子来处理。分别为“这是一行普通的文字,里面有一个”,“em”,“标签”三个盒子。

  • 如果内容被行内元素所包含,属于具名的内联盒子。

  • 如果说是光秃秃的文字,则属于匿名内联盒子。

内联盒子的组成:由内容区,上半行间距,下半行间距组成。

font-size变大,内容区域、上下半行间距也会随之增大。

行框盒子(line-box),每一行就是一个行框盒子,每个行框盒子是一个一个内联盒子组成的。

行框盒子的上边界、下边界要包含最高的内联盒子和最低的内联盒子。

行高

格式:line-height:value,定义行高。

line-height具有继承性,其值为如下:

  • normal,默认值,跟随浏览器走,与元素的字体相关联。
  • px, 像素值。
  • 除了px还可以是number作为行高的值。根据当前元素的font-size大小来计算,是指当前font-size的多少倍。例如:line-heighet: 1.5; font-size:20px;那么行高的的实际高度值为1.5*20=30px。

我们用的时候将它放在块状元素上,当放在块状元素上时它表示的是每行的最小行框高度(行与行之间的最小距离)。既然是每行的最小值,那么说明可以比该值大。

line-height的常用功能:

  1. 调整行与行之间的距离。

  2. 不设置块状元素高度的情况下,line-height改变将会撑高盒子,其中的文字将会垂直居中与盒子。(元素的高度将会和行高相同)

    当设置了块状元素高度的情况下,line-height改变只会更改文字的垂直位置,不会改变盒子的高度。(可以写一个带有高度的p标签包含文字来改变line-height的值来看效果,很好的帮助理解)

    反过来想知道了元素的高度之后,我将line-height设置的和元素高度相同将会导致里面的文字垂直居中。

    当想让单行文本垂直居中于当前元素,设置行高=元素高度,单行文本垂直居中。

垂直居中

基线: (baseline),基线是内联盒子中小写英文字母x的下边缘。是为了排列整齐用的。基线是其他线的基本。

格式:**vertical-align:value**

  • baseline,默认值,基线对齐。

    如果是图片的话,图片的底端和基线进行对齐。

  • bottom,将内联盒子的底边与行框的底边对齐。

  • top,将内联盒子的底边与行框的顶边对齐。

  • middle,元素的垂直中心线和父元素的x-height的1/2处对齐。

vertical-align中使用的问题

  • 在一行中,一个高的元素占据了整行的高度,vertical-align不对它有影响(因为没有空间),这个时候还需要各种对齐,所以说会导致父元素的基线产生移动。

  • 块状元素中只包含一张图片时会有不知名的空白。

    问题分析:

    1. 在HTML5文档声明中,内联元素所有解析如同每个行框的前面有一个空白节点(空白节点的特点就是没办法用脚本获取、不占据宽度、透明,幽灵节点),但是只在HTML5中有并且使用了<!DOCTYPE html>的时候才会有。

    2. 根据上面所说,空白节点就是图片的前面有一个看不到的内容。既然是内容默认就是采用vertical-align:baseline对齐,图片是行内块状元素,图片的基线就是图片的底部,所以这个时候才会出现了空白。

    解决方法:

  1.    图片块状化,因为块状元素没有基线。

  2. 将图片改为vertical-align:top/middle/bottom

  3. 对齐问题

    行内块状元素如果是空的基线是元素底部。如果行内块状元素中有内容那么基线是最后一行元素的基线。

    div { display: inline-block; border: 1px solid green; width: 278px; height: 278px; }
    你好小龙虾你好小龙虾
     

line-height和vertical-align的具体应用

  1. 已知元素的宽度和高度让其中的图片垂直居中、水平居中。

    <head>
        <style>
            div {
    
                border: 1px solid green;
                width: 278px;
                height: 278px;
                /* 1. 让父元素的基线移动到垂直中心位置 */
                line-height: 278px;
                text-align: center;
            }
    
            div img {
                /*  2. 让img的绝对垂直中线和父元素的x的1/2处对齐 */
                vertical-align: middle;
                width: 30px;
            }
        </style>
    </head>
    
    <body>
        <div>
            <img src="./1117.jpg" />
        </div>
    </body>
    

   2.多行文本垂直居中

<head>
    <style>
        div {
            width: 500px;
            height: 500px;
            /* 1. 让父元素的基线移动到垂直中心位置  */
            line-height: 500px;
            border: 1px solid green;
        }

        span {
            /* 2. 让span变为行内块状元素 */
            display: inline-block;
            /* 3. 因为行高会被继承所以在这里使用line-height:normal将继承下来的值干掉 */
            line-height: normal;
            border: 1px solid red;
            /* 4. 给这个span设置vertical-middle也就是和父元素的x的1/2处对齐 */
            vertical-align: middle;

        }
    </style>
</head>

<body>
    <div>
        <span>近日有爆料者透露了三星2022年旗舰手机的屏幕大小,其中Galaxy S22、S22+ 均小于目前的S21系列手机。今日有韩国爆料者在博客表示,仅有 Galaxy S22
            Ultra一款机型采用玻璃后盖,S22、S22+
            的后盖将采用全新的处理工艺,不管怎样都是塑料材质,而不是玻璃。</span>
    </div>
</body>

使用vertical-algin:middle进行居中时只是近似垂直居中

为什么是近似垂直居中:

  1. 图片本身有一条中线是绝对的垂直中心线。

  2. vertical-align:middle永远和x-height1/2处对齐。

  3. 由于字体设计的时候字体不会正好占据内容区的1/2,字体都会设计的正好有一些下沉。

  4. 所以说字体设置的越大,内容区就越大,字体下沉的就越厉害。

解决方法:要设置完全垂直居中,将父元素的font-size大小设置为0。(内容区高度就是0,所有的乱七八糟的线都在同一条线上)

重排:页面生成之后,如果页面位置发生变化要从布局阶段重新开始渲染(重排),页面的重排一定会进行后续的重绘。

重绘:页面元素只是显示出来的样式,布局不变,那么页面内容改变将从绘制阶段开始(重绘)。

重排、重绘制都会让页面重新渲染,所以我们尽可能避免重排,减少重绘。