• 【翻译】关于vertical-align所有你需要知道的


    本文是翻译过来的,如果有不对的地方还请指教~,原文链接:Vertical-Align: All You Need To Know

    前面一些说明,可以略过不看吧

    我经常需要对元素进行垂直方向上的布局

    CSS提供了一些方法来实现这个功能,比如float,position: absolute,手动地增加margin或padding。

    我并不是很喜欢这些方法。Floats只能让元素在顶端布局,而且需要手动清除浮动。absolute定位让元素离开文档流,且不再影响它的周围环境。利用固定的margigin和padding会让布局不够灵活。

    但还有另一个方法:vertical-align。我想它应该得到更多的信任。技术上,使用vertical-align来布局是一个hack。因为,它不是为此而设计的。它主要是用来布局文本和文本旁的元素。当然,你也可以在不同的上下文中用vertical-align来灵活地布局元素。该方式下,元素的大小不需要被知道,元素在文档流中,其它元素可以对它的改变做出相应改变

    古怪的vertical-align

    vertical-align有时很奇怪。使用它有时会让人沮丧。比如,对于有些元素设置vertical-align后它会有影响,但是有些却不会。我仍然在vertical-align的黑暗中一次又一次摸索。

    不幸的是,大多数的分析比较表面。尤其是如果我想用vertical-align进行布局。他们主要关注解释尝试利用vertical-align来布局一个元素中所有元素是一个错误。他们给出了vertical-align的基本介绍,并说明在一些简单情况下元素如何布局。但是,他们没有解释tricky的部分。

    所以,我把这篇文章的目标设置为:一次性完全地阐明vertical-align的行为。通过学习W3C CSS规范以及一些实例得到这篇文章。

    正文开始——

    一、哪些元素可以使用vertical-align

    vertical-align是用于inline级元素。这些元素的display属性为:

    • inline:包裹文本的基本标签
    • inline-block:块元素以inline方式呈现。它们可以设置宽度和高度,也可以设置padding、border和margin
    • inline-table(在本文中没有考虑)

    inline级元素分布在一个行中。如果元素过多在一行中放不下时,那么一个新行就会在下面被创建。所有这些行都叫做line盒子,它包裹了这一行中的所有内容不同的内容大小意味着line盒子有不同的高度。下图用红线标出line盒子的顶边和底边。 

    line盒子会勾勒出在其中内容的轮廓。在这些line盒子中,vertical-align用于对一个独立的元素进行布局。

    二、基线baseline和外边缘outer-edge

    垂直布局的最重要的关键点是它包含的元素的基线。在有些情况下,包裹元素的line盒子的顶边和底边也很重要。让我们来看看不同元素类型的基线和外边缘

    • inline元素

    图中线的标识说明:红线line height顶边和底边;绿线:字体font的高度font-size(=基线上方的高度+基线下方的深度)蓝线基线

    line-height = font-size的高度 line height = font-size的2倍 line height = font-size的一半

    inline元素的外边缘让元素布局在line的顶边和底边之间。如果line-height小于font的高度,这就不重要了。所以,外边缘就是图中的红线。

    inline元素的基线是字符所在的位置。就是图中的蓝线。粗略地说,就是字体高度的中间的下方。

    • inline-block元素

    元素盒子模型:红线外边距margin黄色:border绿色:padding蓝色:内容区域蓝线:inline-block元素的基线

    inline-block元素的外边缘是它的margin的顶边和底边,就是上图中的红线。

    inline-block元素的baseline依赖于元素是否包含处于在正常流中的内容

    inline-block元素中一个字符c

    inline-block元素的baseline为正常流中的

    最后一个内容元素的baseline

    inline-block元素中一个字符c,且overflow: hidden

    inline-block元素的baseline为盒子margin的底边

    inline-block元素中没有内容,但是为内容区域设置了宽高

    inline-block元素的baseline为盒子margin的底边

    • line盒子

    text盒子在line盒子中,它的顶边和底边由图中绿色标识。这个text盒子可以看作是一个line盒子中没有任何布局的inline元素。它的高度与父元素的font-size高度对应。因此,text盒子就是包含line盒子中未格式化的文本。也就是图中的绿色部分。因为,text盒子与baseline是绑定在一起,当baseline移动时它也会随着移动。

    对文本元素用灰色进行标亮

    line盒子顶边与最上面元素的顶边一致,line盒子底边与最下面元素的底边一致。它是由红线标识。

    line盒子的基线由蓝线标识。因为line盒子的基线是不可见的,可能不是很明显看到baseline在哪。但是,你可以在line的开头添加一个字符,比如图中的X,如果这个元素没有用任何方法布局,那么它默认在baseline上

    CSS 2.1 does not define the position of the line box's baseline.

    这可能是最令人疑惑的部分。这意味着,baseline被放置在需要满足其它条件如vertical-align以及最小化line盒子的高度。

    总结两点

    • line盒子,它是垂直布局发生的位置。它有baseline,text盒子,顶边,底边
    • inline级元素。它们是被布局的对象。它们有baseline,顶边和底边(font-size)

    三、vertical-align的值

    vertical-align不同的设置值相对于不同的元素

    默认值为baseline

    • 根据line盒子的baseline分布元素的baseline

    baseline sub super <percentage> <length>
    与line盒子baseline重合 line盒子baseline下 line盒子baseline上 相对于line-height的大小 绝对长度
    • 根据line盒子的baseline分布元素的外边缘

    middle:元素顶边、底边的中点是在(line盒子baseline+X高度一半)位置

    • 根据line盒子的text盒子分布元素的外边缘

    text-top:元素的顶边与line盒子的text盒子的顶边重合

    text-bottome:元素的底边是line盒子的text盒子的底边重合

    • 根据line盒子的外边缘分布元素的外边缘

    top:元素的顶边和line盒子的顶边重合

    bottom:元素的底边和line盒子的底边重合

     四、为什么vertical-align以这种方式来呈现?(几个实例)

    • 让一个icon和文本都垂直居中

    <!-- left mark-up -->
    <span class="icon middle"></span>
    Centered?
    <!-- right mark-up -->
    <span class="icon middle"></span>
    <span class="middle">Centered!</span>
    
    <style type="text/css">
      .icon   { display: inline-block;
                /* size, color, etc. */ }
      .middle { vertical-align: middle; }
    </style>
    View Code

    Centered?  没有设置样式,默认在基线上

    因为取的是小写字母x的高度,而C是大写,

    所以Centered?看起来并没有垂直居中

    对Centered!设置垂直居中
    • line盒子基线移动

    为了满足vertical-align的布局设置,line盒子的基线会自动发生移动

      • 情形一

    <!-- left mark-up -->
    <span class="tall-box text-bottom"></span>
    <span class="short-box"></span>
    <!-- right mark-up -->
    <span class="tall-box text-top"></span>
    <span class="short-box"></span>
    <style type="text/css">
      .tall-box,
      .short-box   { display: inline-block;
                    /* size, color, etc. */ }
    
      .text-bottom { vertical-align: text-bottom; }
      .text-top    { vertical-align: text-top; }
    </style>
    View Code

    两个元素一高一矮,矮的不设置分布,默认在baseline上

    高的设置text-bottom

    两个元素一高一矮,矮的不设置分布,

    默认在baseline上

    高的设置text-top,

    而text盒子是在baseline周围,

    为了让高的能实现text-top布局,

    所以需要让baseline上移

      • 情形二
    <!-- left mark-up -->
    <span class="tall-box bottom"></span>
    <span class="short-box"></span>
    <!-- right mark-up -->
    <span class="tall-box top"></span>
    <span class="short-box"></span>
    <style type="text/css">
      .tall-box,
      .short-box { display: inline-block;
                   /* size, color, etc. */ }
      .bottom    { vertical-align: bottom; }
      .top       { vertical-align: top; }
    </style>
    View Code
    高:vertical-align: top   矮:默认

    高:vertical-align: bottom  矮:默认

    虽然设置的是相对于line盒子的top,

    基线也会上移









      • 情形三
    <!-- left mark-up -->
    <span class="tall-box text-bottom"></span>
    <span class="tall-box text-top"></span>
    
    <!-- mark-up in the middle -->
    <span class="tall-box text-bottom"></span>
    <span class="tall-box text-top"></span>
    <span class="tall-box middle"></span>
    
    <!-- right mark-up -->
    <span class="tall-box text-bottom"></span>
    <span class="tall-box text-top"></span>
    <span class="tall-box text-100up"></span>
    
    <style type="text/css">
      .tall-box    { display: inline-block;
                     /* size, color, etc. */ }
    
      .middle      { vertical-align: middle; }
      .text-top    { vertical-align: text-top; }
      .text-bottom { vertical-align: text-bottom; }
      .text-100up  { vertical-align: 100%; }
    </style>
    View Code
     

    两个较高的元素,

    一个text-top,一个text-bottom

    增加第三个元素,设置为middle

    该元素没有超过line盒子的边界,故

    对baseline位置和line盒子高度没有影响

    增加第三个元素,设置为vertical-align: 100%

    左图是原文的,右图是自己实现的,好像有点不太一样

    黄色部分元素x的基线应该在line盒子基线上line盒子高度的100%

    • inline级元素底部有小间隙

    比如布局一个li列表,这是由于baseline底部会留一些空间来放置文本的下行部分

    <ul>
      <li class="box"></li>
      <li class="box"></li>
      <li class="box"></li>
    </ul>
    
    <style type="text/css">
      .box { display: inline-block;
             /* size, color, etc. */ }
    </style>
    View Code

    解决方案:让这些元素设置成vertical-align

    <ul>
      <li class="box middle"></li>
      <li class="box middle"></li>
      <li class="box middle"></li>
    </ul>
    
    <style type="text/css">
      .box    { display: inline-block;
                /* size, color, etc. */ }
      .middle { vertical-align: middle; }
    </style>
    View Code

    这种情形不会在有文本内容的inline-block元素中发生,因为内容已经把baseline移到上方

    • inline级元素水平方向的间隙会破坏布局

    两个inline-block宽度都设置为50%,且html中有换行符,那么导致这两个元素间会有一个间隙,一行放不下它们,第二个元素会被放在第二行

    <!-- left mark-up -->
    <div class="half">50% wide</div>
    <div class="half">50% wide... and in next line</div>
    
    <!-- right mark-up -->
       <div class="half">50% wide</div><!--
    --><div class="half">50% wide</div>
    
    <style type="text/css">
      .half { display: inline-block;
              width: 50%; }
    </style>
    View Code
    • span和input

    <div style="height: 40px;">
    x
        <span style="border: 1px solid red; display: inline-block; height:  100%;   50px;"></span>
        <input type="text" style="height:  100%; border: 1px solid green;">
    </div>

    五、让vertical-align不再神秘!

    当vertical-align并不如你所相像地那样表现,那么请考虑以下两个问题:

    • line盒子的baseline、顶边、底边在哪?
    • 内联级元素的baseline、顶边、底边在哪?

     我的个人总结(非翻译)

    • 文本只根据line-height来进行布局:垂直居中(父子中大的line-height)
    • line-height和height总是取较大的值
    • 文本的line-height和height再小也会让文本显示
    • 先根据line-height进行布局,height变到很小的时候,文本的下方区域会变小,直到文本底边,上方区域不变
  • 相关阅读:
    Mysql有什么办法解决主备延迟的引起的过期读问题?
    jdk 8 交集 差集
    【立flag】_(:з」∠)_
    Linux基础01 虚拟机安装操作系统,网络类型(网口),网段, 分区,分配网络, KDUMP,网络配置, 快照, 克隆, Xshell优化, Linux历史
    oracle(enquences & latches )lock (oracle 锁大全)
    oracle 密码详解以及破解
    oracle 大表在线删除列操作(alter table table_name set unused )
    MacOs 使用 github 个人令牌(Personal access token)
    web网站在线安全扫描
    vue 实现快捷键录入功能
  • 原文地址:https://www.cnblogs.com/coolqiyu/p/7292564.html
Copyright © 2020-2023  润新知