Go to comments

HTML+CSS宝典 CSS进阶[扩展] 参考线(下)

四、vertical-align属性

要了解 vertical-align 属性的各种预设值是什么含义,还有数值是什么含义,就需要了解一些知识点


什么知识点呢?

如果一个元素内的子元素出现行盒,那么该元素内部也会产生参考线。


决定参考线的有三个 css 属性

1. font-size      字体大小确定了,5条参考线之间的距离

2. font-family  字体确定了,参考线的相对距离就确定下来了

3. line-height  行高确定了,参考线最顶上那条线 和 最底下那条线都确定下来了

这个三个属性一旦确定,参考线就一定确定下来了


比如,p 元素里面包含一个 span 行盒,

<p>
  <span>M<span>
</p>

span 元素有自己参考线,p 元素也有参考线,因为“只要一个元素里面出现了行盒,它就有参考线”


如果 p 元素里没有 span 元素,直接写一个字母 M,p 元素有没有参考线?

<p>
  M
</p>

p 元素也有参考线,之前说过“文字一定在行盒里面”


现在知道为什么了,因为文字是按照参考线来排列的,

不在行盒里面就没有参考线,没有参考线就没法排列,

所以文字一定在行盒里面,于是文字会包裹一个匿名行盒,这也可以认为是 p 元素里面有行盒,因此 p 元素内部也会产生参考线。


这样 p 元素本身生成的参考线大小是多少呢?

1. 为来看清楚,设置 p 元素的字体大小为 32 像素

2. 设置 p 元素字体为 Arial,span 元素也是 Arial 字体了

3. 行高默认为 normal

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vertical-align</title>
<style>
  p{
    background-color: red;
    font-size: 32px;
    font-family:arial;
    line-height:normal;
  }
  span{
    font-size:200px;
    background-color:lightblue;
    line-height:normal;
  }
</style>
</head>
<body>

<p>
  M
  <span>M<span>
  <span style="font-size:5rem;color:yellow;">M<span>
</p>

</body>
</html>

字体大小、字体类型、行高默认值都确定了,参考线就确定了

1. p 元素内部有参考线,

2. span 元素内部也有参考线,

出现了两个参考线


1、vertical-align 属性的预设值

两个参考线是怎么来排列的呢?


vertical-ailgn: baseline

默认情况是基线对齐,p 元素里也有一个字母M,还有二个 span 元素里面的M,三个M都是基线对齐

MMM


为什么会基线对齐?

1. 因为默认情况下,行盒 span 元素的 vertical-ailgn 属性的值是 baseline  

2. baseline 表示该元素的基线与父元素的基线对齐


vertical-align 还有其它的对齐方法


vertical-align: super; 

super 表示该元素的基线与父元素的上基线对齐

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>super</title>
<style>
  p{
    background-color: red;
    font-size: 32px;
    font-family:arial;
    line-height:normal;
  }
  span{
    font-size:200px;
    background-color:lightblue;
    line-height:normal;
  }
</style>
</head>
<body>

<p>
  M
  <span style="vertical-align:super;">M</span> <!-- 这个span元素的基线,与父元素的上基线对齐 -->
  <span style="font-size:5rem;color:#fff;">M</span>
</p>

</body>
</html>

1. 设置第二个span元素(中间的M)与父元素的上基线对齐,

2. 对第三个span元素没什么影响,它仍然与父元素的基线对齐

image.png


vertical-align: sub

sub 表示该元素的基线与父元素的下基线对齐

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>sub</title>
<style>
  p{
    background-color: red;
    font-size: 32px;
    font-family:arial;
    line-height:normal;
  }
  span{
    font-size:200px;
    background-color:lightblue;
    line-height:normal;
  }
</style>
</head>
<body>

<p>
  M
  <span style="vertical-align:sub;">M</span><!-- 当前这个span元素的基线与父元素的下基线对齐 -->
  <span style="font-size:5rem;color:#fff;">M</span>
</p>

</body>
</html>

第二个M与父元素的下基线对齐

image.png


vertical-align: text-top

text-top 表示该元素的 virtual-area 的顶边(就是加上行高的那条线),对齐父元素的 text-top(文本顶边)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>text-top</title>
<style>
  p{
    background-color: red;
    font-size: 32px;
    font-family:arial;
    line-height:normal;
  }
  span{
    font-size:200px;
    background-color:lightblue;
    line-height:normal;
  }
</style>
</head>
<body>

<p>
  M
  <span style="vertical-align:text-top;">M</span><!-- 当前这个span元素的virtual-area的顶边(加上行高那条线),对齐父元素的text-top(文本顶边) -->
  <span style="font-size:5rem;color:#fff;">M</span>
</p>

</body>
</html>

