當(dāng)margin的值為百分比形式時,為什么瀏覽器會根據(jù)父容器寬度得出計算值?
假如有一個父容器寬度400px,高度600px,其子元素設(shè)置 margin:20% 20%后的計算值應(yīng)該為“margin:120px 80px”還是“margin:80px 80px”呢?在橫向排版時,寬度“有跡可循”,可以把瀏覽器寬度作為參考,所以第二個正確,但是高度是不固 定的,所以margin百分比值在計算時會參考父容器的寬度。當(dāng)書寫模式改為縱向,其計算參考便會變?yōu)楦溉萜鞯母叨攘恕?/strong>
margin:auto為什么只能實現(xiàn)水平居中,不能垂直居中?
當(dāng)一個常規(guī)流中塊級元素的margin屬性左右值設(shè)為關(guān)鍵字auto,且它擁有固定寬度時,它便會平分剩余的水平空間,居中顯示。然而如果設(shè)置上下值為auto,瀏覽器得到的計算值為0,并不起任何的效果。那么問題來了,為什么垂直方向的auto不生效?
與上一問類似,這與布局相關(guān)。網(wǎng)頁排版時,常規(guī)流的塊級元素水平方向總是鋪滿瀏覽器窗口,垂直方向各塊級元素按照先后順序從上往下排列,當(dāng)頁面內(nèi)容過多時網(wǎng)頁會出現(xiàn)縱向滾動條,因此原理上縱向是可以無限擴(kuò)展的,計算時找不到一個固定的參考值,所以縱向的auto無法生效。
同樣,margin:auto會受書寫模式的影響。當(dāng)書寫模式為縱向時,margin:auto垂直方向是可以居中的,水平方向仍然可以居中。不 信?請自己寫個demo試試吧。其實受到書寫模式影響的屬性除了這些外,還有margin折疊、padding百分比值的計算等。
margin折疊指的是毗鄰的兩個或多個外邊距 (margin) 在垂直方向會合并成一個外邊距。
觸發(fā)條件:毗鄰,沒有被非空內(nèi)容、padding、border 或 **clear 分隔開的margin特性. **非空內(nèi)容就是說這元素之間要么是兄弟關(guān)系或者父子關(guān)系
這些 margin 都處于普通流中,即非浮動元素,非定位元素。
垂直方向外邊距合并的計算:
- 參加折疊的margin都是正值:取其中 margin 較大的值為最終 margin 值。
參加折疊的margin都是正值:取其中 margin 較大的值為最終 margin 值。
- 參與折疊的 margin 都是負(fù)值:取的是其中絕對值較大的,然后,從 0 位置,負(fù)向位移。
<div style="height:100px; margin-bottom:-75px; width:100px; background-color: red;">A</div>
<div style="height:100px; margin-top:-50px; margin-left:50px; width:100px; background-color: green;">B</div>
- 參與折疊的 margin 中有正值,有負(fù)值:先取出負(fù) margin 中絕對值中最大的,然后,和正 margin 值中最大的 margin 相加。
- 相鄰的 margin 要一起參與計算,不得分步計算
要注意,相鄰的元素不一定非要是兄弟節(jié)點,父子節(jié)點也可以,即使不是兄弟父子節(jié)點也可以相鄰。
而且,在計算時,相鄰的 margin 要一起參與計算,不得分步計算。
<div style="margin:50px 0; background-color:green; width:50px;">
<div style="margin:-60px 0;">
<div style="margin:150px 0;">A</div>
</div>
</div>
<div style="margin:-100px 0; background-color:green; width:50px;">
<div style="margin:-120px 0;">
<div style="margin:200px 0;">B</div>
</div>
</div>
以上例子中,A 和 B 之間的 margin 折疊產(chǎn)生的 margin,是6個相鄰 margin 折疊的結(jié)果。將其 margin 值分為兩組:
正值:50px,150px,200px
負(fù)值:-60px,-100px,-120px
根據(jù)有正有負(fù)時的計算規(guī)則,正值的最大值為 200px,負(fù)值中絕對值最大的是 -120px,所以,最終折疊后的 margin 應(yīng)該是 200 + (-120) = 80px。
- 浮動元素、inline-block 元素、絕對定位元素的 margin 不會和垂直方向上其他元素的 margin 折疊
- 創(chuàng)建了塊級格式化上下文的元素,不和它的子元素發(fā)生 margin 折疊
以 “overflow : hidden” 的元素為例:
<div style="margin-top:50px; width:100px; height:100px; background-color:green; overflow:hidden;">
<div style="margin-top:50px; background-color:gold;">B</div>
</div>
- 元素自身的 margin-bottom 和 margin-top 相鄰時也會折疊
自身 margin-bottom 和 margin-top 相鄰,只能是自身內(nèi)容為空,垂直方向上 border、padding 為 0。
自身 margin-bottom 和 margin-top 相鄰,只能是自身內(nèi)容為空,垂直方向上 border、padding 為 0。
以上代碼運(yùn)行后,我們講得到的是紅色邊框的正方形,方框的寬高都應(yīng)該是 100px,高度不應(yīng)該是 150px。
行內(nèi)級元素可以設(shè)置寬高嗎
置換元素可以,非置換元素不可以,如span,strong不可以,但是img,input,select,textarea等可以設(shè)置。置換元素本身擁有固有尺寸(高度,寬度,寬高比)的元素,不設(shè)置寬高時,會按照本身的寬高進(jìn)行顯示。
CSS規(guī)則根據(jù)優(yōu)先級生效,低優(yōu)先級的規(guī)則會被瀏覽器忽略還是覆蓋?
多個優(yōu)先級的樣式都會被渲染,只不過高優(yōu)先級會覆蓋住低優(yōu)先級,元素呈現(xiàn)為高優(yōu)先級 的樣式。現(xiàn)在請考慮這樣一個問題,在一個div應(yīng)用了兩條background-image規(guī)則,照之前的理論來看,兩條規(guī)則都會渲染,那么請問瀏覽器會 請求被覆蓋規(guī)則的背景圖片嗎?真實情況是瀏覽器會聰明到只請求當(dāng)前應(yīng)用的背景圖片
使用margin可以做出圓角按鈕的原理是什么?
當(dāng)不能使用border-radius時,如何制造一個圓角按鈕?現(xiàn)在有一個制造1px圓角的小技巧:button中嵌套span,設(shè)置span的margin為:“margin:1px -1px”。原理就是利用視覺誤差。
.btn {
padding: 0;
margin: 0 5px;
border: none;
background: #a5a5a5;
display: inline-block;
font-size: 26px;
}
<a class="btn"><span>1px圓角</span></a>
清除浮動有N種方式,他們間有什么共同點嗎?
清楚浮動的方法
1 結(jié)尾處加空div標(biāo)簽 clear:both;
<style type="text/css">
.div1{background:#000080;border:1px solid red}
.div2{background:#800080;border:1px solid red;height:100px;margin-top:10px}
.left{float:left;width:20%;height:200px;background:#DDD}
.right{float:right;width:30%;height:80px;background:#DDD} /*清除浮動代碼*/ .clearfloat{clear:both} </style>
<div class="div1"> <div class="left">Left</div> <div class="right">Right</div> <div class="clearfloat"></div> </div> <div class="div2"> div2 </div>
2 父級div定義偽類:after和zoom:ie8以上和非IE瀏覽器才支持:after,zoom(IE專有屬性)可解決ie6,ie7浮動問題。
<style type="text/css">
.div1{background:#000080;border:1px solid red;}
.div2{background:#800080;border:1px solid red;height:100px;margin-top:10px}
.left{float:left;width:20%;height:200px;background:#DDD}
.right{float:right;width:30%;height:80px;background:#DDD} /*清除浮動代碼*/
.clearfloat:after{display:block;clear:both;content:"";visibility:hidden;height:0}
.clearfloat{zoom:1}
</style>
<div class="div1 clearfloat">
<div class="left">Left</div>
<div class="right">Right</div>
</div>
<div class="div2"> div2 </div>
3 父級div定義 overflow:hidden
<style type="text/css">
.div1{
background:#000080;border:1px solid red;width:98%;overflow:hidden;}
.div2{background:#800080;border:1px solid red;height:100px;margin-top:10px;width:98%}
.left{float:left;width:20%;height:200px;background:#DDD}
.right{float:right;width:30%;height:80px;background:#DDD}
</style>
<div class="div1"> <div class="left">Left</div> <div class="right">Right</div> </div> <div class="div2"> div2 </div>
原理:必須定義width或zoom:1,同時不能定義height,使用overflow:hidden時,瀏覽器會自動檢查浮動區(qū)域的高度
優(yōu)點:簡單、代碼少、瀏覽器支持好
缺點:不能和position配合使用,因為超出的尺寸的會被隱藏。
4 父級div定義 overflow:auto
<style type="text/css">
.div1{background:#000080;border:1px solid red;/*解決代碼*/width:98%;overflow:auto}
.div2{background:#800080;border:1px solid red;height:100px;margin-top:10px;width:98%}
.left{float:left;width:20%;height:200px;background:#DDD}
.right{float:right;width:30%;height:80px;background:#DDD} </style>
<div class="div1"> <div class="left">Left</div> <div class="right">Right</div> </div> <div class="div2"> div2 </div>
原理:必須定義width或zoom:1,同時不能定義height,使用overflow:auto時,瀏覽器會自動檢查浮動區(qū)域的高度
優(yōu)點:簡單、代碼少、瀏覽器支持好
缺點:內(nèi)部寬高超過父級div時,會出現(xiàn)滾動條。
建議:不推薦使用,如果你需要出現(xiàn)滾動條或者確保你的代碼不會出現(xiàn)滾動條就使用吧。
5 父級div 也一起浮動
原理:所有代碼一起浮動,就變成了一個整體
優(yōu)點:沒有優(yōu)點
缺點:會產(chǎn)生新的浮動問題。
建議:不推薦使用,只作了解。
6 父級div定義 display:table
<style type="text/css">
.div1{background:#000080;border:1px solid red;/*解決代碼*/width:98%;display:table;margin-bottom:10px;}
.div2{background:#800080;border:1px solid red;height:100px;width:98%;}
.left{float:left;width:20%;height:200px;background:#DDD}
.right{float:right;width:30%;height:80px;background:#DDD} </style>
<div class="div1"> <div class="left">Left</div> <div class="right">Right</div> </div> <div class="div2"> div2 </div>
原理:將div屬性變成表格
優(yōu)點:沒有優(yōu)點
缺點:會產(chǎn)生新的未知問題。
建議:不推薦使用,只作了解。
7 結(jié)尾處加 br標(biāo)簽 clear:both
<style type="text/css">
.div1{background:#000080;border:1px solid red;margin-bottom:10px;zoom:1}
.div2{background:#800080;border:1px solid red;height:100px}
.left{float:left;width:20%;height:200px;background:#DDD}
.right{float:right;width:30%;height:80px;background:#DDD} .clearfloat{clear:both} </style>
<div class="div1"> <div class="left">Left</div> <div class="right">Right</div> <br class="clearfloat" /> </div> <div class="div2"> div2 </div>
原理:父級div定義zoom:1來解決IE浮動問題,結(jié)尾處加 br標(biāo)簽 clear:both
建議:不推薦使用,只作了解。
8 父級div定義 height
原理:父級div手動定義height,就解決了父級div無法自動獲取到高度的問題。
優(yōu)點:簡單、代碼少、容易掌握
缺點:只適合高度固定的布局,要給出精確的高度,如果高度和父級div不一樣時,會產(chǎn)生問題
什么是hasLayout?
在InternetExplorer中,一個元素要么自己對自身的內(nèi)容進(jìn)行計算大小和組織,要么依賴于父元素來計算尺寸和組織內(nèi)容。為了調(diào)節(jié)這兩個不同的概念,渲染引擎采用了 hasLayout 的屬性,屬性值可以為true或false。當(dāng)一個元素的 hasLayout屬性值為true時,我們說這個元素有一個布局(layout)
當(dāng)一個元素有一個布局時,它負(fù)責(zé)對自己和可能的子孫元素進(jìn)行尺寸計算和定位。簡單來說,這意味著這個元素需要花更多的代價來維護(hù)自身和里面的內(nèi)容,而不是依賴于祖先元素來完成這些工作。因此,一些元素默認(rèn)會有一個布局。當(dāng)我們說一個元素“擁有l(wèi)ayout”或“得到layout”,或者說一個元素“has layout” 的時候,我們的意思是指它的微軟專有屬性 hasLayout 被設(shè)為了 true。一個“l(fā)ayout元素”可以是一個默認(rèn)就擁有 layout 的元素或者是一個通過設(shè)置某些 CSS 屬性得到 layout的元素。如果某個HTML元素?fù)碛?haslayout 屬性,那么這個元素的 haslayout 的值一定只有 true,haslayout為只讀屬性 一旦被觸發(fā),就不可逆轉(zhuǎn)。通過 IE Developer Toolbar 可以查看 IE 下 HTML元素是否擁有haslayout,在 IE Developer Toolbar 下,擁有 haslayout的元素,通常顯示為“haslayout = -1”。
負(fù)責(zé)組織自身內(nèi)容的元素將默認(rèn)有一個布局,主要包括以下元素: body 、html;tabel、tr、td、th;img;hr;input、button、file、select、textarea、fieldset;frameset、frame、iframe等。
對于沒有默認(rèn)布局的元素,如何激發(fā)haslayout?
設(shè)置如下css屬性即可:display:inline-block,height/width:(除auto任何值),float:left|right,position:absolue,zoom:除 normal 外任意值,
僅限IE7:overflow非visible,設(shè)置min-width或min-height
具有“l(fā)ayout” 的元素如果同時 display: inline ,那么它的行為就和標(biāo)準(zhǔn)中所說的 inline-block很類似了:在段落中和普通文字一樣在水平方向和連續(xù)排列,受 vertical-align影響,并且大小可以根據(jù)內(nèi)容自適應(yīng)調(diào)整。這也可以解釋為什么單單在 IE/Win 中內(nèi)聯(lián)元素可以包含塊級元素而少出問題,因為在別的瀏覽器中display: inline 就是內(nèi)聯(lián),不像 IE/Win 一旦內(nèi)聯(lián)元素?fù)碛?layout 還會變成 inline-block。
zoom:1的原理和作用
Zoom屬性是IE瀏覽器的專有屬性, 它可以設(shè)置或檢索對象的縮放比例、觸發(fā)hasLayout、清楚浮動。
當(dāng)設(shè)置了zoom的值之后,所設(shè)置的元素就會就會擴(kuò)大或者縮小,高度寬度就會重新計算了,這里一旦改變zoom值時其實也會發(fā)生重新渲染,運(yùn)用這個原理,也就解決了ie下子元素浮動時候父元素不隨著自動擴(kuò)大的問題。
BFC:塊級格式化上下文
BFC自成體系,對自己內(nèi)部的元素負(fù)責(zé),不會與浮動元素重疊,上下margin不會重疊,清楚浮動或者實現(xiàn)一個雙欄布局。如何構(gòu)造一個BFC:1.float設(shè)置為非none值;2.overflow設(shè)置為非visible;3.display設(shè)置為 table-cell,table-caption,inline-block;4.position設(shè)置為absolute或fixed。
ie6/7沒有BFC概念,但是有一個與BFC性質(zhì)相似的概念:layout。在IE6,7中遇到的很多bug都可以通過讓元素has layout來解決,比如浮動margin雙邊距,躲貓貓,3像素間距等等。
9.圖片和文字居中
<p>
<span style="vertical-align:middle;">hello</span>
<span style=''background(url(...)) vertical-align:middle;'"/>
</p>