摘要:想寫出高效合理的布局,必須以深厚的基礎為前提。現在布局方式主要分為三種傳統布局方案等配合。彈性布局,實現方便,兼容性較好。在環境中的元素按照如下規則渲染和文檔流一樣,元素按照自己類型的布局特性從左到右,從上往下依次排列。
前端css布局知識繁雜,實現方式多種多樣。想寫出高效、合理的布局,必須以深厚的css基礎為前提。為了方便記憶和復習,將css布局要點記錄如下。內容較多,應用方面說的不太詳細,但都是很實用的點。
所謂布局,就是指將元素設置為我們想要的大小,放置于我們想要的位置,位置、尺寸是核心兩要素。這些元素其實就是一些方塊,頁面就是由各種方塊拼湊而成。現在布局方式主要分為三種:
傳統css布局方案(position,float,line-height等配合)。實現復雜,需要多種屬性配合使用,兼容性最好。
flex布局方案。彈性布局,實現方便,兼容性較好。
gird布局方案。
使用哪種布局方式,看項目具體要求,如果不需要兼容IE,建議使用flex或者grid,這兩種是未來趨勢。如果要考慮兼容,則最好使用傳統css布局方案。
傳統css布局方案 css標準盒模型前面提過,一個html元素,就是一個方塊,講究一點的話就是盒模型。盒模型長這樣:
我們可以在chrome開發者工具的styles中查看:
css盒模型,分為4部分:
content:顯示元素內容區域,包含子孫元素的地方
padding:內容區域到邊框的距離,也稱內邊距
border:顯示自身輪廓
margin: 用于設置元素自身和同級元素或者父級元素的距離
規則無規矩不成方圓。所有的html元素都是按照一定規則去排列渲染的。在html中,不只有一種規則,是多種規則的混合。了解這些渲染規則和這些規則生效的條件對于我們理解css有很大幫助。
文檔流文檔流可以理解為所有元素的默認渲染規則。它的規則很簡單:元素按照自己的類型的布局特性從左到右,從上往下依次排列。
元素在布局上分為三種類型:
塊級元素:默認占據一整行,即時設置寬度也還是占據一整行,由margin來補充(霸道總裁),有block、table、flex、grid、list-item
內聯元素:寬度由內容撐開,只占據自己的位置,即時設置了寬度也不起作用,margin也是左右起作用,上下不起作用(大家閨秀),有inline
內聯塊級元素: 寬度由內容撐開,只占據自己的位置,可以設置自己的寬度(兩個人的孩子?),有inline-block、inline-table、inline-flex、inline-grid
上面內聯元素其實說的不太正確,這里需要特殊說一下,內聯元素又分為兩種:
可置換內聯元素:該元素展示的內容不在css作用域范圍之內,典型比如img、video、object、input、textarea等,展示內容由src、value等決定,這種元素可以設置寬高
不可置換內聯元素:普通的內聯元素,比如span、a、i、em等
有兩種方式可以脫離文檔流,絕對定位和浮動,我們下面再詳細說。
BFCBFC全稱是Block Formatting Context,塊級格式化上下文。在BFC環境中的元素按照如下規則渲染:
和文檔流一樣,元素按照自己類型的布局特性從左到右,從上往下依次排列。
BFC是一個獨立、封閉的渲染區域。子元素的樣式對BFC外部產生影響。
BFC可以識別浮動子元素。
BFC可以識別浮動的同級元素。利用這一點可以制作彈性布局。
那么什么樣的渲染區域是一個BFC哪?下列幾種方式可以顯示聲明一個BFC的渲染區域:
根元素或包含根元素的元素
float的值不為none
position為absolute或者fixed
overflow的值不為visible
display為inline-block、table-cell、table-caption
尺寸元素的尺寸有兩種情況:
默認情況: 塊級元素寬度默認為100%,高度由內容撐開;內聯元素和內聯塊級元素寬度和高度默認由內容撐開。
開發者設置: 主動設置width、height、line-height等
我們先來明確一下元素的尺寸概念,我們都知道元素的盒模型,元素由content、padding、border、margin四個區域組成。那么尺寸具體是指什么?我們可以把尺寸分為三類:
元素尺寸:由content、padding、border組成,在原生的DOM API中用offsetWidth、offsetHeight獲取
元素內部尺寸: 由content、padding組成,在原生的DOM API中用clientWidth和clientHeight獲取
元素外部尺寸: 由content、padding、border、margin組成,沒有對應的DOM API,但是理解這個,對布局很有幫助
而我們在css中設置的width、height代表哪部分區域是有歧義的,我們通過設置box-sizing,可以切換width、height所代表的區域。
box-sizingbox-sizing,可以切換width、height所代表的區域。box-sizing主流瀏覽器有兩個值:
content-box: width、height設置的是content的寬高
border-box: width、height設置的是content、padding、border加起來的寬高
box-sizing的這兩個屬性,造成width、height的二義性,而且很多情況下是全局設置的,隱蔽性很強,對于新手來說很容易懵。這兩個屬性的產生有一定的歷史原因,最開始的盒模型默認采用的border-box,早期的IE就是這種,也叫IE盒模型。后來W3C覺得content-box更好,又把盒模型默認改為content-box模式。后來的后來,隨著彈性布局的流行,border-box的優勢越來越明顯,大家都更愿意使用border-box來布局,W3C又想把border-box搞回來。但是已經有好多基于content-box的網站,為了兼容性也不能隨便改。于是,W3C就想出了box-sizing這種方式,支持了border-box,但是默認還是content-box。使用box-sizing應注意的幾點:
加入要全局設置box-sizing: border-box,要注意對第三方組件庫的侵入,因為第三方組件很可能是基于content-box來布局的
設置所有元素的box-sizing屬性為inherit:
*, *:before, *:after { box-sizing: inherit; }
這樣我們可以設置父元素的box-sizing,就可以控制所有子元素的box-sizing屬性,對于我們封裝組件,設置整個組件環境很方便,只有我們在封裝組件時強設置box-sizing,就不怕全局的樣式侵入了。
content-box模式在設置彈性布局時,可以使用calc屬性輔助實現,或者弄兩層div實現
尺寸的百分比設置我們知道width, height都是可以設置百分比,那這個百分比的參照物是誰?這里引出一個概念,叫做包含塊(CB, Contanining Block),一個元素的包含塊就是該元素的width、height百分比的參照物。
很多新手同學,在設置寬高百分比的時候,有時候覺得莫名其妙,各種奇怪現象,怎么設置都不起作用。其實就是沒有包含塊的概念。一個元素的包含塊是誰,主要取決于該元素的position屬性,總結如下:
position為static和relative的元素,包含塊為其父元素的content-box
position為absolute的元素,包含塊為其最近的定位非static的祖先元素的padding-box,如果沒有定位非static的祖先元素,則為初始包含塊(后面解釋)
position為fixed的元素,包含塊為視口viewport
position為absolute和fixed時,包含塊也可能是由滿足以下條件的最近父級元素的padding-box:
A transform or perspective value other than none
A will-change value of transform or perspective
A filter value other than none or a will-change value of filter (only works on Firefox)
這條比較特殊,遇到的情況比較少,多帶帶拿出來
除了width, height的百分比相對于包含塊設置外,margin、padding的百分比也是相對于包含塊設置,只不過margin、padding百分比相對于包括塊的寬度設置(水平模式下)。絕對定位的偏移屬性top、left、right、bottom也是相對于包含塊設置,后面再詳細說。
元素的包含塊都是自己的祖先元素,那hmtl元素沒有祖先元素,它的百分比設置相對于誰那?就是初始包含塊,根元素(hmtl)所在的包含塊是一個被稱為初始包含塊的矩形。這個矩形的大小就是瀏覽器視口的大小。有一點需要注意,那些沒有定位非static祖先元素的參照物是初始包含塊,而非html元素。
margin因為margin在布局中有一些重要特性和特殊情況,所以多帶帶拿出來講一下。
我們知道,塊級元素即使設置了寬度,也會占滿一行,為什么會這樣?剩余的空間被誰占了?
這里要明確一點,塊級元素占據一行,是指塊級元素的外部尺寸占據一行,就是margin-box。當margin設置為auto的時候,margin會自動占滿剩余空間。
margin-left: 默認為0,為auto時,自動充滿剩余空間
margin-right: 默認為0,為auto時,自動充滿剩余空間
margin-top: 默認為0,為auto時,值還是為0
margin-bottom: 默認為0,為auto時,值還是為0
當margin-left和margin-right同時為auto,就會平分剩余空間,這就是margin:auto會使元素水平居中的原因。然后margin: auto卻不能使元素垂直居中,這是因為在垂直方向上,塊級元素不會自動擴充,它的外部尺寸沒有自動充滿父元素,也沒有剩余空間可說。如果我們在父元素上設置writing-mode: vertical-lr,這時margin:auto就會使子元素垂直居中,而水平居中無效。
那有沒有什么辦法使用margin:auto讓元素同時水平垂直居中?答案是有的,就是絕對定位的情況下。
.father { width: 300px; height:150px; position: relative; } .son { position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 200px; height: 200px; margin: auto; }
此時的son的外部尺寸,就會自動充滿它的包含塊,效果和塊級元素類似。這時候設置.son元素的寬高,就會有剩余空間出來,margin:auto會自動平分剩余空間,使.son水平垂直居中。
margin對元素的影響有2個:
影響內部尺寸
影響外部尺寸
塊級元素這種寬度方向自動充滿空間的布局特性,當沒有設置寬度,設置margin-left和margin-right為對元素的內部空間有影響。margin為正值時,元素尺寸縮小;margin為負值時,元素尺寸增大。因為元素的外部尺寸大小已經定了,就是其包含塊的尺寸,而外部尺寸等于元素尺寸加上margin,如果margin為負,元素尺寸自然就增大了。利用內部尺寸增大、外部尺寸不變這個特點,我們可以進行等間隔列表的布局。比如我們實現一個一行三列,兩側無間隙,中間間隙為20px的布局:
.father{ margin-right: -20px; } .son{ width: calc( calc(100% - 20px * 3) / 3); margin-right: 20px; }
在元素寬高固定的時候,相當于元素尺寸固定了,margin開始影響元素的外部尺寸。正margin會使元素元素的外部尺寸增大,負margin會使元素元素的外部尺寸縮小。正值很好理解,就不說了。主要說一下負值,這時候margin-top、margin-left和margin-right、margin-bottom的表現看起來是有區別的,實質是一樣。margin-top、margin-left為負值時,表現為元素向上或者向左移動,margin-right、margin-bottom為負值時,表現為其右側元素或者下面元素都會相應地向左或者向上移動。仔細想想,這都是元素外部尺寸縮小的表現。margin-top、margin-left使左側上上側尺寸縮小,就會自然向左或者向上移動。margin-right、margin-bottom使右側和下側尺寸縮小,旁邊和下面的元素自然就會往左或者往上占位。
塊級元素的上邊距和下邊距在某些場景下會發生合并行為。需要注意的是浮動元素和絕對定位元素不會發生合并,且合并只發生在垂直方向。有以下3中合并場景
相鄰兄弟元素
父元素和第一個/最后一個元素
元素內容為空時,height為0,自己的上邊距和下邊距會發生合并
margin合并的計算規則
正正取大
正負相加
負父取小(-20px, -50px合并取-50px)
阻止margin合并的方法
把合并元素變成BFC,比如設置display: inline-block,overflow: hidden, float: left等
父子合并/空元素合并時,給父元素/空元素設置border、padding都能阻止合并
內聯元素尺寸主要想說line-height,vertical-align兩個屬性,這兩個屬性對高度有重要的影響,而且如果沒有理解這兩個屬性的作用,會經常碰到一些不好解決的詭異的布局問題。
這個名字是張鑫旭大神定義的,在W3C規范中也是可以找到根據的。在《CSS世界》這本書中,為了證明幽靈空白節點的存在,舉了一個例子:
div { background-color: #cd0000; } span { display: inline-block; }
你可能猜到了,div的高度不為0,我在chrome下試了試高度為21px,這個高度猜測應該和div的字體、字體大小、行高有關。這個幽靈空白節點的存在,會引起一些怪異現象,比如:
我是文字,我要環繞你
.img-wrap因為高度塌陷,實際上不識別float元素,高度為0,p元素與其重合,從而實現文字環繞效果。
高度塌陷特性在實現布局的時候是不合理的,而現在文字環繞的場景很少,float基本都用來布局使用了。這現在實際上已經成為了一個“bug”的存在。所以css又提供了一個屬性用來清除浮動:clearfix。
clearfix在mdn上的解釋為指定一個元素是否可以在它之前的浮動元素旁邊(我覺得這里用重合更貼切),或者必須向下移動(清除浮動) 在它的下面。
注意上面這句話,指定一個元素表示clearfix的作用目標是元素自身,在它之前的浮動元素表示clearfix的作用條件是它前面有浮動元素,而clearfix的作用效果是讓元素換行顯示。所以clearfix的作用是,如果元素前面有浮動元素,可以指定該元素換行顯示,或者說是識別前面的浮動元素。clearfix有3個值:
left: 清除左浮動
right: 清除右浮動
both: 清除左右浮動
一般情況下采用clearfix: both。清除浮動一個重要應用就是解決float高度塌陷的問題。通用的解決方案是設置.clearfix類:
.clearfix { display: block; zoom: 1; &:after { content: ""; display: block; font-size: 0; height: 0; clear: both; visibility: hidden; } }
在包含浮動元素的父元素上設置該類即可。
博客地址
參考張鑫旭 《CSS世界》
https://mp.weixin.qq.com/s/8e...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/116935.html
摘要:高度模型淺識為的簡寫,簡稱為塊級格式化上下文,為瀏覽器渲染某一區域的機制,中只有和中還增加了和。并非所有的布局都會在開發中使用,但是其中也會涉及一些知識點。然而在不同的純制作各種圖形純制作各種圖形多圖預警 一勞永逸的搞定 flex 布局 尋根溯源話布局 一切都始于這樣一個問題:怎樣通過 CSS 簡單而優雅的實現水平、垂直同時居中。記得剛開始學習 CSS 的時候,看到 float 屬性不...
摘要:擁抱未來的布局方式與布局全教程本書系列文章為對中布局與布局的詳細介紹,已在同步更新,如您在閱讀過程中發現描述有誤或錯別字的情況,您可以向本項目提出或。主要是對于標準里的布局方式草案中的布局方式進行一些總結。 GitBook《擁抱未來的CSS布局方式:flex與grid布局》全教程 本書(系列文章)為對CSS中flex布局與grid布局的詳細介紹,已在GitHub同步更新,如您在閱讀過程...
摘要:如果沒有學習過計算機科學的程序員,當我們在處理一些問題時,比較熟悉的數據結構就是數組,數組無疑是一個很好的選擇。 showImg(https://segmentfault.com/img/bVTSjt?w=400&h=300); 1、常見 CSS 布局方式詳見: 一些常見的 CSS 布局方式梳理,涉及 Flex 布局、Grid 布局、圣杯布局、雙飛翼布局等。http://cherryb...
閱讀 2472·2021-10-12 10:11
閱讀 1218·2021-10-11 10:58
閱讀 3258·2019-08-30 15:54
閱讀 695·2019-08-30 13:59
閱讀 666·2019-08-29 13:07
閱讀 1392·2019-08-26 11:55
閱讀 2132·2019-08-26 10:44
閱讀 2619·2019-08-23 18:25