1. 第二个M的顶边(加上行高)对齐父元素(第一个M)的文本顶边(父元素的第二条线)

image.png


2. 这样导致父元素(第一个M)的基线位置发生变化,父元素的基线位置发生变化,第三个M的位置也跟着变

image.png

这就是为什么会影响到其它元素


vertical-align: text-bottom

表示该元素的 virtual-area 的底边(加行高的边),对齐父元素的 text-bottom

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>text-bottom</title>
<style>
  p{
    background-color: red;
    font-size: 32px;
    font-family:arial;
    line-height:normal;
  }
  span{
    font-size:200px;
    background-color:lightblue;
    line-height:normal;
  }
</style>
</head>
<body>

  <p>
    M
    <span style="vertical-align:text-bottom;">M</span>
    <span style="font-size:5rem;color:#fff;">M</span>
  </p>

</body>
</html>

第二个M加上行高的底边,对齐父元素第一个M的底边

image.png


是加上行高之后的底边,如果给第二个父元素 M 的行高加高点,设置  line-height: 2  底边又变了

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vertical-align:text-bottom</title>
<style>
  p{
    background-color: red;
    font-size: 32px;
    font-family:arial;
    line-height:normal;
  }
  span{
    font-size:200px;
    background-color:lightblue;
    line-height:normal;
  }
</style>
</head>
<body>

  <p>
    M
    <span style="vertical-align:text-bottom; line-height:2;">M</span>
    <span style="font-size:5rem;color:#fff;">M</span>
  </p>

</body>
</html>

第二个M元素是增加行高的底边,对齐第一个父元素字母M的倒数第二条线(text-bottom)

image.png

导致父元素(第一个M)的基线发生变化,父元素的基线发生变化,第三个元素M的位置也发生变化了


vertical-align: top

该元素的 virtual-area 的顶边,对齐父元素的顶边(父元素的顶边,指的是该行中的最高顶边)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>top</title>
<style>
  p{
    background-color: red;
    font-size: 32px;
    font-family:arial;
    line-height:normal;
  }
  span{
    font-size:200px;
    background-color:lightblue;
    line-height:normal;
  }
</style>
</head>
<body>

  <p>
    M
    <span>M</span>
    <span style="font-size:5rem;color:#fff; vertical-align:top;">M</span>
  </p>

</body>
</html>

设置第二span元素(第三个M)

第三个M的最高顶边(加上行高之后的顶边),没有跟第二个M对齐,第三个M的顶边对齐父元素中最高的那条顶边

image.png


vertical-align: bottom

bottom 该元素的 virtual-area 的底边,对齐父元素的底边(该行中的最低边)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vertical-align:bottom</title>
<style>
  p{
    background-color: red;
    font-size: 32px;
    font-family:arial;
    line-height:normal;
  }
  span{
    font-size:200px;
    background-color:lightblue;
    line-height:normal;
  }
</style>
</head>
<body>

  <p>
    M
    <span>M</span>
    <span style="font-size:5rem;color:#fff; vertical-align:bottom;">M</span>
  </p>

</body>
</html>

还是设置第三个M

image.png


2、行框概念 line-box

行盒组合起来,可以形成多行,每一行的区域叫做"line-box"


意思是,一个元素里面可以出现很多行盒,比如 i元素、m元素、span元素、strong元素、还有文字(文字是匿名行盒)等,

这些行盒组合起来可以形成多行,形成多行之后每一行的区域叫做 line-box


Ps:

行盒的单词是 inline-box,

line-box 不好翻译,这里随便翻译一下把它叫做行框


line-box 行框是什么呢?

line-box 是一个区域,表示每一行都有一个 line-box


line-box 的顶边是该行内所有行盒最高顶边,底边是该行行盒的最低底边


比如页面上的三个元素

M  MM

每个M都有自己的参考线,每个M都有一个顶边和底边,整个这一行的盒子生成一个 line-box

line-box 的顶边,就是这一行里最高的顶边

line-box 的底边,就是这一行里最底的底边


形成 line-box,就可以这样表述

vertical-align: top         该元素的 virtual-area 的顶边,对齐 line-box 的顶边

vertical-align: bottom   该元素的 virtual-area 的底边,对齐 line-box 的低边


实际上,一个元素实际占用高度(高度自动的时候),高度的计算是通过 line-box 计算


3、vertical-align 属性还可以取值为数值

数值:是相对于基线的偏移量,向上为正数,向下为负数


默认是基线对齐,设置后面两个M

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vertical-align</title>
<style>
  p{
    background-color: red;
    font-size: 32px;
    font-family:arial;
    line-height:normal;
  }
  span{
    font-size:200px;
    background-color:lightblue;
    line-height:normal;
  }
