《CSS世界》筆記三:內聯元素與對齊

上一篇:《CSS世界》筆記二:盒模型四你們族
下一篇:《CSS世界》筆記四:流的保護與破壞php

寫在前面

在頁面佈局中,內聯元素的垂直對齊是比較常見和基礎的佈局需求,可是咱們每每會由於垂直對齊中的1px,2px而頭疼不已。在這一篇博客(《css世界》第五章)中,張大大從深層次解釋了垂直對齊的原理,併爲內聯元素的垂直對齊提供了最佳實踐。css

1、基本概念

(1)基線(baseline):字母 x 的下邊緣(線)就是基線segmentfault

(2)x-height:小寫字母 x 的高度,術語描述就是基線和等分線(mean line)(也稱做中線,midline)之間的距離佈局

圖片描述

ascender height: 上行線高度
cap height: 大寫字母高度
median: 中線
descender height: 下行線高度

(3)middle線vertical-align:middle; 中middle指的是基線往上1/2 x-height高度(近似垂直居中)字體

(4)單位ex:CSS中的一個相對單位,指的是小寫字母 x 的高度
用法:不受字體和字號影響的內聯元素的垂直居中對齊效果url

.icon-arrow {
    display: inline-block;
    width: 20px;
    height: 1ex;
    background: url(arrow.png) no-repeat center;
}

2、行高line-height

對於非替換元素的純內聯元素,其可視高度徹底由 line-height 決定,通俗的說,純內聯元素的可視高度不受padding、margin、border 屬性的影響(這個咱們在 上一篇博客也有說明)

2.1 行距

一個公式:行距 = line-height - font-sizespa

上下行距分配規則:當行距爲偶數時,上下行距平分;當行距爲基數時,上邊距向上取整,下邊距向下取整;由於絕大多數字體都是偏下的code

圖片描述

2.2 line-height實現居中

誤區:並不是是line-height=height實現了單行文本的居中,line-height單獨做用便可實現orm

應用:利用line-height實現多行文本居中對齊blog

<div class="box">
    <div class="content">基於行高實現的...</div>
</div>

/* 近似居中對齊 */
.box {
    width: 280px;
    line-height: 120px;
    background-color: #f0f3f9;
    margin: auto;
}
.content {
    display: inline-block;
    line-height: 20px;
    margin: 0 20px;
    text-align: left;
    vertical-align: middle;
}

/* 絕對居中 */
.box {
    font-size: 0;
}
.box .content {
    font-size: initial;
}

原理:
近似居中:.box行高爲120,.content行高爲20,「幽靈空白節點」在.content前撐起了整個內容區域

絕對居中:在上面的基礎上,因爲middle(基線往上1/2 x-height高度)爲近似居中,因爲x-height受到font-size的影響,font-size爲0時可理解爲絕對居中

2.3 line-height的屬性值

line-height 的默認值是 normal,還支持數值、百分比值以及長度值

默認值normal在不一樣字體下的解析不一樣,所以在實際開發中通常會重置line-height

重點

假設 font-size = 14px;

數值:line-height: 1.5; ==> line-height 計算值是 1.5*14px=21px

百分比值:line-height: 150%; ==> line-height 計算值是 150%*14px=21px

長度值:line-height:21px

乍一看,彷佛 line-height:1.五、line-height:150%和 line-height:1.5em 這3種用法是如出一轍的,最終的行高大小都是和 font-size計算值,可是,實際上,line-height:1.5和另外兩個有一點兒不一樣,那就是 繼承細節有所差異若是使用數值做爲 line-height 的屬性值,那麼全部的子元素繼承的都是這個值;可是,若是使用百分比值或者長度值做爲屬性值,那麼全部 的子元素繼承的是最終的計算值

最佳實踐:基本上各大站點都是使用數值做爲全局的 line-height 值

3、vertical-align屬性(重點)

vertical-align 做用的前提條件是:只能應用於內聯元素以及display值爲table-cell的元素,注意,浮動和絕對定位會讓元素塊狀化也會使vertical-align失效

3.1 屬性值

四類屬性值:

  • 線類,如 baseline(默認值)、top、middle、bottom;
  • 文本類,如 text-top、text-bottom;
  • 上標下標類,如 sub、super;
  • 數值百分比類,如 20px、2em、20%等;
根據計算值的不一樣, 相對於基線往上或往下偏移,究竟是往上仍是往下取決於 vertical-align的計算值是正值仍是負值,若是是負值,往下偏移,若是是正值,往上偏移
vertical-align:baseline 等同於 vertical-align:0

vertical-align的百分比:margin 和 padding 是相對於寬度計算的,line-height 是相對於 font-size 計算的,而這裏的 vertical-align 屬性的百分比值則是相對於 line-height 的計算值計算的

3.2 vertical-align相關問題及解決

(1)案例一:任意一個塊級元素,裏面如有圖片,則塊級元素高度基本上都要比圖片的高度高

<div class="box">
    <img src="mm1.jpg">
</div>

.box {
    border: 1px solid #ccc;
}
.box > img {
    height: 96px;
}

圖片描述

緣由:間隙產生的三大元兇就是「幽靈空白節點」、line-heightvertical-align屬性;圖片前放置小寫的x,會發現圖片的基線是元素底部,與「幽靈空白節點」的基線(小寫x下邊緣)對齊;

解決方法

  1. 圖片塊狀化:能夠一口氣幹掉「幽靈空白節點」、line-heightvertical-align
  2. line-height:0;
  3. font-size: 0;
  4. 幹掉基線對齊:vertical-align的值爲top、middle、bottom中的任意一個都是能夠的

(2)案例二:使用text-align: justify;實現文字兩端對齊

text-align: justify;多用於文字排版,有一個很是重要的特性:不會對最後一行兩端對齊,所以單行文本時若要對齊須要人爲換行

補充text-align: justify;的用法案例:

<div class="form">
    <label for="name">姓名</label><input id="name" type="text"><br>
    <label for="tel">聯繫方式</label><input id="tel" type="text">
</div>

$font-size: 14px;
$line-height: 1.5;

.form {
    background-color: #eee;
    width: $font-size * 5 + 150px;
}
label {
    display: inline-block;
    text-align: justify;
    width: $font-size * 5;
    height: $font-size * $line-height;
    overflow: hidden;
    vertical-align: bottom;
    margin-right: 10px;
}
label:after {
    content: '';
    width: 100%;
    display: inline-block;
}

圖片描述

(3)案例三:使用text-align: justify;實現列表兩端對齊

爲了讓最後一行也兩端對齊,須要使用佔位元素實現換行

<div class="box">
    <img src="1.jpg" width="96">
    <img src="1.jpg" width="96">
    <img src="1.jpg" width="96">
    <img src="1.jpg" width="96">
    <i class="justify-fix"></i>
    <i class="justify-fix"></i>
    <i class="justify-fix"></i>
</div>

.box {
    text-align: justify;
}
.justify-fix {
    display: inline-block;
    width: 96px;
}

圖片描述

此時,元素底部有很大的間隙。產生的緣由無非是vertical-align,所以咱們會設置line-height:0;,可是並無真正解決問題,爲何?

一個 inline-block 元素,若是裏面沒有內聯元素,或者overflow不是visible,則該元素的基線就是其 margin 底邊緣;不然其基線就是元素裏面最後一行內聯元素的基線。
<span class="dib-baseline"></span>
<span class="dib-baseline">x-baseline</span>


.dib-baseline {
    display: inline-block;
    width: 150px; height: 150px;
    border: 1px solid #cad5eb;
    background-color: #f0f3f9;
}

實際展現以下圖所示:
圖片描述

最終解決:

  1. font-size: 0;
  2. line-height: 0; 且在佔位元素中添加空格<i class="justify-fix">&nbsp;</i>

4、擴展案例

4.1 基於20px圖標對齊最佳實踐

一個 inline-block 元素,若是裏面沒有內聯元素,或者 overflow 不是 visible, 則該元素的基線就是其 margin 底邊緣;不然其基線就是元素裏面最後一行內聯元素的基線。

基於上面的理論,有下面幾個要點:

  1. 圖標高度和當前行高都是 20px
  2. 圖標標籤裏面永遠有字符,能夠藉助:before 或:after 僞元素生成一個空格字符輕鬆搞定
  3. 圖標 CSS 不使用 overflow:hidden 保證基線爲裏面字符的基線,可是要讓裏面潛在的字符不可見
.icon {
    display: inline-block;
    width: 20px; height: 20px;
    background: url(sprite.png) no-repeat center;
    white-space: nowrap;
    letter-spacing: -1em;
    text-indent: -999em;
}
.icon:before {
    content: '\3000';
}

4.2 無兼容的水平垂直居中彈框

利用以前提到的絕對居中的知識vertical-align:middle; font-size:0;

<div class="container">
    <div class="dialog"></dialog>
</div>

.container {
    position: fixed;
    top: 0; right: 0; bottom: 0; left: 0;
    background-color: rgba(0,0,0,.5);
    text-align: center;
    font-size: 0;
    white-space: nowrap;
    overflow: auto;
}
.container:after {
    content: '';
    display: inline-block;
    height: 100%;
    vertical-align: middle;
}
.dialog {
    display: inline-block;
    vertical-align: middle;
    text-align: left;
    font-size: 14px;
    white-space: normal;
}

5、總結

  1. 內聯元素各類線 & 行高計算及分配規則;
  2. 利用line-height如何實現多文本居中 & line-height 各屬性值區別
  3. vertical-align取值對垂直對齊的影響及解決方式
  4. justify 實現文字兩端對齊和列表兩端對齊

上一篇:《CSS世界》筆記二:盒模型四你們族
下一篇:《CSS世界》筆記四:流的保護與破壞

相關文章
相關標籤/搜索