CSS中l(wèi)ine-height與vertical-align

參考文章:
深入了解CSS的line-height屬性
Vertical-Align: 你需要知道的所有事【譯】
Vertical-Align: All You Need To Know

1榕莺、什么是行間距或者行高(line-height)

line-height是指文本行基線間的垂直距離增炭。

1.1攻臀、頂線菠净,中線祝沸,基線使套,底線

從上到下分別是頂線病往,中線,基線冤议,底線斟薇。vertical-align的四個(gè)屬性top,middle,baseline,bottom就是與這四條線有關(guān)。

1.2恕酸、行高堪滨,行距,半行距

  • 行高是指上下文本行基線間的垂直距離蕊温。(上圖中兩條紅線間的垂直距離)
  • 行距是指一行底線到下一行頂線的垂直距離袱箱。(第一條粉線和第二條綠線間的垂直距離)
  • 半行距就是行距/2。(圖中可以看出义矛,半行距=(行高-字體size)/2 )


1.3发笔、內(nèi)容區(qū),行內(nèi)框凉翻,行框

  • 內(nèi)容區(qū):頂線和底線包裹的區(qū)域(字體的size)
  • 行內(nèi)框:在沒(méi)有其他因素影響的時(shí)候(padding等)了讨,行內(nèi)框等于內(nèi)容區(qū)。而設(shè)定行高時(shí)行內(nèi)框高度不變制轰,半行距分別增加/減少到內(nèi)容區(qū)的上下兩邊(深藍(lán)色區(qū)域)行框(line box)前计。(字體size不變,修改行高就是修改行距)
  • 行框:行框高度等于本行內(nèi)所有元素中行內(nèi)框最大的值(以行高值最大的行內(nèi)框?yàn)榛鶞?zhǔn)垃杖,其他行內(nèi)框采用自己的對(duì)齊方式向基準(zhǔn)對(duì)齊男杈,最終計(jì)算行框的高度),當(dāng)有多行內(nèi)容時(shí)调俘,每行都會(huì)有自己的行框伶棒。

1.4、line-height的設(shè)置

百分比方式設(shè)置

<body>
  121212
  <p>121212</p>
</body>
body{
  font-size:16px;
  line-height:120%;
}
p{
  font-size:32px;
}

line-height的百分比(120%)和body的字體大胁士狻(16px)苞冯,被用來(lái)計(jì)算(16*120=19.2),這個(gè)值會(huì)被層疊下去的元素所繼承侧巨。


補(bǔ)充

p{
  font-size:32px;
  line-height:60px;
  padding:10px
}

最終盒模型

盒模型中,內(nèi)容(不是上文說(shuō)的內(nèi)容區(qū)鞭达,上文的內(nèi)容區(qū)是頂線與底線間的區(qū)域)的高度等于line-height的值司忱。為什么會(huì)有margin?瀏覽器默認(rèn)P的上下margin是1em,設(shè)置了P的font-size是32px,所以1em=32px畴蹭。上下margin就是32px坦仍。

長(zhǎng)度方式(px)設(shè)置

<body>
  121212
  <p>121212</p>
</body>
body{
  font-size:16px;
  line-height:20px;
}
p{
  font-size:32px;
}

值normal

<body>
  121212
  <p>121212</p>
</body>
body{
  font-size:16px;
  line-height:normal;
}
p{
  font-size:32px;
}
body

body的line的line-height是22px,所以normal等于1.375

p的line-height:32px*1.375=44px(normal并不是精確的等于1.375)

純數(shù)字
就是將normal改為一個(gè)想要的準(zhǔn)確數(shù)字最铁。

1.5艘虎、各種BOX

<body>
  <p>這個(gè)<em>強(qiáng)調(diào)</em> 元素為行內(nèi)元素</p>
</body>
body{
  font-size:16px;
  line-height:1.5;
}
p{
  font-size:32px;
  padding:10px;
}

containing box
p就是一個(gè)containing box,包含了其他boxs朝抖。

inline box
在段落內(nèi),有一系列的inline box,inline box不會(huì)讓內(nèi)容成塊顯示梳玫,而是排成一行爹梁。“強(qiáng)調(diào)”是一種inline box,“這個(gè)”提澎,“元素為行內(nèi)元素”為一種匿名inline box姚垃。

