CSS實用技巧(中)


前言

我們經常使用CSS,但是卻不怎么了解CSS,本文主要對vertical-alignBFCposition中開發過程不怎么注意的特性進行簡要總結,從本文中,你將了解到以下內容:

  • vertical-align為何時靈時不靈
  • BFC是什么?有何作用
  • 絕對定位的奇淫技巧

CSS特性

vertical-align為什么時靈時不靈

生效條件

只能應用在displayinlineinline-blockinline-tabletable-cell上。

有個高頻面試題,“如何使一個不定寬高div垂直水平居中?”,有的萌新竟然回答用vertical-align: middle。這個回答是減分的,至少在某種程度上給人一種感覺CSS基礎比較薄弱。

內聯元素垂直居中對齊

開發中會遇到用字幕x代替關閉icon,用...顯示溢出或者加載中。但是會發現字母x、省略號並沒有與文本垂直方向居中對齊,這是因為文本默認是基線對齊,x、省略號默認底部在基線處。如下圖所示:

如下,為文本對齊demo:

<div class="container">
  <span>你好,世界</span>
  <span class="more">...</span>
</div>

實際顯示效果如下:

如果要實現垂直居中,利用vertical-align,搭配line-height即可,vertical-align不僅可以設置middle/top/bottom/baseline...關鍵字,也可以設置常用的度量單位,正負值均可,使用比較靈活。為什么要給.more設置line-height屬性呢?其實是因為line-height屬性可以繼承,如果不縮小.more的行高,就會撐大父元素的尺寸。

<style>
  .container{
    font-size: 64px;
    line-height: 64px;
  }
  .more{
    line-height: 16px;
    vertical-align: 16px;
  }
</style>

BFC究竟有什么作用

什么是BFC

BFC全稱block formatting context,即“塊狀格式化上下文”,與外界元素相對獨立的一片區域,具有以下特性:

  • 計算BFC高度時,浮動元素也參與計算
  • 屬於同一BFC容器的元素垂直方向的margin會合並
  • BFC容器是獨立容器,不會影響外部元素的布局

利用BFC的特性,我們可以實現以下功能:

  1. 清除浮動
  2. 防止垂直方向margin合並
  3. 實現多欄彈性布局

BFC的生效條件

