V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Can I use?
http://caniuse.com/
Less
http://lesscss.org
Cool Libraries
Bootstrap from Twitter
Jetstrap
hblevins
V2EX  ›  CSS

下面的代码中,如何解释 div 的高度?

  •  
  •   hblevins · 66 天前 · 773 次点击
    这是一个创建于 66 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我的理解是 span 的 line-height 设置为 0 ,那么它所在行的行框的高度就变为 0 ,无法撑起 div 的高度,因此 div 的高度因此为 0 。但实际上,div 的高度为 27, 应该如何解释 div 的高度呢?

    两个现象:
    1 、当 div 和 span 的 font-size 设置为相同值时,div 的高度会为 0 (这又是为什么呢?)
    2 、如果去掉,那么 div 的高度为 0. 这可能是因为页面上没有<!DOCTYPE html>,浏览器将会以怪异模式的方式去渲染。

    代码地址: https://jsbin.com/ziyimaleqe/edit?html,output

    div-height.png

    4 条回复    2024-08-06 18:16:30 +08:00
    jionJack
        1
    jionJack  
       66 天前
    你 div 又没设置高度,span 也没样式,
    chnwillliu
        2
    chnwillliu  
       36 天前
    尝试解释一下。涉及概念,字体的 baseline ,上升线 ascender, 下降线 descender, em size, CSS line-height 和 inline formating context 的工作原理。



    首先,font-size 设定的是 em size ,根据字体文件里的 unitPerEm 和 ascender descender 数据,就能计算出当前 font-size 下上升线和下降线相对 baseline 的距离,这个就是 inline boxes 的 content area 的高度。字体不一样上升线下降线的数据就不一样。

    CSS line-height 的工作方式是添加额外的 leading 到上升线和下降线的两侧,使得新的调整后的上升线和下降线之间的间距刚好达到 CSS line-height 的值。后文上升线和下降线皆指 line-height 值调整后的上升线和下降线。

    block container 的高度由内部的行盒( line box )堆叠而成,对于每一行,高度又是怎么计算呢?答案就是按行盒的 baseline 对齐行盒内所有的行内盒子( inline boxes )的 baseline ,从最低的下降线到最高的上升线就是行盒的高度。行盒本身有从行盒创建者那里得来的 font-size ,font-family 和 line-height ,从而得出 baseline ,ascender, descender 三条线,行内盒子也可能有不同的 baseline ,ascender, descender 。vertical-align 调整的其实是 baseline 偏移量,从而其实也会影响 line box 最终的高度。

    line-height:0 会导致什么? line-height:0 会使得调整后的上升线和下降线重合到中间的位置,一般字体而言基本会比 baseline 高一点。如何再叠加 font-size:0 才会出现上升线,下降线和 baseline 三线合一。

    okay ,现在解释:

    现象#1 div{font-size:0;line-height:0} span{line-height:0;font-size:100px} div 高度由来。

    行盒三线合一,唯一的 span 创建的 inline box 上升线和下降线重合到中间的位置,距离 baseline 为原字体的 ascender - ( ascender + descender )/ 2 。baseline 对齐,行盒包住所有的上升线和下降线,因此高度就是 span 字体的 ascender - ( ascender + descender )/ 2 ,再根据 font-size 和字体的 unitPerEm 即可计算出 CSS px 值。

    拿 Times New Roma 举例,ascender 1825 descender -443 unitPerEm 2048 (1825-(1825+443)/2)/2048*100=33.7

    现象#2 div{line-height:0} span{line-height:0;font-size:100px} Times New Roma 字体下 27px 高度

    行盒 font-size 继承自 body 16px ,上升线和下降线重合,位与 baseline 上方的高度是 (1825-(1825+443)/2)/2048*16=5.4px ,由#1 得知 span 的行内盒子上升线和下降线位与 baseline 上方 33.7px 处重合,因此行盒高度 33.7-5.4=28.3px

    现象#3 div{font-size:100px;line-height:0} span{line-height:0;font-size:100px} div 高度 0

    行盒与 span 的行内盒子完全一致,上升线和下降线位与 baseline 上方 33.7px 处重合,baseline 一对齐,上升线和下降线也跟着对齐了,最终行盒包裹所有的上升线和下降线,高度依然为 0.
    chnwillliu
        3
    chnwillliu  
       36 天前 via Android
    更正 div{line-height:0} span{line-height:0;font-size:100px} Times New Roma 字体下 div 高度测得是 28px 高度。
    chnwillliu
        4
    chnwillliu  
       32 天前 via Android
    再更正,其实所谓行盒自身的三线,更准确的说法是行盒会创建一个零宽度的 strut 盒子,这个盒子从行盒那里继承 font size font family 和 line-height ,这个盒子和其他 inline boxes 一起按 baseline 对齐。

    这个盒子也就是著名的幽灵空白节点。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2185 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 01:51 · PVG 09:51 · LAX 18:51 · JFK 21:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.