摘要:可以試試去掉的會發生很奇妙的事呢附加關于子元素設置為而引發的問題。附加關于開啟硬件加速提升網站動畫渲染性能問題。合并后的外邊距的高度等于兩個發生合并的外邊距的高度中的較大者。
1. 水平垂直居中問題
這可以說是最經典的問題了,水平垂直居中,這個問題從入門前端一直到面試,甚至到工作之后都會時不時遇到,最近的面試也被問過這之類的問題,這里還是好好總結一番,以作備忘。公用 HTML 部分:
方法一:CSS居中
設置子元素 position 為 absolute ,然后讓 top 和 left 都為 50%,再使 margin 為子元素的長和寬的負 1/2 即可:
說明: 這種方法局限性很大,不做推薦。
注意: 此處父元素得添加 postion:relative/absolute ,因為 absolute 定位是基于最近的設有 position 的父元素進行定位,如果父元素沒有設置 position ,則其會基于 body 定位。但是如果 body 也沒有的設置 position 的話則基于視口高度計算位置:document.documentElement.clientHeight 。可以試試去掉 parent 的 position 會發生很奇妙的事呢!
附加: 關于子元素 position 設置為 relative 而引發的問題。如果此時父元素的 position 為 absolute,那么不會有什么奇怪的現象發生;但是如果此時父元素的 position 為 relative ,那么你會發現父元素會向上方移動一點距離,這又是為什么呢???這涉及到外邊距塌陷(margin-collapse)問題了,這點在后面的一些2. 外邊距問題中去解釋了(提前透露:父級向上移動了-50px)。
推薦指數: ★
#parent { background-color: black; position: relative; /*或者absolute*/ height: 300px; width: 300px; } #child { background-color: #ccc; position: absolute; left: 50%; top: 50%; margin: -50px 0 0 -50px; height: 100px; width: 100px; }方法二:
CSS里面還有一種 display: table-cell 的屬性,我們可以將父元素的 display 設置為 table-cell 屬性,然后將子元素的 display 設置為 inline 或者 inline-block ,此時便可以用我們熟悉的 text-align: center 和 vertical-align: middle 來使得子元素水平垂直居中了。
說明: 這種方法最適合子元素都為行內元素(或者帶有行內元素性質的塊級元素)的布局,故而可以根據情況選用。
推薦指數: ★★★☆
#parent { background-color: black; display: table-cell; text-align: center; vertical-align: middle; height: 300px; width: 300px; } #child { background-color: #ccc; display: inline-block; height: 100px; /*可以改為33.3%*/ width: 100px; /*可以改為33.3%*/ }方法三:
方法一中只能解決子元素定大小問題,有時候子元素大小變化可以用以下方法解決:
說明: 這種方法非常棒,兼容性也很不錯,強推!
附加: 關于子元素的 position 設為 relative 而使得垂直居中無效問題。關于這個問題其實很好理解,因為,postion: relative 的移動是基于自身原本的位置嘛,top 、 bottom 、 left 、 right 都為 0 ,換句話說就是位置不動,然而,你有見過塊級元素能夠 margin: auto 上下自動補齊的嗎!沒有吧~ 故而起作用的只有左右自動計算補齊而已,也就只有水平居中對齊了!
推薦指數: ★★★★★
#parent { background-color: black; position: relative; height: 300px; width: 300px; } #child { background-color: #ccc; position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; height: 33.3%; width: 33.3%; }方法四:
由于CSS3的來臨,我們也應該跟上時代的潮流,故而對上述方法有有所改進,在此我們可以嘗試一下 transform 元素的 translate 2D 平移,讓其想著 X 、Y 軸負方向移動自身長度的一半距離即可達到效果。
說明: 畢竟技術向新的方向發展,可以多嘗試一下新技術,推薦。
注意: 由于瀏覽器的支持性問題,使用的時候可以檢測 CSS 支持性,也可以通過 Autoprefixer CSS online 來寫兼容性代碼。
附加: 關于 CSS3 開啟 GPU 硬件加速提升網站動畫渲染性能問題。這一點不知道對此位置平移轉換有沒幫助,不過當做是拓展來介紹了,在此我就不詳細說了,推薦 CSS3 頁面渲染加速。
推薦指數: ★★★★
#parent { background-color: black; position: relative; height: 300px; width: 300px; } #child { background-color: #ccc; position: absolute; /*或者relative*/ top: 50%; left: 50%; transform: translate(-50%, -50%); height: 33.3%; width: 33.3%; }方法五:
這個是另外一種 CSS3 的解決方法(我比較喜歡),即 flex 布局。通過設置父元素的 display 屬性為 flex,然后設置其 align-content 和 justify-content 來使得子元素能夠水平垂直居中。
說明: 這個方法在布局上非常靈活,在不考慮兼容的情況下,強烈推薦此方法進行布局。這真的是個非常棒的布局方法!
注意: 由于瀏覽器的支持性問題,使用的時候可以檢測 CSS 支持性,也可以通過 Autoprefixer CSS online 來寫兼容性代碼。
附加: 關于flex的詳細介紹可以參考阮老師的博客: Flex 布局語法篇和 Flex 布局實例篇。
推薦指數: ★★★★☆
#parent { background-color: black; display: flex; display: -webkit-flex; /*Safari*/ align-content: center; -webkit-align-items: center; justify-content: center; -webkit-justify-content: center; height: 300px; width: 300px; } #child { background-color: #ccc; height: 33.3%; width: 33.3%; }2. 外邊距問題 現象描述
第一種情形是,當你在一個 div 元素內插入一個塊級子元素,然后設置其 margin-top 值,這是你會發現并不是子元素在父元素內撐開了一段距離,而是父元素向上撐開了一段距離。
原以為: 實際上: body body -------------------- -------------------- parent * ----------- | 50px * * | 50px parent * ----------- child child ----------- ----------- parent parent -------------------- -------------------- body body
另一種情況是,當你在 div 元素內插入多個塊級元素,你給其中相鄰的兩個設置 margin-top 和 margin-bottom ,你會發現,他們之間的距離為相對應的 margin-top 和 margin-bottom 中的最大值,當設置第一個塊級元素的 margin-top 屬性則會像第一種情形那樣,父級框移動了。
原以為: parent ------------------------ | 10px childA | 10px ==> | 30px | 20px ==> | childB | 20px ------------------------ parent 實際上: body -------------------------- | 10px parent ---------------- childA | max(10px, 20px) ==> 20px childB | 20px ---------------- parent -------------------------- body問題分析
詳細解答在官方文檔的 8.3.1 合并 margin 這一節,太長了,我就不復制了,但是簡單來說可以用W3C上的話來總結:
外邊距合并指的是,當兩個垂直外邊距相遇時,它們將形成一個外邊距。
合并后的外邊距的高度等于兩個發生合并的外邊距的高度中的較大者。
這樣就清楚了!下面說說我的理解(很實用):
Case 1:
父親與兒子并排站(沒邊界嘛,父親位置不定),兒子說:我站在相對前方目標 1m 的地方,問:父親站在離前方目標多遠處?
顯然是 1m 的地方嘛!因為目標不明確(父親也是相對嘛),故而父親同樣也是站在相對前方 1m 處。
Case 2:
ChildA: 我站在距離 ChildB 1m 的位置。
ChildB: 我站在距離 ChildA 1m 的位置。
問: ChildA、ChildB距離多遠?
根據相對性,這不就是 1m 嘛!
依次類比,很相似吧(沒邊界擋著 == 站在同一起跑線)! (σ???)σ..:*☆ 哎喲不錯哦!!!
其實分析時已經表明了,因為都站在同一起跑線,故而大家都不分先后,要讓它們分開,設置點障礙就行了,如:
情況 1:
Method 1: 給父元素添加 border: 1px solid #xxxxxx(劃分界限,父子沒并排站,兒子前方有了目標)。
Method 2: 給父元素添加 overflow: hidden 屬性(相當于父級給自己定了一個隱藏邊界)。
Method 3:讓父元素為絕對定位(因為相當于讓父元素站在一個定點,子元素的前方目標明確了,是父親相對自己距離為 0,距離也就拉開了)。
Method 4:為父元素聲明浮動(浮動會脫離文檔流,此時瀏覽器會給頂元素位置,即所能達到的最左上方)。
個人推薦: Method 2。
這個情況可以說是前一個情況的完整版,其實整體上就是BFC問題(前者也是),BFC的詳細內容我就不細說了,推薦 BFC 神奇背后的原理。
情況 2:
首先得讓父級元素按照情況 1中方式處理,其次是處理子元素。
Method 1:自己計算好相鄰元素的距離,然后直接設置。
Method 2:給每個子元素添加一個 wrapper ,使得每個子元素都是 BFC 區域。
3. 奇怪的布局問題 現象描述個人推薦: Method 2。
當你在 div 元素內插入多個行內塊級元素,你給其中任意一個或者多個設置 margin-top 想要使得它/它們表現得與眾不同,可是,到頭來所有元素都會移動,而且唯一準確的只有所設值最大的那個子元素,其他子元素則混淆。
(注:所有子元素高度為 height: 50px) 原以為: parent ---------------------------------------------------- | 50px childB | 25px childA childC ---------------------------------------------------- parent 實際上: parent ---------------------------------------------------- | 50px | 50px + 25px | 50px - 25px childA childB childC ---------------------------------------------------- parent問題分析
其實這個問題和IFC問題很相似,也就是行內元素基線的選擇問題。 IFC 的介紹中有這么一段話:
IFC ( Inline Formatting Contexts )直譯為"內聯格式化上下文",IFC 的 line box(線框)高度由其包含行內元素中最高的實際高度計算而來(不受到豎直方向的 padding/margin 影響)
IFC 中的 line box 一般左右都貼緊整個 IFC ,但是會因為 float 元素而擾亂。
這就說到很明白了。由于這里是 display: inline-block 故而,其線框高度包含了 margin 、 border 、 padding 、 content ,這樣就知道為什么其他元素的 margin 后的結果與預期不一致的問題了。(此處把 childC 的高度變為 300xp 則是以 childC 的基線為基準定位其他兄弟元素,因為此時 childC “最高”)。
問題解決友情推薦: 什么是 BFC 、IFC 、GFC 和 FFC
要解決這個問題,想讓不同子元素呈現不同效果,我們可以給每個子元素添加一個 wrapper ,并讓 wrapper 以 BFC 的形式包裹子元素,然后你就可以肆無忌憚的改變每個子元素位置了!(參考1. 水平垂直居中問題)
/*wrapper style*/ .wrapper { display: inline-block; height: 100%; /*讓 wrapper 基線對齊*/ overflow: hidden; /* BFC */ }
其他問題: 為什么其他子元素的 margin: mpx 不是在基線上位置向下移動 mpx 而是向上移動呢?(m > 0)
這個問題其實也很好說明,由于此處默認對齊方式是都是基于 bottom 的,故而都是在 bottom 這條起始線開始變化(可以打開瀏覽器看盒子模型), childB 由于沒有 margin 故而其底邊線為此時公用的底邊界,其他盒子在此基礎上有 margin-bottom 的開始向上移動(“最高”的盒子會撐高整個高度,其它盒子只會上升 margin-bottom 值),因此會出現此現象。
此題代碼CSS外邊距塌陷
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/112396.html
摘要:持續心累的找工作階段算是結束了,不同公司對面試的知識側重點不同,整體的感受就是大公司可能更偏向一些基礎或者原理布局一些經典算法方面。現將我在面試過程遇到的問題總結下。目前先傳題目答案整理好之后再發布出來。 持續心累的找工作階段算是結束了,不同公司對面試的知識側重點不同,整體的感受就是:大公司可能更偏向一些JS基礎或者原理、html布局、一些經典算法方面。小公司的面試更加側重對經驗和細節...
摘要:持續心累的找工作階段算是結束了,不同公司對面試的知識側重點不同,整體的感受就是大公司可能更偏向一些基礎或者原理布局一些經典算法方面。現將我在面試過程遇到的問題總結下。目前先傳題目答案整理好之后再發布出來。 持續心累的找工作階段算是結束了,不同公司對面試的知識側重點不同,整體的感受就是:大公司可能更偏向一些JS基礎或者原理、html布局、一些經典算法方面。小公司的面試更加側重對經驗和細節...
摘要:持續心累的找工作階段算是結束了,不同公司對面試的知識側重點不同,整體的感受就是大公司可能更偏向一些基礎或者原理布局一些經典算法方面。現將我在面試過程遇到的問題總結下。目前先傳題目答案整理好之后再發布出來。 持續心累的找工作階段算是結束了,不同公司對面試的知識側重點不同,整體的感受就是:大公司可能更偏向一些JS基礎或者原理、html布局、一些經典算法方面。小公司的面試更加側重對經驗和細節...
閱讀 1220·2021-09-26 09:55
閱讀 3177·2019-08-30 15:55
閱讀 958·2019-08-30 15:53
閱讀 2290·2019-08-30 13:59
閱讀 2375·2019-08-29 13:08
閱讀 1102·2019-08-29 12:19
閱讀 3296·2019-08-26 13:41
閱讀 414·2019-08-26 13:24