以下CSS屬性會觸發元素生成BFC結界:

  • 根元素(<html>
  • 浮動元素(元素的 float 不是 none
  • 絕對定位元素(元素的 positionabsolutefixed
  • 行內塊元素(元素的 displayinline-block
  • 表格單元格(元素的 displaytable-cellHTML表格單元格默認為該值)
  • 表格標題(元素的 displaytable-captionHTML表格標題默認為該值)
  • 匿名表格單元格元素(元素的 displaytabletable-rowtable-row-grouptable-header-grouptable-footer-group(分別- 是HTML tablerowtbodytheadtfoot 的默認屬性)或 inline-table
  • overflow 計算值(Computed)不為 visible 的塊元素
  • display 值為 flow-root 的元素
  • contain 值為 layoutcontentpaint 的元素
  • 彈性元素(displayflexinline-flex 元素的直接子元素)
  • 網格元素(displaygridinline-grid 元素的直接子元素)
  • 多列容器(元素的 column-countcolumn-width 不為 auto,包括 column-count 為 1)
  • column-spanall 的元素始終會創建一個新的BFc

BFC使用案例

  • 清除浮動
<style>
  .container{
    /* overflow: hidden; */
    /* position: absolute; */
    /* float: left; */
  }
  .left{
    float: left;
    width: 200px;
    height: 200px;
  }
</style>
<div class="container">
  <div class="left"></div>
</div>

以上代碼,container容器高度為0,因為子元素left浮動。我們只需要把container容器轉成BFC容器,即可清楚浮動,注釋的幾種方法都可以。

  • 防止垂直方向margin合並
<style>
  .blue, .red-inner {
    height: 50px;
    margin: 10px 0;
  }

  .blue {
    background: blue;
  }

  .red-outer {
    overflow: hidden;
    background: red;
  }
</style>
<div class="blue"></div>
<div class="red-outer">
  <div class="red-inner">red inner</div>
</div>
  • 自適應布局

左側固定,右側自適應。

<style>
  .left{
    height: 200px;
    width: 200px;
    float: left;
    background-color: burlywood;
  }
  .right{
    height: 200px;
    margin-left: 200px;
    background-color: cadetblue;
  }
</style>
<div class="container">
  <div class="left"></div>
  <div class="right"></div>
</div>

絕對定位還能玩出什么花樣

簡介

絕對定位使用場景非常多。絕對定位元素脫離文檔流,相對於最近的非 static 祖先元素定位,可以利用left/right/top/bottom定位元素位置。我們通常都是設置垂直方向與水平方向的的位置,如果四個方向都不設置或者四個方向都設置會出現什么彩蛋呢?下文會給出揭曉。

left/top/right/bottom都有值的定位

  • 當對立位置(leftrighttopbottom)都設置值且元素沒用固定寬高

此時元素的寬高是根據元素位置決定的,張鑫旭大佬在《CSS世界》中定義為格式化寬高,如下代碼,最終box-item的寬高計算為:width = 200 - 50 -50 = 100px;width = 200 - 50 -50 = 100px;

<style>
  .box{
    position: relative;
    width: 200px;
    height: 200px;
    margin: 50px;
    background-color: bisque;
  }
  .box-item{
    position: absolute;
    left: 50px;
    right: 50px;
    top: 50px;
    bottom: 50px;
    background-color: coral;
  }
</style>
 <div class="box">
    <div class="box-item"></div>
  </div>

這種行為特性對於我們做自適應布局非常有用,而且兼容性非常好,比如我們要做左側固定寬度,右側自適應,除了以上BFC的寫法,我們還可以采用以下方法:

<style>
  .container{
    position: absolute;
    top: 100px;
    bottom: 100px;
    left: 0;
    right: 0;
  }
  .left{
    position: absolute;
    top: 0;
    bottom: 0;
    width: 200px;
    background-color: burlywood;
  }
  .right{
    position: absolute;
    left: 200px;
    right: 0;
    top: 0;
    bottom: 0;
    background-color: cadetblue;
  }
</style>
<div class="container">
  <div class="left"></div>
  <div class="right"></div>
</div>
  • 當對立位置都設置了值且元素設置了固定寬高

這個時候你會發現,元素的寬高時以width/height為准,上述說的格式化寬度、高度並沒有生效。這是因為在高度計算過程中,元素的內部尺寸優先級大於外部尺寸,width/height影響的是元素內部尺寸,絕對定位影響的是外部尺寸,當元素絕對定位四個方向都設置值,此時外部尺寸會被內部尺寸覆蓋,導致實際元素寬度是width/height的值。

我們經常用margin: 0 auto;實現元素水平居中,但是不定寬高元素垂直水平居中就有些麻煩。但是有個神奇的現象,絕對定位配合margin: auto;,可以實現元素垂直水平居中,如下所示:

<style>
  .box{
    position: relative;
    width: 200px;
    height: 200px;
    margin: 50px;
    background-color: bisque;
  }
  .box-item{
    position: absolute;
    margin: auto;
    width: 50px;
    height: 50px;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    background-color: coral;
  }
</style>
<div class="box">
  <div class="box-item"></div>
</div>

出現這種現象是因為margin:auto本質上是平分元素剩余可用空間,塊級元素一般是水平方向自動充滿,垂直方向順序排列。平常我們用margin: 0 auto;之所以能夠使塊級元素水平居中,是因為水平方向元素存在剩余可用空間,而auto平分剩余可用空間,因此就產生居中效果。而垂直方向不存在剩余可用空間,因此無法垂直居中。
上述demobox-item之所以能夠垂直居中,得益於top/bottom設置了值,使元素產生高度100%的外部尺寸,而width/height固定元素的內部尺寸,使得 外部尺寸高度-內部尺寸高度=元素剩余可用空間高度,而auto等分剩余可用空間,可以使元素達到垂直居中效果。可以嘗試調整四個方向的值,看看box-item位置是怎么移動的。

無依賴的絕對定位

當絕對定位沒有設置四周定位尺寸時,會發生神奇的一幕,當前元素沒有相對於最近的非 static 祖先元素定位,而是在當前位置不變,並且當前元素脫離文檔流,不占據頁面空間。這個特性某些情況下非常有用,比如給box-card加一個圖標,借助無依賴定位 + padding/margin即可。寫法比較簡潔,建議嘗試一下。

小結

比起其他的開發語言,想要深入了解CSS,並不是一件容易事,大多數人都是停留在用的基礎上,知道這個屬性/方法,至於為什么會這樣了解較少。張鑫旭大佬CSS高度讓人嘆為觀止,繼續加油吧!!!

參考資料

  • CSS世界》
  • BFC


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM