深入理解css中vertical-align属性

网站建设 2023-01-28 21:38www.1681989.com免费网站

一、为什么要写这篇文章

今天看到一个问题

两个div 都设置 displayle-block,正常显示;在第二个div中加一个块级元素或者内联元素,显示就变了个样,为什么?

<meta charset="utf-8"/>
<style>
div{
    width: 100px;
    height: 100px;
    border:1px solid red;
    display: le-block;
}
.align{
/    vertical-align: ;/
}
</style>
<body>
    <div>
    </div>
    <div class="align">为什么?</div>
</body>

解决方案就是给第二个div加上vertical-align:。

关于vertical-align和基线我知道一点,这个问题我没能答出,所以学习分享一下。

二、vertical-align干什么的?

w3c有一段相关信息如下

 

'vertical-align'
Value:      basele | sub | super |  | text- | middle | bottom | text-bottom | <percentage> | <length> | herit
Initial:      basele
Applies to:      le-level and 'table-cell' elements
Inherited:      no
Percentages:      refer to the 'le-height' of the element itself
Media:      visual
Computed value:      for <percentage> and <length> the absolute length, otherwise as specified

可以看到vertical-align影响le-level元素和table-cell元素垂直方向上的布局。根据MDN描述,vertical-align对::first-letter和::first-le同样适用。

适用于

le水平的元素  

le:<img>,<span>,<strong>,<em>,未知元素  

le-block:<put>(IE8+),<button><IE8+>....

'table-cell'元素

table-cell:<td>

所以默认情况下,图片,按钮,文字和单元格都可以用vertical-align属性。

取值


复制代码
代码如下:
vertical-align: basele|length|percentage|sub|super||middle|bottom|text-|text-bottom|itial|herit;

三、basele

1、字母‘x’与basele

 字母x的下边缘(线)就是基线。不是字母s之类狼蚁网站SEO优化有尾巴的字母

基线甚至衍生出了  

1.“alphabetic” basele: “字母”基线 – 英文  

2.“hangg” basele: “悬挂”基线 – 印度文  

3.“ideographic” basele: “表意”基线 – 中文

2、basele的确定规则

1、le-table元素的basele是它的table第一行的basele。

2、父元素【le box】的basele是一个le box 的basele。

3、le-block元素的basele确定规则  

规则1le-block元素,如果内部有le box,则le-block元素的basele就是一个作为内容存在的元素[le box]的basele,而这个元素的basele的确定就要根据它自身来定了。  

规则2le-block元素,如果其内部没有le box或它的overflow属性不是visible,那么basele将是这个le-block元素的底marg边界。

3、例子le-block例子

上图描述

上图中从左到右都是le-block元素,红线代表marg-box的边界,蓝线代表basele;黄色为border,绿色为paddg,蓝色为content。

左边元素包含着没有脱离正常流的内容c,中间元素除了没有脱离正常流的内容c外还增加了overflow:hidden,右边元素没有内容,内容区有宽高。

分析图中各种情况le-block元素的basele

上图左图,le-block元素有处于正常流的内容,根据规则1,所以le-block的basele就是一个作为内容存在的元素的basele,也就是内容c的basele,而c的basele根据自身定,就是图中蓝色。

上图中图,le-block元素overflow:hidden不为visible,根据规则2,该le-block元素basele就是le-block元素的marg-box的下边界了,即图中蓝线。

上图右图,le-block元素没有内容,根据规则2,所以其basele为marg-box的下边界,即蓝线。

4、例子basele确定规则例子

举例  

<style type="text/css">
    .ctn-block{
        display: block;
        background-color: #bbb;
        le-height: 200px;
        font-size: 50px;
    }
    .ctn-block .child1{
        display: le-block;
        width: 100px;
        height: 100px;
        marg:10px 0;
        vertical-align: basele;
        background-color: aliceblue;
    }
</style>

<div class="ctn-block">
    <div class="child1"></div>
    <span>Gg</span>
</div>

分析

父元素.ctn-block的base-le是Gg的basele,

le-block元素因为没有内部le box,也没有设置overflow:visible,所以其basele是底marg边界。

四、vertical-align基于basele的不同取值

1、basele

将子元素盒子的basele与父盒子的basele对齐。

2、middle

将元素盒子的垂直中点与父盒子的basele加上父盒子的x-height的一半位置对齐

这里元素盒子的垂直中点容易确定,父盒子的basele也好确定,x-height要进行计算得到,这个x-height就是字母x的高度。

 3、text-

将盒子的顶端(marg-边界)与父盒子的文本区域顶端对齐

审查盒子看到marg-的顶端。

审查文本,看到蓝色区域的上边界就是文本区域顶端。

最终效果就是盒子的顶端与父盒子文本区域顶端对齐。

4、text-bottom

将盒子的底端(marg-bottom边界) 与父盒子的文本区域底端对齐

和text-类似,不过将子元素的marg-bottom和文本区域的下边界对齐。

5、sub

将子元素盒子的basele降低,到适当的父盒子的下标位置

子元素的basele已经确定了,就是marg-bottom下边界,父盒子的下标位置太不好理解。。。需要了解下标这个概念,我们可以通过<sub>标签为文字添加下标,将<span>中的内容修改为Gg<sub>Gg</sub>,就会有如下效果。

这里就是将元素的marg-bottom下边界和下标的basele对齐。

6、super

将元素盒子的basele升高,到适当的父盒子的上标位置。

与sub对应,super提升到上标内容的basele处,通过<sup>标签创建上标。

 

7、percentage

百分比升高(正值)或降低(负值)子元素盒子,具体的升高/降低数值由父盒子的le-height的值乘以百分比计算得出。如果百分比为0%,就和vertical-align:basele一样。

这个是相当好理解的,就相当于子元素盒子的basele升高或降低,具体数值为百分比乘以父盒子的le-height。

本例中,父盒子的le-height为200px,所以设定25%,元素应该上移50px。

并不是很直观,给它加上一个transform: translate(0, 50px);【相对下移50px】,它又移到那个熟悉的位置了。

 

8、length

升高(正值)或降低(负值)子元素盒子。值为升高/降低的距离,如果为0,和vertical-align:basele一样。

以我们最常用的px作为单位,设定vertical-align:50px,效果就和上面百分比为25%(200px25%=50px)一样了,不做例子了。

五、vertical-align基于le box的不同取值

当vertical-align设置为和bottom时,其就不是按照basele进行定位了,而是根据le box进行定位。子元素盒子的顶部和底部也就是其上下marg外边界。

1、

将子元素盒子的顶部和其所在的le box顶部对齐

由于vertical-align:将会让子元素盒子顶部与le box顶部对齐,而如果le box高度小于子元素高度,le box将会被撑开。我们先用一个高度较高的元素撑开le box,然后看看效果

 

可以看到,big子元素撑开了le box,而child1的marg-外边界紧贴在le box的顶端。

2、bottom

将子元素盒子的底部和其所在的le box底部对齐

和类似,由于big用于撑开le box,可以不必修改其vertical-align的值,仅修改child1为vertical-align:bottom,效果

六、le元素下方可能会有一点空隙

例子尝试将li元素在垂直方向上进行对齐的话,这个现象非常常见

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style type="text/css">
        ul{
            background-color: bisque;
        }
        .box { display: le-block;
            width: 100px;
            height: 100px;
            background-color: aliceblue;
            /     vertical-align: middle;/
        }
    </style>

</head>
<body>

<ul>
    <li class="box"></li>
    <li class="box"></li>
    <li class="box"></li>
</ul>
</body>
</html>

 1、垂直空隙

 

因为li元素默认vertical-align:basele,而basele的下方会给字母的一部分留出空间,会产生一个空隙,要产生理想的效果,解决方案就是改变le box的basele位置,比如将这些li设置为vertical-align:middle。【tip:加一个x效果更明显】

 

2、水平空隙

li元素的水平空隙是因为换行引起的,这个换行会变成一个空白,这个空白会被解析为DOM中的文本节点。比如像狼蚁网站SEO优化酱紫的代码。

<ul>
  <li class="box"></li><li class="box"></li>
  <li class="box"></li>
</ul>

效果如下因为前2个li之间没有空白,而2和3个li之间有空白。

 

上面的代码可读性太差,也不美观,一般这样写

    <ul>
        <li class="box"></li><!-- 注释去空格
     --><li class="box"></li>
        <li class="box"></li>
    </ul>

我们用一个注释节点代替空白(文本节点),而注释节点渲染的时候是不渲染的。了解更多DOM中的节点类型,可看我的另一篇文章《DOM》。

七、vertical-align:middle让元素下移而不居中的问题分析

1、问题

现在有三个le-box块,高度分别为100px,200px,300px,想让高度为100px的块垂直居中,于是写出了如下代码  

<style type="text/css">
    .ctn-block{
        background-color: #bbb;
    }
    .ctn-block .child {
    display: le-block;
    width: 100px;
    background-color: aliceblue;
}
.ctn-block .child-1 {
    height: 100px;
/    vertical-align: middle;/
}
.ctn-block .child-2 {
    height: 200px;
}
.ctn-block .child-3 {
    height: 300px;
}
</style>
<div class="ctn-block">
    <div class="child child-1"></div>
     <div class="child child-2"></div>
    <div class="child child-3"></div>
</div>

给中间div加上vertical-align:middle,效果变为上图二的样子——child-1元素下移了,却没有居中。

2、原因

从上面可以指定,vertical-align:middle的定位方式是将子元素盒子的垂直中点与父盒子的basele加上父盒子的x-height的一半位置对齐。

子元素盒子的中点很好算,而父盒子的basele加上父盒子的x-height一半位置又是什么呢?

计算父盒子的basele三个子元素的basele走在一条直线上,就是child-2和child-3的底部。

然后加上父盒子的x-height由于chrome下默认font-size是16px,而font-family:sans-serif,所以x-height的一半大概是3-4px,综上,按照如下方式对齐

 

3、 解决方案

 一种方式是将最高的元素设为vertical-align:middle。

然后将想要居中的也设定为vertical-align:middle,其他的根据需要设定vertical-align:/bottom。

原理有点抽象

明确一点最高元素设定为vertical-align:middle后,这个元素对于le box来说,basele就是其中线。

其他元素设置vertical-align:/bottom后,它们不影响le box的basele,所以再将需要设定垂直居中的元素也设定为vertical-align:middle,它们的basele必然在最高元素的basele之上,所以会会被强制下移,进行居中。

.ctn-block .child-1 {
        height: 100px;
        vertical-align: middle;
    }
    .ctn-block .child-2 {
        height: 200px;
        vertical-align:;
    }
    .ctn-block .child-3 {
        height: 300px;
        vertical-align: middle;
    }

 

4、衍生的一种可行的垂直居中方案

为父元素设定一个伪元素after,其高度为父元素的高度,display:le-block,将其设定为vertical-align:middle即可撑开le box,le box的basele为父元素高度一半的位置。然后设定子元素vertical-align:middle,即可实现居中。

考虑兼容性的话,这里需要使用一些hack,由于IE8不支持::after伪元素,所以需要一个span来替代。而display:le-block亦需要hack。 

八、其他应用

ico和文字对齐

<style type="text/css">
    .pop-head-nologbox {
        width:500px;
    }

    .pop-head-nolog-icon {
        display:le-block;
        width: 14px;
        height: 14px;
        background: url("images/not_log_tip_ico.png") no-repeat;
    }

    .pop-head-nolog-txt {
        display: le-block;
        color: #333;
        font-size: 12px;
        marg-left:2px;
    }

    .pop-head-nolog-btn {
        display: le-block;
        marg-left: 3px;
    }

    .pop-head-nolog-btn a {
        display: block;
        width: 76px;
        height: 25px;
        le-height: 25px;
        color: #fff;
        text-align: center;
        background-color: #00adee;
        border-radius: 1px;
        font-size: 12px;
    }
</style>

<div class="pop-head-nologbox">
    <div class="pop-head-nolog-icon"></div>
    <span class="pop-head-nolog-txt">您还没有登录哦!</span>

    <div class="pop-head-nolog-btn"><a href="javascript:;" j-delegate="log">立即登录</a></div>

</div>

 

我想让左边ico和文字,按钮都对齐。

.pop-head-nolog-icon,.pop-head-nolog-txt,.pop-head-nolog-btn{
        vertical-align: middle;
    }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持狼蚁SEO。

Copyright © 2016-2025 www.1681989.com 推火网 版权所有 Power by