line box
多個(gè)inline box組成line box,多個(gè)line box組成containing box盼忌。

Content Area
Content Area是圍繞著文字的一種看不見的box,高度取決與font-size

inline box與line-height
font-size:32px积糯,line-height:48px,行間距=48px-32px=16px谦纱,半行間距=8px看成。
半行間距會(huì)用在Content Area的頂部和底部。


這里inline box的高度就是line-height跨嘉。inline box包著Content Area

但是川慌,當(dāng)line-height小于font-size。line box的高度還是line-height,所以line-box的高度小于Content Area的高度偿荷,Content Area會(huì)溢出line-box窘游。

inline box 與line box
line box的高度取決于他內(nèi)部最高的inline box。

2跳纳、vertical-align

vertical-align是用來(lái)對(duì)齊內(nèi)聯(lián)級(jí)元素的忍饰。設(shè)置為以下display屬性的元素,它們都被認(rèn)為屬于內(nèi)聯(lián)級(jí)元素寺庄。inline艾蓝、inline-block or **inline-table **(本文中不涉及此種情況):

inline內(nèi)聯(lián)元素基本上是包裹文本的標(biāo)簽。

inline-block內(nèi)聯(lián)塊元素則如它們的名字所示:擁有內(nèi)聯(lián)特性的塊元素斗塘。他們可以有width和height(可能是由自己的內(nèi)容定義)赢织,以及padding、border和margin馍盟。

內(nèi)聯(lián)級(jí)元素彼此緊挨著放在一行中于置。一旦有更多的元素被放置到當(dāng)前行中,一個(gè)新的行將會(huì)在它下面創(chuàng)建贞岭。所有這些行有所謂的“行框”八毯,行框中包含所有的內(nèi)容。不同大小的內(nèi)容意味著不同高度的行框瞄桨。在下面的插圖中话速,行框的頂部和底部都是用紅線表示的。


在行框中芯侥,元素的vertical-align屬性是負(fù)責(zé)垂直對(duì)齊的泊交。那么乳讥,到底元素垂直對(duì)齊的參照物是什么?

參照物:父元素的基線和外邊緣
看看元素的基線和行框的外觀:
inline元素

三行并排的文本廓俭。行框的頂部和底部邊緣用紅線表示云石,字體的高度由綠線表示,基線由一條藍(lán)線表示白指。在左邊留晚,有一個(gè)line-height設(shè)置為與字體font-size大小相同高度的文本,綠線和紅線重疊在一條線上告嘲。在中間错维,line-height是字體的兩倍大。在右邊橄唬,line-height是字體大小的一半大赋焕。

內(nèi)聯(lián)元素(display:inline)的外邊緣與其行高的頂部和底部邊緣對(duì)齊,行高可以小于字體的高度仰楚。所以隆判,行框就是上面的圖中的紅線。

內(nèi)聯(lián)元素的基線是字符放置的位置線(字母x底部所在的水平線)僧界,即圖中的藍(lán)線侨嘀。粗略地說(shuō),基線是在字體1/2高度的下面的某個(gè)地方捂襟。

inline-block元素
inline-block因?yàn)橐呀?jīng)有寬和高咬腕,可能存在多行,每行都有自己的基線和行框葬荷,所以會(huì)比較特殊涨共。

上圖中,最外層是div宠漩,里面分別是三個(gè)inline-block的span举反,黃色為border,綠色為padding扒吁,藍(lán)色為content area(一個(gè)span火鼻,其中有一個(gè)字母“C”)。左邊的inline-block的span的內(nèi)容(span)是一個(gè)正常文檔流元素雕崩。中間的inline-block的span還額外加了overflow: hidden魁索。右邊的inline-block的span包含一個(gè)流外的span(但內(nèi)容區(qū)域有一個(gè)高度)(譯者注:流內(nèi)的元素必須是普通文檔流(normal flow)中的元素,流外的元素必須是浮動(dòng)或絕對(duì)定位的元素以及根元素晨逝。)。藍(lán)線為每個(gè)inline-block的span的基線懦铺。內(nèi)聯(lián)塊元素的外邊緣是其margin框的頂部和底部邊緣捉貌,即圖中的紅線。

內(nèi)聯(lián)塊元素(上圖三個(gè)inline-block的span)的基線取決它包含的內(nèi)容是否在文檔流中:

  • 在流內(nèi)內(nèi)容的情況下,內(nèi)聯(lián)塊元素的基線是正常流中最后一個(gè)內(nèi)容元素的基線(左邊的例子)趁窃。對(duì)于這最后一個(gè)元素牧挣,它的基線是根據(jù)它自己的規(guī)則找到的。
<div class="demo1">
  x<span>
    x<span style="display:inline-block;height:30px;width:100px;background-color:blue">x</span>
    x
  </span>
</div>
.demo1 span{
  display:inline-block;
  background-color:silver;
  height:90px;
  
}

灰色背景的元素內(nèi)部有三個(gè)子元素醒陆,兩個(gè)“x”,一個(gè)span瀑构。元素的基線就是最后一個(gè)正常流元素(“x”)的基線。
修改元素的長(zhǎng)度刨摩,使其內(nèi)容出現(xiàn)多行:

最外面的X怎么也跟著移動(dòng)了寺晌?這涉及行框基線的移動(dòng),下文細(xì)說(shuō)澡刹。

  • 在流內(nèi)內(nèi)容但內(nèi)聯(lián)塊元素有overflow:hidden屬性的情況下呻征,基線是內(nèi)聯(lián)塊元素margin框的底部邊緣(例如在中間的圖)。
    修改上面的例子樣式:
.demo1>span{
  display:inline-block;
  background-color:silver;
  height:90px;
  width:100px;
  margin:10px;
  overflow:hidden;
}


通過(guò)最外面的x大致知道行框的基線位置罢浇,就是內(nèi)聯(lián)塊元素的下外邊距的地方陆赋,也是內(nèi)聯(lián)塊元素元素的基線位置。
一開始此處有疑惑:內(nèi)聯(lián)塊元素元素的基線跑到了下外邊距處嚷闭,那么元素里面的內(nèi)容不應(yīng)該以這條基線做定位嗎攒岛?群里問(wèn)了大佬,內(nèi)聯(lián)塊元素已經(jīng)設(shè)了寬高胞锰,可能有多行(即使只有一行)灾锯,每行有各自的行框,然后又根據(jù)規(guī)則定位了胜蛉,跟內(nèi)聯(lián)塊元素的基線已經(jīng)沒(méi)有關(guān)系挠进。

  • 在流外內(nèi)容的情況下,基線是內(nèi)聯(lián)塊元素margin框的底部邊緣(例如在右邊)誊册。
<div class="demo1">
  x<span>
  <span style="display:inline-block;height:30px;width:100px;background-color:blue;">x</span>
  </span>
</div>
.demo1>span{
  display:inline-block;
  background-color:silver;
  height:90px;
  width:100px;
}

加上浮動(dòng)

<div class="demo1">
  x<span>
  <span style="display:inline-block;height:30px;width:100px;background-color:blue;float:left">x</span>
  </span>
</div>

行框的基線是可變的
當(dāng)使用vertical-align時(shí)领突,基線放置在哪里可能是最令人疑惑的部分。它需要滿足vertical-align的值和行框的高度等所有條件案怯【基線的位置猶如是方程中的一個(gè)自由參數(shù)。

行框的基線是看不見的嘲碱,但你可以使它很容易看到金砍。只要在文本行的開頭添加一個(gè)字符,像我增加了一個(gè)“X”的字母麦锯。如果這個(gè)字符不以任何方式對(duì)齊恕稠,它將默認(rèn)地坐在基線上。

圍繞著行框的基線的部分(綠線)扶欣,我們可以稱其為文本框鹅巍。文本框可以簡(jiǎn)單地被認(rèn)為是行框內(nèi)的內(nèi)聯(lián)元素千扶,沒(méi)有任何對(duì)齊。文本框的高度等于它的父元素的字體大小骆捧。因此澎羞,文本框只圍住了行框內(nèi)的無(wú)格式文本。由于這個(gè)文本框是綁在基線上的敛苇,當(dāng)基線移動(dòng)時(shí)它將移動(dòng)妆绞。(注:此文本框在W3C規(guī)范中稱為“strut(支柱)”)

vertical-align的值
1)將元素的基線,參照父元素的基線對(duì)齊

baseline:元素的基線與父元素的基線對(duì)齊枫攀。

sub:元素的基線偏移到父元素的基線之下括饶。

sup:元素的基線偏移到父元素的基線之上。

<percentage>:元素的基線相對(duì)于父元素的基線偏移了一個(gè)百分比(該百分比是對(duì)比元素自身的line-height計(jì)算得出)脓豪。

<length>:元素的基線相對(duì)于父元素的基線偏移了一個(gè)絕對(duì)長(zhǎng)度巷帝。

2)將元素的中心點(diǎn),參照父元素的基線對(duì)齊

middle:將元素的頂部和底部之間的中心點(diǎn)扫夜,對(duì)齊父元素的基線之上x-height的1/2之處(x-height為字母x的字符高度)楞泼。

3)將元素的外邊緣,參照父元素的文本框?qū)R

text-top:將元素的頂部邊緣笤闯,對(duì)齊到父元素的文本框的頂部邊緣堕阔。

text-bottom:將元素的底部邊緣,對(duì)齊到父元素的文本框的底部邊緣颗味。

4)將元素的外邊緣超陆,參照父元素行框的外邊緣對(duì)齊

top:元素的頂部邊緣對(duì)齊到父元素的頂部邊緣。

bottom:元素的底部邊緣對(duì)齊到父元素的底部邊緣浦马。

基線的移動(dòng)
如果一行中有一個(gè)高個(gè)的元素占據(jù)了整行的高度时呀,那么vertical-align對(duì)它沒(méi)有影響。它的頂部和底部沒(méi)有空間讓它移動(dòng)晶默。為了滿足行框基線的對(duì)齊方式谨娜,行框的基線必須移動(dòng)。矮個(gè)元素設(shè)置了vertical-align: baseline磺陡。在左邊趴梢,高個(gè)元素設(shè)置了vertical-align: text-bottom。在右邊币他,高個(gè)元素設(shè)置了vertical-align: text-top坞靶。你可以看到右邊的基線跳起來(lái)了。

(左)將兩個(gè)元素放在一行中并設(shè)置vertical-align 蝴悉,它們會(huì)使得行框的基線移動(dòng)到符合它倆的對(duì)齊規(guī)則之處彰阴,然后行框的高度也會(huì)隨之調(diào)整。(中)添加第三個(gè)元素拍冠,不超越行框的邊緣尿这,既不影響行框的高度廉丽,也不影響基線的位置。(右)添加第三個(gè)元素妻味,如果它超出了行框的邊緣,行框的高度和基線調(diào)整欣福。在這種情況下责球,我們的前兩個(gè)元素也會(huì)跟著發(fā)生變化。

內(nèi)聯(lián)級(jí)元素底部的小間隙

列表項(xiàng)坐在基線上拓劝。下面的一點(diǎn)空間雏逾,是文本的基線以下預(yù)留的depth(在W3C規(guī)范中,一個(gè)字體的基線以上稱為characteristic height郑临,基線以下稱為depth)栖博。想要去掉這個(gè)depth空隙,有解決的辦法嗎厢洞?只要移動(dòng)基線的位置就可以仇让,例如通過(guò)設(shè)置列表項(xiàng)目vertical-align: middle

水平垂直居中

<div class="box">
        <div class="content">
          自適應(yīng)垂直居中
        </div>
</div>
html{
  height:100%;
}
body{   
   height: 100%;  
   width: 100%;  
}
.box{
   display:inline-block;
   text-align: center;
   width:50%;
   height:50%;
   background-color:#e1e3cd;
   overflow:hidden;
}
.box:after{
    content:"";
    display:inline-block;
    height:100%;
    vertical-align:middle;
}
.content{
    vertical-align:middle;
    background-color:silver;
    display: inline-block;
    width: 50%;
    height:50%;
}

要將content水平垂直居中定位在box里,利用vertical-align是其中一種方法躺翻。原理是:vertical-align:middle(將元素的頂部和底部之間的中心點(diǎn)丧叽,對(duì)齊父元素的基線之上x-height的1/2之處(x-height為字母x的字符高度)。)公你,content肯定是要垂直居中的迂尝,那只能修改行框的基線位置(注意:不是修改box的基線,box具有寬高剪芥,它里面的內(nèi)容可能會(huì)有多行垄开,每行有各自的行框,box的基線已經(jīng)不會(huì)影響內(nèi)容的布局粗俱,但是box的基線還是會(huì)受里面內(nèi)容的影響(內(nèi)聯(lián)塊元素的基線是正常流中最后一個(gè)內(nèi)容元素的基線))说榆,使其位于box的垂直中心位置。修改行框的基線寸认,只要在box內(nèi)加一個(gè)高度為100%的空元素签财,然后設(shè)置vertical-align:middle偏塞,添加的元素已經(jīng)占滿整個(gè)行框高度唱蒸,而只要移動(dòng)行框的基線,就可以滿足定位規(guī)則灸叼,所以行框的基線就被移動(dòng)到box垂直中心位置神汹。content再按規(guī)則對(duì)齊到行框基線上就可以了滔以。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市氓拼,隨后出現(xiàn)的幾起案子你画,更是在濱河造成了極大的恐慌,老刑警劉巖桃漾,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件坏匪,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡撬统,警方通過(guò)查閱死者的電腦和手機(jī)适滓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)恋追,“玉大人凭迹,你說(shuō)我怎么就攤上這事】啻眩” “怎么了蕊苗?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)沿彭。 經(jīng)常有香客問(wèn)我朽砰,道長(zhǎng),這世上最難降的妖魔是什么喉刘? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任瞧柔,我火速辦了婚禮,結(jié)果婚禮上睦裳,老公的妹妹穿的比我還像新娘造锅。我一直安慰自己,他們只是感情好廉邑,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布哥蔚。 她就那樣靜靜地躺著,像睡著了一般蛛蒙。 火紅的嫁衣襯著肌膚如雪糙箍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天牵祟,我揣著相機(jī)與錄音深夯,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛咕晋,可吹牛的內(nèi)容都是我干的雹拄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼掌呜,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼滓玖!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起质蕉,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤呢撞,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后饰剥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡摧阅,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年汰蓉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片棒卷。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡顾孽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出比规,到底是詐尸還是另有隱情若厚,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布蜒什,位于F島的核電站测秸,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏灾常。R本人自食惡果不足惜霎冯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望钞瀑。 院中可真熱鬧沈撞,春花似錦、人聲如沸雕什。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)贷岸。三九已至壹士,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間偿警,已是汗流浹背墓卦。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留户敬,地道東北人落剪。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓睁本,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親忠怖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子呢堰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 問(wèn)答題47 /72 常見瀏覽器兼容性問(wèn)題與解決方案? 參考答案 (1)瀏覽器兼容問(wèn)題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 13,756評(píng)論 1 92
  • 有些東西我們經(jīng)常用凡泣,但是我們卻并不了解它的原理枉疼,所以一旦換了場(chǎng)景,好多東西就不知道該怎么用了鞋拟。最近一直很糾結(jié)ver...
    朱小維閱讀 4,946評(píng)論 8 34
  • 移動(dòng)開發(fā)基本知識(shí)點(diǎn) 一.使用rem作為單位 html { font-size: 100px; } @media(m...
    橫沖直撞666閱讀 3,482評(píng)論 0 6
  • H5移動(dòng)端知識(shí)點(diǎn)總結(jié) 閱讀目錄 移動(dòng)開發(fā)基本知識(shí)點(diǎn) calc基本用法 box-sizing的理解及使用 理解dis...
    Mx勇閱讀 4,518評(píng)論 0 26
  • 以下文章是我在網(wǎng)上收集的內(nèi)容骂维,為了記錄自己的學(xué)習(xí)以及為了以后不到處找而記錄下來(lái),如果對(duì)你有用贺纲,請(qǐng)感謝寫這些文章的前...
    DCbryant閱讀 941評(píng)論 0 2