zoukankan      html  css  js  c++  java
  • 【翻译】关于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变到很小的时候,文本的下方区域会变小,直到文本底边,上方区域不变
  • 相关阅读:
    IO 单个文件的多线程拷贝
    day30 进程 同步 异步 阻塞 非阻塞 并发 并行 创建进程 守护进程 僵尸进程与孤儿进程 互斥锁
    day31 进程间通讯,线程
    d29天 上传电影练习 UDP使用 ScketServer模块
    d28 scoket套接字 struct模块
    d27网络编程
    d24 反射,元类
    d23 多态,oop中常用的内置函数 类中常用内置函数
    d22 封装 property装饰器 接口 抽象类 鸭子类型
    d21天 继承
  • 原文地址:https://www.cnblogs.com/coolqiyu/p/7292564.html
Copyright © 2011-2022 走看看