</style>
</head>
<body>

  <p>
    M
    <span>M</span>
    <span style="font-size:5rem;color:#fff; vertical-align: 20px;">M</span>
    <span style="font-size:5rem;color:#fff; vertical-align: -5px;">M</span>
  </p>

</body>
</html>

image.png


如果设置第二个元素M

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vertical-align</title>
<style>
  p{
    background-color: red;
    font-size: 32px;
    font-family:arial;
    line-height:normal;
  }
  span{
    font-size:200px;
    background-color:lightblue;
    line-height:normal;
  }
</style>
</head>
<body>

  <p>
    M
    <span style="vertical-align: -50px;">M</span> <!-- 设置第二个M -->
    <span style="font-size:5rem;color:#fff;">M</span>
    <span style="font-size:5rem;color:#fff;">M</span>
  </p>

</body>
</html>

第二个M它最高,所以它没法动了,整个 line-box 全靠它撑起了的

MMMM

只能相对对应其它元素,运动是相互的


下面 line-box 的情况就不一样了

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vertical-align</title>
<style>
  p{
    background-color: red;
    font-size: 32px;
    font-family:arial;
    line-height:normal;
  }
  span{
    font-size:200px;
    background-color:lightblue;
    line-height:normal;
  }
</style>
</head>
<body>

  <p>
    M
    <span style="vertical-align: 70px;">M</span>
    <span style="font-size:5rem;color:#fff;">M</span>
    <span style="font-size:5rem;color:#fff;">M</span>
  </p>

</body>
</html>

line-box 的顶边是第二个大 M 的顶边,

line-box 的底边是后面两个 M 的底边

MMMM



4、vertical-align 取值为百分比

百分比,也是相对于基线的偏移量,但是百分百是相对于自身 virtual-area 的高度(算上行高的)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>百分百取值</title>
<style>
  p{
    background-color: red;
    font-size: 32px;
    font-family:arial;
    line-height:normal;
  }
  span{
    font-size:200px;
    background-color:lightblue;
    line-height:normal;
  }
</style>
</head>
<body>

<p>
  M
  <span>M</span>
  <span style="font-size:5rem;color:#fff;">M</span>
</p>

</body>
</html>

设置第三个M

行高、字体大小都会影响它位置变化,这块比较复杂


5、什么情况下不生成行框 line-box?

line-box 是承载文字内容的必要条件,如果没有行框文字是没法显示的


以下情况不生成行框

1. 某元素内部没有任何行盒(不演示这种情况)

2. 某元素字体大小为0, font-size: 0  不生成行框


p 元素里面不生成行框,里面的文字 lorem 不会显示

<p style="font-size: 0;">
  <span style="font-size: 2em;">
    lorem.
  </span>
</p>

行框确定了元素的自动高度,而 p 元素里面没有生成行框,它的高度就是0,因此里面不显示文字


给 p 元素设置高度 100 像素,里面还是不会显示文字

<p style="font-size:0; height:100px; background-color:red;">
  <span style="font-size: 2em;">
    lorem.
  </span>
</p>

这就解释了行框是承载文字的必要条件,没有行框就不会显示

lorem.


但是这里有兼容问题,有些老 IE 浏览器又显示,所以恐怖的要死,

css里面最复杂的就是行盒,了解就行了


五、可替换元素和行块盒的基线

可替换元素 和 行块盒,排列的时候跟行盒一样排成一排,又涉及到参考线的影响。


可替换元素和行块盒的基线在哪?

可替换元素里面又不一样,图片跟 input 又不一样


1、图片的基线在哪?

图片的基线位置,位于图片的下外边距(下外边距就是计算 margin 的尺寸)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>图片元素基线</title>
</head>
<body>

<p style="font-size: 32px;">
    <img style="width:100px;" src="http://www.ruyic.com/blog/uploads/image/201904/155591911913470.png" alt="">
    请联系我M
</p>

</body>
</html>

1. 字母M的基线在字母的边缘

2. 中文字体的基线在字母M往上一些

3. 图片的基线在下外边距

字母M的基线、中文字体的基线、图片的基线是对齐的,在一条线上

请联系我M



给图片设置一个 margin 外边距

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>图片元素基线</title>
</head>
<body>

  <p style="font-size: 32px;">
    <img style="width:100px;margin:20px;" src="http://www.ruyic.com/blog/uploads/image/201904/155591911913470.png" alt="">
    请联系我M
  </p>

</body>
</html>

还是图片的基线对齐

请联系我M


2、图片下面的白边问题

图片下面有红边

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>图片红边</title>
<style>
  div{
    background-color: red;
    font-size: 16px;
  }
</style>
</head>
<body>

<div>
  <img src="http://www.ruyic.com/blog/uploads/image/201904/155591911913470.png" alt="">
</div>

</body>
</html>

为什么图片下面有白边(红边)

因为

1. div 元素里面的子元素出现行盒,div元素内部会生成参考线,

2. div 参考线生成了,基线在图片下边沿的位置

3. 由于图片没有设置 margin,图片的下边沿就是基线,

4. 现在图片跟父元素的基线是对齐的,所以出现了红色的边


解决白边有两个方法

第一个:设置 div 父元素 font-size: 0,父元素就不生成任何行框

第二个:设置 img 元素为块盒 display:block,块盒不会使父元素生成参考线,没有参考线就不存着基线对齐


这里使用 vertical-align 属性不好解决,

设置 img 元素的 vertical-align: bottom 好像是解决了,但是这个问题没有根本上解决

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>图片红边</title>
<style>
  div{
    background-color: red;
    font-size: 16px;
  }
</style>
</head>
<body>

  <div>
    <img style="vertical-align:bottom;" src="http://www.ruyic.com/blog/uploads/image/201904/155591911913470.png" alt="">
  </div>

</body>
</html>

看起来没有红边了


如果图片尺寸特别小,宽度只有 10 像素,还会出现问题,最好的办法就是设置 img 元素为块盒


补充一下

vertical-align: midden  

midden 表示该元素的中线(中线的意思是 content-area 的一半,垂直上的中间位置)与父元素的 X 字母高度一半的位置对齐


3、表单元素的基线

表单元素的基线在内容的底边


给 input 元素设置 margin 属性 20 像素是有效的,因为 input 是可替换元素

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>表单元素的基线</title>
</head>
<body>

<p>
  <input type="checkbox" style="margin:20px;">
  请选择M
</p>

</body>
</html>

input 元素 margin 底边没有和基线对齐,input 的基线和文字的基线对齐。因为 input 的基线和图片不一样

请选择M


4、行块盒基线又不一样了

行块盒分为很多种情况


第一种情况,

行块盒最后一行有 line-box 行框,用最后一行的基线作为整个行块盒的基线(我们很少会遇到这种情况)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>行块盒</title>
</head>
<body>

<p>
  <span style="width:50px; display:inline-block; border:1px solid; padding:20px;">
    Lorem ipsum dolor sit amet
  </span>

  <span>
    M
  </span>
</p>

</body>
</html>

行块盒与 M 的排列,最后一行的基线和 M 对齐

Lorem ipsum dolor sit amet M



第二种情况,

如果行块盒内部没有行盒,则使用下外边距作为基线

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>行块盒</title>
</head>
<body>

<p>
  <span style="width:50px; height:50px; display:inline-block; border:1px solid; margin:20px">

  </span>

  <span>
    M
  </span>
</p>

</body>
</html>

没有文字的情况下,对齐方式又变了,再设置 margin,设置了 margin 就跟图片一样了

M


六、行盒的垂直对齐

多个行盒垂直方向上的对齐


1、怎么解决 文字 和 多选框没有对齐

给没有对齐的元素设置 vertical-align 属性,这里给 input 属性设置  vertical-align: middle 

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>垂直对齐</title>
<style>
  input[type="checkbox"]{
    width: 30px;
    height: 30px;
  }
</style>
</head>
<body>

  <p>
    <input type="checkbox" style="vertical-align: middle; ">
    <span>我同意</span>
  </p>

</body>
</html>

input 自己的位置变化了,导致与文字之间的相对位置也变化了,所以看上去是文字变化了


我同意


除了预设值还可以设置数值,调整到合适的位置

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>垂直对齐</title>
<style>
  input[type="checkbox"]{
    width: 30px;
    height: 30px;
  }
</style>
</head>
<body>

<p>
  <input type="checkbox" style="vertical-align:-9px; ">
  <span>我同意</span>
</p>

</body>
</html>


我同意


2、文字和图片对齐怎么调整呢?

可以设置图片img元素,也可以设置span元素都可以,两行行盒任选一个调整

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>垂直对齐</title>
<style>
</style>
</head>
<body>

<p>
  <img src="http://www.ruyic.com/blog/uploads/image/202202/164605771322963.png" alt="">
  <span style="vertical-align: 17px;">请联系我</span>
</p>

</body>
</html>

这里设置 span 元素 vertical-align 属性


请联系我


对比不设置的 vertical-align 属性的,图片的基线在下边缘,文字的基线和图片的基线对齐的效果

 请联系我


3、关于图片底部白边

白边发生在图片的父元素是一个块盒,块盒的高度是自动的,图片底部和父元素之间会出现空白,父元素设置的字体越大白边越大


一般有两种解决办法

第一种:设置父元素字体大小为0  font-size: 0 ,副作用是父元素里有文字就看不见了

第二种:img元素设置为块盒  display: block ,最常见的就是这种方法



Leave a comment 0 Comments.

Leave a Reply

换一张