
來(lái)源 | https://chrisdeo.github.io
《CSS世界》這本書(shū)可以說(shuō)是張?chǎng)涡竦囊槐綜SS領(lǐng)域的內(nèi)功心法修煉手冊(cè)了,閱讀這本書(shū),其實(shí)是為了印證一些自身在CSS學(xué)習(xí)上的一些東西,所以,有了這篇讀書(shū)筆記,記錄一些我不是很清晰的知識(shí)點(diǎn),同時(shí)也分享給你,希望對(duì)你也有所幫助與啟發(fā)。1、偽類選擇器:一般指前面有個(gè)英文冒號(hào)(:)的選擇器,如first-child或:last-child等。2、偽元素選擇器:就是有連續(xù)兩個(gè)冒號(hào)的選擇器,如::first-line、::first-letter、::before、::after等。P.S:?jiǎn)巍㈦p冒號(hào)都是現(xiàn)在的規(guī)范,為了區(qū)分偽類和偽元素。IE8僅支持單冒號(hào)的偽元素。3、后代選擇器:選擇所有合乎規(guī)則的后代元素。用空格連接。4、相鄰后代選擇器:僅選擇兒子(一層后代)元素,用>連接。6、通常把HTML標(biāo)簽分為兩種:塊級(jí)元素和內(nèi)聯(lián)元素。7、塊級(jí)元素和display: block不是一回事,但是它們都具備一個(gè)基本特征:一個(gè)水平流只能單獨(dú)顯示一個(gè)元素。8、具有換行特性的”塊級(jí)元素”(筆記7的綜合體),可以配合clear屬性來(lái)清除浮動(dòng)帶來(lái)的影響。9、實(shí)際開(kāi)發(fā)中不會(huì)使用display: list-item來(lái)配合清除浮動(dòng)。理由①:會(huì)出現(xiàn)不必要的項(xiàng)目符號(hào)·,但是可以通過(guò)list-style: none規(guī)避。
理由②:IE不支持偽元素設(shè)置display: list-item,普通元素設(shè)置有效。10、a標(biāo)簽?zāi)J(rèn)display是inline。11、替換元素:根據(jù)其標(biāo)簽和屬性來(lái)決定元素的具體顯示內(nèi)容,即內(nèi)容可被替換,如input, textarea, select, img, video, object等。它們具備了一些其他特性,如內(nèi)容的外觀不受頁(yè)面上的CSS影響,有自己的尺寸:像video、iframe、canvas等這些默認(rèn)尺寸為300X150px,img等則是0,表單無(wú)明顯規(guī)則。在很多CSS屬性上有自己的一套表現(xiàn)規(guī)則:如vertical-align的默認(rèn)值為baseline,在非替換元素,對(duì)應(yīng)西方字符x的下邊緣,而替換元素由于幾乎不可能出現(xiàn)字符這種,所以變成了元素的下邊緣。替換元素尺寸的計(jì)算優(yōu)先級(jí):CSS樣式設(shè)置 > HTML內(nèi)聯(lián)屬性 > 固有。如果發(fā)生了只設(shè)置了width沒(méi)有設(shè)置height的情景怎么辦?最終height = width X 原圖高寬比例。12、理解樣式屬性的意義,規(guī)避不必要的樣式書(shū)寫(xiě),減少性能損耗:
栗子1:當(dāng)我們修改a標(biāo)簽成display: block的時(shí)候,它已經(jīng)具備了塊級(jí)特性,即它本身會(huì)有流的自然填充性,它會(huì)像流一樣自動(dòng)鋪滿外部容器空間。但是,如果你設(shè)置了寬度,不論是百分比還是固定值,它的流動(dòng)性就丟失了。見(jiàn)書(shū)中提供的width: 100%流破壞和自然流填充對(duì)比Demo。栗子2:*{box-sizing: border-box},這種通配符的屬性選擇器應(yīng)當(dāng)盡量避免,因?yàn)楸热鐂earch類型的搜索框,其默認(rèn)的box-sizing就是border-box,這種重復(fù)賦值就是一種損耗,再比如普通內(nèi)聯(lián)元素(非圖片等替換元素),box-sizing無(wú)論是什么值,對(duì)渲染表現(xiàn)都沒(méi)有影響,同樣設(shè)置這種就是無(wú)意義的賦值。13、在本書(shū)中,作者將CSS的盒模型分為了”外盒”以及”內(nèi)盒”,兩者對(duì)應(yīng)具有”外部尺寸”以及”內(nèi)部尺寸”。流的自然填充性就是依賴于外部尺寸的作用。14、格式化寬度:該寬度僅出現(xiàn)在position: absolute或position: fixed情形中,這種情形下,寬度表現(xiàn)為”包裹性”,寬度由內(nèi)部尺寸決定。但是對(duì)于非替換元素,如果left/right,top/bottom這種對(duì)向?qū)傩酝瑫r(shí)存在的時(shí)候,寬度將會(huì)呈現(xiàn)為”格式化寬度”,表現(xiàn)形式就是相對(duì)于最近的具有定位特性的祖先元素計(jì)算,適應(yīng)于該包含塊的padding box。15、在本書(shū)中作者有提到”寬度分離原則”,文中的解釋為CSS中的width屬性不與影響寬度的padding/border屬性共存,即外層容器單獨(dú)設(shè)置width屬性,margin、border、padding利用流動(dòng)性在內(nèi)部自適應(yīng)實(shí)現(xiàn)。這種設(shè)置的目的在于:使寬度嚴(yán)格按照我們預(yù)期的設(shè)計(jì)圖寬度生效,用”人話”來(lái)說(shuō),width = content-width + padding-width + border-width。16、當(dāng)然我們實(shí)際使用的時(shí)候,提供了box-sizing: border-box,這種設(shè)置的效果與筆記15中的寬度分離原則一致。默認(rèn)情況下是
box-sizing: content-box,即content-width = width+ padding-width + border-width。17、對(duì)height屬性,如果父屬性height為auto,只要子元素在文檔流中,其設(shè)定的百分比值會(huì)被完全忽略。舉一個(gè)冗余的為div設(shè)置背景的樣式。div { width: 100%; height: 100%; background: url(bg.jpt);}
這樣設(shè)置的結(jié)果就是高度永遠(yuǎn)為0,實(shí)踐的結(jié)果是百分比高度值要生效,其父級(jí)必須有一個(gè)可以生效的高度值。規(guī)范中如此描述:如果包含的高度沒(méi)有顯示指定(即高度由內(nèi)容提供),且該內(nèi)容非絕對(duì)定位,則計(jì)算值為auto,而auto自然是沒(méi)辦法跟百分比計(jì)算的。18、根據(jù)瀏覽器渲染順序,其實(shí)按DOM自上而下渲染,可以看出嵌套的樣式外部是先固定下來(lái)的,所以不存在那種不斷根據(jù)自適應(yīng)改變進(jìn)行無(wú)限的寬高變化。19、max-width和max-height的應(yīng)用場(chǎng)景一定是自適應(yīng)布局或流體布局中:以一個(gè)最常見(jiàn)的適配場(chǎng)景為例,雖然我們現(xiàn)在使用的顯示器大多數(shù)都是默認(rèn)1920X1080分辨率的,但是,還是有很多以前的小屏幕分辨率機(jī)型,這種可能是古董臺(tái)式機(jī),也有可能是小屏的筆記本電腦。我自身在工作時(shí),就遇到過(guò)筆記本是1600X900分辨率的業(yè)務(wù),此時(shí),通過(guò)這兩個(gè)屬性就能讓寬度在設(shè)定的區(qū)間內(nèi)自適應(yīng):
.container { min-width: 1600px; max-width: 1920px; }
除此之外,它們的兼容性很好,IE7開(kāi)始就支持了。20、以前我的認(rèn)知里面!important對(duì)樣式的權(quán)重是最高的,但是像max-width屬性如果小于width屬性將會(huì)直接將其覆蓋,如果大于,當(dāng)然還是以width顯示。21、同時(shí)存在min-width和max-width的描述,那么最大者生效。22、max-width和max-height的初始值是none,min-width和min-height的初始值是auto。23、max-height的一種應(yīng)用:任意高度元素的展開(kāi)收起動(dòng)畫(huà)技術(shù),傳送門(mén)。這種是原生的CSS3實(shí)現(xiàn),傳統(tǒng)可以用JQ的slideUp()或slideDown()。如果元素內(nèi)容是固定的,即高度固定時(shí),可以用height+overflow: hidden實(shí)現(xiàn)。當(dāng)內(nèi)容是不確定的時(shí)候,想通過(guò)動(dòng)畫(huà)操作實(shí)現(xiàn)從0到內(nèi)容高度,那么動(dòng)畫(huà)結(jié)束的樣式應(yīng)該是height: auto,前面我們也記錄過(guò),auto沒(méi)辦法和百分比計(jì)算。此時(shí)我們改用max-height,只需要保證它是一個(gè)比展開(kāi)的內(nèi)容高度值更大的值即可。那么在動(dòng)畫(huà)計(jì)算的時(shí)候,取的就是height的計(jì)算高度。當(dāng)然這個(gè)max-height在文中還有別的限制,因?yàn)槠湓谶^(guò)高的情況下,由于收起恢復(fù)到原本高度需要時(shí)間,并且在變化過(guò)程中區(qū)域不會(huì)被隱藏,會(huì)給人一種延遲感。綜上,max-height的取值應(yīng)當(dāng)是一個(gè)比內(nèi)容高度高,同時(shí)不能高出太多的值,怎么界定太多呢,即視覺(jué)殘留不能有明顯的延遲感。24、移動(dòng)端的CSS3動(dòng)畫(huà)支持良好,所以移動(dòng)端的JS框架都是沒(méi)有動(dòng)畫(huà)模塊的(原文,本人沒(méi)確認(rèn)過(guò))。25、假想盒:規(guī)范中有如此描述,每一個(gè)行框盒子前,會(huì)有一個(gè)寬度為0但是具有元素字體和行高屬性的內(nèi)聯(lián)盒子,我們把這個(gè)假想盒稱為支柱。注:假想盒僅在HTML5文檔聲明中出現(xiàn)。26、Web開(kāi)發(fā)時(shí),為了提高加載性能以及節(jié)約帶寬費(fèi)用,首屏以下的圖片會(huì)通過(guò)滾屏的方式異步加載。常采取的方案是直接使用<img>占位,然后設(shè)置樣式:img { visibility: hidden; }img[src] { visibility: visible; }
注,此處的<img>是直接沒(méi)有src屬性。因?yàn)榧幢闶莝rc="",在很多瀏覽器下依然會(huì)有請(qǐng)求,并且請(qǐng)求的是當(dāng)頁(yè)數(shù)據(jù)。27、內(nèi)聯(lián)標(biāo)簽設(shè)置寬高樣式是無(wú)效的,但是可以通過(guò)轉(zhuǎn)換display成塊級(jí)生效。28、img標(biāo)簽在Firefox下帶src屬性時(shí),不會(huì)被識(shí)別為替換元素,而是普通內(nèi)聯(lián)元素,即會(huì)有筆記27的問(wèn)題。29、基于偽元素的圖片內(nèi)容區(qū)域預(yù)處理技術(shù),這個(gè)demo我覺(jué)得挺有意思的,見(jiàn)傳送門(mén)。主要的知識(shí)點(diǎn)是,::before和::after這種偽元素作用在img上是有限制的,對(duì)IE來(lái)講,暫不支持這樣操作,對(duì)CHROME和FF。有額外的附加條件:①不能有src屬性(Both),②不能使用content屬性生成圖片(Chrome),③需要有alt屬性并有值(Chrome),④::before偽元素的content值會(huì)被無(wú)視,::after則無(wú)問(wèn)題(FF)。
30、作者觀點(diǎn):替換和非替換元素之間只隔一個(gè)src屬性。對(duì)于CHROME而言,它還需要一個(gè)alt不為空的值才會(huì)成立。對(duì)于IE而言,它的確在沒(méi)有src屬性的時(shí)候還是表現(xiàn)為替換元素,這是因?yàn)镮E有個(gè)默認(rèn)的占位替換內(nèi)容,當(dāng)src缺失的時(shí)候,會(huì)默認(rèn)用這個(gè)占位內(nèi)容去替換(高版本的IE透明化處理了,IE8下會(huì)顯示)。31、作者觀點(diǎn):替換元素和非替換元素之間只隔了一個(gè)CSS content屬性。見(jiàn)傳送門(mén),這是一個(gè)EMOJI替換的處理,不過(guò)這種hover下只是切換樣式,實(shí)際上img里的資源在渲染的時(shí)候已經(jīng)下載了,所以不管切不切換顯示,保存的都是老圖。32、替換元素的固有尺寸無(wú)法修改,即使用content設(shè)置了背景圖后,我們無(wú)法調(diào)整大小,若是在移動(dòng)端使用這種方法設(shè)置背景,原比例的圖會(huì)導(dǎo)致圖片模糊(retina屏幕需要2倍圖),推薦使用SVG圖,矢量圖隨意縮放不會(huì)失真。33、使用content屬性生成的文本無(wú)法被選中也無(wú)法被屏幕閱讀設(shè)備讀取也無(wú)法被搜索引擎抓取,即不利于SEO,它只適合用來(lái)生成一些無(wú)關(guān)緊要的內(nèi)容,如裝飾圖、序號(hào)。34、:empty偽類選擇器用來(lái)匹配無(wú)內(nèi)容的元素,用偽元素::after生成的content內(nèi)容不會(huì)影響實(shí)體內(nèi)容。35、content動(dòng)態(tài)生成值無(wú)法獲取。36、getComputedStyle可以獲取偽元素的計(jì)算樣式,window.getComputedStyle(DOM,"::after").content。37、content內(nèi)容生成應(yīng)用:
①輔助元素生成,如清除浮動(dòng):
.clear:after { content: ''; display: 'block'; clear: both;}
再如等分空間的柱狀圖,傳送門(mén),核心在于通過(guò):before實(shí)現(xiàn)底對(duì)齊,:after實(shí)現(xiàn)兩端對(duì)齊。②字符內(nèi)容生成:傳送門(mén),原理就是通過(guò)@font-face自定義字體集合,然后替換文本內(nèi)容。除此之外,這個(gè)content也可以為Unicode字符,比如\A換行(LF),\D回車(CR)。配合CSS3 animation的loading demo,傳送門(mén)。③圖片生成,content: url(),適用于png、jpg、svg、ico、base64URL等,但是不支持CSS3漸變背景圖(linear-gradient)。④利用content開(kāi)啟符號(hào)閉合,一種使用open-quote和close-quote實(shí)現(xiàn)的方式:通過(guò) 選擇器 { quotes: '前引號(hào)插入內(nèi)容' '后引號(hào)插入內(nèi)容'; }配合選擇器:before { content: open-quote; }以及選擇器:after { content: close-quote; }實(shí)現(xiàn)。另一種則是直接把這種quote放到content內(nèi)容中直接書(shū)寫(xiě):偽元素before/after選擇器: { content: '你要加的內(nèi)容'; }。⑤通過(guò)attr屬性設(shè)置content內(nèi)容:img::after { content: attr(alt) },注:attr內(nèi)可以傳入原生HTML屬性以及自定義data-X屬性且這些屬性不能帶引號(hào)。⑥content計(jì)數(shù)器:這種應(yīng)用,需要先掌握幾個(gè)核心的方法屬性,{ counter-reset: 變量命名1 數(shù)值1 變量命名2 數(shù)值2 ···; }這是一個(gè)初始化計(jì)數(shù)器的動(dòng)作并且能夠同時(shí)指定多個(gè)計(jì)數(shù)器,數(shù)值內(nèi)容在CHROME下可以是負(fù)數(shù),如果是小數(shù)則向下取整;但在FF和IE下不會(huì)識(shí)別,視作0處理;除了指定數(shù)值,還能夠設(shè)置none和inherit來(lái)取消重置和繼承重置。具體見(jiàn)傳送門(mén)。counter-increment屬性的值可以是counter-reset指定的一個(gè)或多個(gè)關(guān)鍵字,后面可選跟隨數(shù)字,表示每一次增加的值,缺省值為1。counter-increment可以被多次觸發(fā),即在::before和::after中的該屬性都會(huì)被觸發(fā),然后通過(guò)counter(關(guān)鍵字)輸出結(jié)果。counter()/counters()方法類似于CSS3的calc()方法,比較有意思的一點(diǎn)是,counter()還能接收第二個(gè)參數(shù)style,它對(duì)應(yīng)的是list-style-type支持的屬性值,即遞增的顯示可以不只是單純數(shù)字,也可以是羅馬字、英文等,見(jiàn)傳送門(mén)。content里可以調(diào)用多個(gè)counter()。counters(name, string,style可選)的string傳參需要引號(hào)包圍,并且是必傳,它用來(lái)表示子序號(hào)的連接字符串,那子序號(hào)需要重新定義關(guān)鍵字么?其實(shí)不需要,counter-reset設(shè)定的關(guān)鍵字僅對(duì)他最近的層級(jí)生效(唯一性),即同一個(gè)初始名,但其實(shí)不同嵌套初始化的不共享這個(gè)值,見(jiàn)傳送門(mén)。注:設(shè)置了counter/counters方法顯示輸出樣式的DOM在文檔流中必須在設(shè)置counter-increment元素的后面才有技數(shù)效果。38、HTML5可以接受自定義標(biāo)簽,瀏覽器默認(rèn)樣式?jīng)]有規(guī)范,會(huì)被應(yīng)用缺省inline,向下兼容,IE8等低版本不識(shí)別,會(huì)直接顯示其內(nèi)容。39、筆記16中,我們知道了設(shè)置box-sizing: border-box以后,width成了真正意義上的總寬度。但如果是具有塊狀特性的元素且內(nèi)部padding足夠大,怎么樣算足夠大?比如總寬度是100px,橫向左右padding和為120px,那么最終寬度是120px。40、對(duì)內(nèi)聯(lián)元素來(lái)說(shuō),它們沒(méi)有可視寬度和高度,即clientHeight和clientWidth永遠(yuǎn)是0。垂直方向上的行為表現(xiàn)完全受line-height和vertical-align的影響。41、內(nèi)聯(lián)元素的垂直padding,可以用來(lái)擴(kuò)大鏈接或按鈕的點(diǎn)擊區(qū)域,同時(shí)不會(huì)影響到現(xiàn)有布局,還有一種登陸 | 注冊(cè)管道符的demo,見(jiàn)傳送門(mén)。42、對(duì)于非替換元素的內(nèi)聯(lián)元素,不僅padding不會(huì)加入行盒高度計(jì)算,margin和border也不會(huì)參與計(jì)算,它們的表現(xiàn)形式是在內(nèi)聯(lián)盒周圍發(fā)生渲染。②支持百分比,塊級(jí)元素div { padding: 50%; }可以擼出一個(gè)正方形,但是內(nèi)聯(lián)元素由于有假想盒的存在(筆記25),會(huì)有個(gè)額外的高度導(dǎo)致最終寬高不等,解決方案很簡(jiǎn)單,其實(shí)就是用控制內(nèi)聯(lián)高度的方式即font-size解決該問(wèn)題:
span { padding: 50%; font-size: 0; background-color: gray;}
注:padding百分比無(wú)論是水平還是垂直方向上都是相對(duì)于寬度計(jì)算的。44、頭圖兼容性較好的做法(包括IE6在內(nèi)的大部分瀏覽器),傳送門(mén)。45、內(nèi)聯(lián)元素的padding在文字較多的時(shí)候可能會(huì)出現(xiàn)斷行。46、標(biāo)簽元素存在內(nèi)置padding,ol/ul內(nèi)置padding單位是px。如果列表中的font-size很小,則li元素內(nèi)的ul或ol左邊緣就會(huì)離文本內(nèi)容區(qū)域很遠(yuǎn),反之font-size很大就會(huì)出現(xiàn)項(xiàng)目符號(hào)跑到元素外的情況。當(dāng)font-size在12px-14px時(shí),22px是一個(gè)較好的padding-left設(shè)定值,所有瀏覽器都能正常顯示。不過(guò)為了更佳的體驗(yàn),用content計(jì)數(shù)器用法更舒服。47、button的padding在設(shè)置為0的時(shí)候,在FF下依舊會(huì)保留左右的padding??梢酝ㄟ^(guò)button::-moz-focus-inner { padding: 0; }來(lái)解決這個(gè)兼容問(wèn)題。48、IE7下button內(nèi)文字過(guò)多會(huì)使左右padding逐漸變大。49、padding可以配合background-clip屬性實(shí)現(xiàn)一些CSS圖形的繪制效果。50、元素偏移尺寸:對(duì)應(yīng)元素的border box尺寸,如offsetWidth和offsetHeight。51、元素內(nèi)部尺寸:對(duì)應(yīng)元素內(nèi)部區(qū)域尺寸,即padding box尺寸,包括padding但不包括border。如clientWidth和clientHeight。52、元素外部尺寸:對(duì)應(yīng)元素外部區(qū)域尺寸,包括padding、border以及margin。即margin box尺寸,沒(méi)有原生DOM API,JQ中可以使用$().outerWidth(true)和$().outerHeight(true)來(lái)控制。53、對(duì)于margin,元素設(shè)定width值或者保持”包裹性”的時(shí)候,margin對(duì)尺寸沒(méi)有影響。只有在空間可被充分利用的條件下是可以被影響的,那啥是空間可被充分利用呢?比如說(shuō)有父子DOM嵌套關(guān)系,分別有father和son的class,那么如果在father設(shè)置width,son不設(shè)置寬度,設(shè)置margin就會(huì)影響到自身的寬度,以下面代碼為例,最后son寬度就是340px,并且這種條件下,垂直方向的高度也可以改變。
<div class="father"> <div class="son"></div></div>.father { width: 300px;}.son { margin: 0 -20px;}
那這種充分利用的特性帶來(lái)了什么實(shí)際場(chǎng)景中的應(yīng)用?比如:一側(cè)定寬的兩欄自適應(yīng)布局,見(jiàn)傳送門(mén)。其實(shí)本質(zhì)就是margin來(lái)擴(kuò)充了父級(jí)的寬度,然后內(nèi)部?jī)蓹冢粰跒楣潭ㄋ赖?,另一欄自適應(yīng)剩余部分的結(jié)果。再比如表格間隙多余的最后一項(xiàng)消除的替代方案,舉個(gè)例子,我們想要我們的每一條li之間產(chǎn)生20px的間隙,那么一般來(lái)講會(huì)設(shè)置一個(gè)margin-right: 20px;,但事實(shí)上,換行的時(shí)候,最后一項(xiàng)就會(huì)多出一個(gè)間隙,消除手段通常是在這個(gè)元素上生成的時(shí)候,附加一個(gè)margin-right: 0;的樣式類或用CSS3的nth-of-type選擇器(不考慮IE8)。現(xiàn)在充分利用margin這種改變布局的特性,我們可以在父容器給一個(gè)margin-right: -20px;,子元素則根據(jù)剩余部分自適應(yīng),那么多余的20的px相當(dāng)于就被抹除了!54、不同瀏覽器的滾動(dòng)條觸發(fā)規(guī)則:Chrome是子元素超過(guò)content-box尺寸觸發(fā),IE和FF則是超過(guò)padding-box觸發(fā)。這種規(guī)則會(huì)導(dǎo)致padding-bottom在IE和FF下失效。55、筆記54中我們知道了padding-bottom有兼容性問(wèn)題,即在頁(yè)面底部留白時(shí),我們不應(yīng)使用padding來(lái)控制,而可以轉(zhuǎn)投筆記53中的利用特性,使用margin擴(kuò)充縱向留白。56、利用margin外部尺寸來(lái)實(shí)現(xiàn)等高布局,傳送門(mén),核心見(jiàn)下面代碼:
.column-box { overflow: hidden;}.column-left,.column-right { margin-bottom: -9999px; padding-bottom: 9999px;}
57、margin的百分比值同padding一樣,無(wú)論是水平還是垂直方向上都是相對(duì)于寬度計(jì)算的。58、像<h1>、<p>、<ul>這些標(biāo)簽是有默認(rèn)垂直方向的margin值的,并且單位是em這種相對(duì)字體的單位。這里作者說(shuō)了他的理解,我覺(jué)得沒(méi)啥毛病,即如果margin使用px這種絕對(duì)單位,當(dāng)字體font-size變大了,那么整個(gè)容器其實(shí)寬高還是那么大就會(huì)造成內(nèi)容臃腫在一起。而使用em它是根據(jù)父元素的font-size按比例算的,所以margin會(huì)跟著自適應(yīng)變大,整個(gè)容器的排版依舊能夠保持一致。59、margin的合并問(wèn)題:
①:只發(fā)生在塊級(jí)元素上(不包括那些通過(guò)浮動(dòng)和絕對(duì)定位產(chǎn)生塊級(jí)特性的元素)。
②:只發(fā)生在垂直方向上(前提是不通過(guò)writing-mode改變方向)。
60、margin的合并場(chǎng)景:
①:相鄰兄弟元素margin合并。
②:父級(jí)和第一個(gè)子元素或者最后一個(gè)子元素的合并(如果父級(jí)沒(méi)有聲明垂直margin,子級(jí)聲明的垂直margin將被合并到父級(jí)去,傳送門(mén))。
③:空塊級(jí)元素的margin合并(這里這個(gè)空的塊提不提供margin垂直方向上的值,它都會(huì)產(chǎn)生合并特性)。61、引出筆記61前,讓我們先溫習(xí)一下啥是BFC,BFC英文全稱是Block Formatting Context,即塊狀格式化上下文。BFC指的是頁(yè)面布局中的一塊區(qū)域,它擁有自己獨(dú)有的內(nèi)部渲染規(guī)則,不受外部影響,同時(shí)也不會(huì)影響到外部區(qū)域,所以BFC元素是不會(huì)發(fā)生margin重疊的情況;另外BFC也可以清除浮動(dòng)帶來(lái)的影響,原因也是那個(gè)不影響外部區(qū)域,假設(shè)它無(wú)法清除,那就會(huì)造成高度坍塌,破壞外部結(jié)構(gòu)。除此之外,BFC還有一個(gè)很關(guān)鍵的用處:自適應(yīng)布局,怎么自適應(yīng)?當(dāng)我們的元素形成BFC以后將不受外部影響,打個(gè)比方,如果他們同在一塊浮動(dòng)容器控制下,那么這塊BFC將脫離控制,自動(dòng)填滿刨去其他浮動(dòng)元素的剩余空間。62、如何觸發(fā)BFC?
①根元素(即html)。
②float屬性不為none。
③position屬性為absolute,fixed(不為relative和static)。
④display為inline-block,table-cell,table-caption,flex,inline-flex。
⑤overflow不為visiable時(shí)(auto、scroll或hidden)。63、消除margin合并的方式:
對(duì)于margin-top合并的情況:
①父元素設(shè)置為BFC。
②父元素設(shè)置border-top。
③父元素設(shè)置為padding-top。
④父元素和第一個(gè)子元素之間添加內(nèi)聯(lián)元素進(jìn)行分隔。
對(duì)于margin-bottom合并的情況:
①父元素設(shè)置為BFC。
②父元素設(shè)置border-bottom。
③父元素設(shè)置為padding-bottom。
④父元素和最后一個(gè)子元素之間添加內(nèi)聯(lián)元素進(jìn)行分隔。
⑤父元素設(shè)置height、min-height或max-height。64、margin合并后的計(jì)算值:
①正正取大。
②正負(fù)相加。
③負(fù)負(fù)最負(fù)(轉(zhuǎn)成絕對(duì)值,取大)。65、margin合并的意義:
①兄弟元素合并:和em作用類似,為了排版更加舒適。
②父子元素合并:在頁(yè)面任何地方嵌套或直接插入空div都不會(huì)影響原本的塊狀布局。
③自身margin合并:避免不小心遺落或者生成的空標(biāo)簽影響原本的排版和布局。66、margin: auto的問(wèn)題:這個(gè)問(wèn)題我覺(jué)得可以分為兩種情況,第一種是元素沒(méi)有設(shè)置width和height,注意這里的設(shè)置即便值是auto也算設(shè)置,它會(huì)自動(dòng)填充父容器。另一種則是設(shè)置了寬高,這個(gè)時(shí)候前者的填充性被覆蓋,根據(jù)”剩余空間”進(jìn)行分配。67、關(guān)于利用margin: auto來(lái)進(jìn)行水平垂直居中的應(yīng)用,我在<<到底怎么樣才能水平垂直居中喔>>一文中有對(duì)其進(jìn)行應(yīng)用的例子,但是那只是在水平方向上利用了該特性,垂直方向上其實(shí)使用的是transform來(lái)移動(dòng)。那為什么容器定高,元素定高,margin: auto無(wú)法垂直方向上居中呢?因?yàn)橛|發(fā)margin: auto計(jì)算的一個(gè)前提條件是當(dāng)width或height為auto時(shí),元素是具有對(duì)應(yīng)方向的自動(dòng)填充特性的。見(jiàn)筆記66中第二種情況,設(shè)置寬高后該特性將被覆蓋。所以沒(méi)辦法在按這種規(guī)則計(jì)算分配空間。在前文我提到的另一篇博客中有另一個(gè)方案對(duì)絕對(duì)定位元素的垂直居中進(jìn)行控制,即在對(duì)向?qū)傩陨贤瑫r(shí)設(shè)置值,這個(gè)時(shí)候該元素會(huì)表現(xiàn)為”格式化寬度和格式化高度”,見(jiàn)筆記14。68、margin: auto的計(jì)算需要IE8及以上的瀏覽器才能支持。69、內(nèi)聯(lián)非替換元素的垂直margin無(wú)效,但替換元素的垂直margin有效,并且沒(méi)有margin合并的問(wèn)題,所以圖片永遠(yuǎn)不會(huì)發(fā)生margin合并。70、tr,td或者display: table-cell,display: table-row的元素margin都是無(wú)效的。71、絕對(duì)定位元素非定位方向的margin值無(wú)效。72、定高容器的子元素的margin-bottom或定寬容器的子元素的margin-right無(wú)效,這個(gè)就比較經(jīng)典了,我自己在寫(xiě)需求的時(shí)候,就有一個(gè)地方需要使用絕對(duì)定位設(shè)置margin-right定位,但是卻發(fā)現(xiàn)無(wú)效了。怎么理解這個(gè)問(wèn)題呢?當(dāng)我們想通過(guò)margin屬性改變自身位置時(shí),必須是和當(dāng)前元素定位方向一樣的margin屬性才行,否則設(shè)定的margin只能影響后面的兄弟元素或父元素。這里的定位方向又是啥?對(duì)一般元素,默認(rèn)流是左側(cè)以及上方,那么只能通過(guò)margin-left和margin-top來(lái)影響元素定位。但是如果通過(guò)float: right或者絕對(duì)定位設(shè)置right屬性,就會(huì)改變定位方向,就可以通過(guò)另一側(cè)設(shè)置了。附:當(dāng)absolute遇到left/top/right/bottom屬性時(shí),才變成真正的絕對(duì)定位元素。其實(shí)這里涉及到一個(gè)相對(duì)性問(wèn)題,當(dāng)設(shè)置了一個(gè)方向的屬性,那么那個(gè)水平或者垂直方向上的相對(duì)性將丟失,那這個(gè)相對(duì)性到底是個(gè)啥呢?73、border-width不支持百分比值,除了使用固定數(shù)值,還支持關(guān)鍵詞如thin,等同1px;medium,默認(rèn)值等同3px;thick,等同4px。74、border-style默認(rèn)值為none。你也可以通過(guò)設(shè)置border-width: 0來(lái)重置。文中描述說(shuō)如果同時(shí)對(duì)這兩種屬性進(jìn)行設(shè)置,渲染性能最高?
div { border: 1px solid; border-bottom: 0 none; }
75、border-style: dotted在IE下和在CHROME、FF下表現(xiàn)形式不同,前者是小圓點(diǎn),后者是小方點(diǎn)。由于CSS的border-radius是在IE9瀏覽器才開(kāi)始支持的,所以之前版本的IE圓角實(shí)現(xiàn)可以利用這種特性來(lái)hack模擬,本質(zhì)就是結(jié)合overflow: hidden來(lái)隱藏多余點(diǎn)(當(dāng)我們想單獨(dú)得到一個(gè)圓的時(shí)候)。
.box { width:150px; height: 150px; overflow: hidden;}.dotted { width:100%; height: 100%; border: 149px dotted #cd0000;}
<div class="box"> <div class="dotted"></div></div>
76、border-style: double上下兩線border實(shí)線,值為1px和2px時(shí),與solid表現(xiàn)形式一致。當(dāng)3px開(kāi)始才有雙線表現(xiàn),所以有筆記73中的medium默認(rèn)值。77、border-color在沒(méi)有設(shè)定時(shí),默認(rèn)取color色值。78、border與transparent的巧妙配合:color: transparent在IE9以上才支持,而border-color: transparent在IE7就支持了。①右下角background定位:現(xiàn)在CSS3操作直接background-position: right 數(shù)值 bottom 數(shù)值即可。文中提到的下面這種操作…em…我沒(méi)實(shí)踐出來(lái)。
.box { border-right: 50px solid transparent; background-position: 100% 50%;}
②增大移動(dòng)端點(diǎn)擊按鈕的可觸區(qū)域:第一種是在外層嵌套標(biāo)簽專門(mén)控制區(qū)域,第二種則是利用其自身的padding或bottom擴(kuò)充區(qū)域大小。而設(shè)定padding在我們使用外部font庫(kù)時(shí),可能會(huì)造成中間圖案定位問(wèn)題,所以最佳方案是使用透明border增加點(diǎn)擊區(qū)域傳送門(mén)。div { width: 0; border: 10px solid; border-color: #f30 transparent transparent;}
79、塊級(jí)元素負(fù)責(zé)結(jié)構(gòu),內(nèi)聯(lián)元素負(fù)責(zé)排版。80、line-height行高的定義是兩條baseline的間距,而baseline又對(duì)應(yīng)著英文字母x的下邊緣。vertical-align的默認(rèn)值為baseline。而CSS中有一個(gè)概念x-height,它對(duì)應(yīng)字母x的高度,等于等分線mean-line到基線baseline的距離。81、我們常用的vertical-align: middle并不是等分線mean-line處,而是基線往上1/2個(gè)x-height處。所以我們有通過(guò)vertical-align: middle來(lái)進(jìn)行垂直居中時(shí),其實(shí)它并不是容器的垂直居中,而是我們字體樣式的垂直居中。82、ex單位對(duì)應(yīng)的就是x-height的高度,它是一個(gè)相對(duì)單位,不管字體字號(hào)如何改變,永遠(yuǎn)相對(duì)于這個(gè)變化。那么這個(gè)單位可以怎么利用呢?比如基于ex單位的天然垂直居中對(duì)齊效果實(shí)例頁(yè)面,見(jiàn)傳送門(mén)。83、<div>內(nèi)容為空的情況高度為0,當(dāng)添加文字后,高度被撐起,但本質(zhì)上這個(gè)撐起的高度是由行高line-height屬性絕對(duì)的而不是font-size。84、前面我們提到了font-size,現(xiàn)在我們來(lái)看看font-size到底作用在啥子地方。首先,line-height的數(shù)值屬性和百分比屬性值都是相對(duì)于font-size計(jì)算的。而vertical-align又是根據(jù)line-height計(jì)算的,見(jiàn)筆記80。以下面的代碼塊為計(jì)算樣例,最終的vertical-align = 16px * 1.5 * -0.25 = -6px。
p { font-size: 16px; line-height: 1.5;}p > img { vertical-align: -25%;}
然后我們看看font-size的關(guān)鍵字屬性值。
相對(duì)當(dāng)前元素font-size計(jì)算的有:
①larger,<big>標(biāo)簽對(duì)應(yīng)font-size大小。
②smaller,<small>標(biāo)簽對(duì)應(yīng)font-size大小。
與當(dāng)前元素font-size無(wú)關(guān),僅受瀏覽器設(shè)置的字號(hào)影響:
①xx-large,和<h1>元素計(jì)算值一樣。
②x-large,和<h2>元素計(jì)算值一樣。
③large,和<h3>元素計(jì)算值相似(偏差值在1px以內(nèi))。
④medium,font-size的初始值,和<h4>的元素計(jì)算值一樣,為16px。
⑤還有與large相對(duì)格式的small。85、瀏覽器默認(rèn)font-size大小是16px,所以設(shè)置font-size: 87.5%和font-size: 14px是等價(jià)的。86、Chrome下有一個(gè)12px的字號(hào)限制,就是文字的font-size計(jì)算值不能小于12px,由于Chrome的特殊性,我們通常進(jìn)行移動(dòng)端em、rem適配的時(shí)候,就不能直接設(shè)置。
html { font-size: 62.5%;}
這樣計(jì)算結(jié)果是10px,換算成em,如果是直屬父級(jí),或rem就是1em/1rem,但是Chrome老哥說(shuō),我覺(jué)得不行,因?yàn)橹灰∮?2px且不為0的大小我就覺(jué)得它是12px大小的,什么?你問(wèn)是0的時(shí)候Chrome怎么看?那當(dāng)然是0咯。那怎么弄呢,可以設(shè)置成625%,即100px。既便于計(jì)算又不會(huì)有之前的問(wèn)題。87、希望隱藏logo對(duì)應(yīng)元素內(nèi)的文字,除了text-indent縮進(jìn)隱藏外,還可以通過(guò)設(shè)置font-size: 0。88、font-family默認(rèn)值由操作系統(tǒng)和瀏覽器共同決定。它支持兩類屬性值,一類是“字體名”,一類是“字體族”,如果字體名包含空格需要使用引號(hào)包裹,不區(qū)分大小寫(xiě),且如果有多個(gè)字體設(shè)定將遵從從左往右依次匹配本地是否有對(duì)應(yīng)的字體。
字體名用法:
body { font-family: simsun;}body { font-family: 'Microsoft Yahei', 'PingFang SC';}
字體族分類:
①serif 襯線字體,即那些橫豎撇捺、張弛有度,有深有淺的字體。
②sans-serif 無(wú)襯線字體(現(xiàn)在更普適的使用字體),即那些所有筆畫(huà)都差不多粗細(xì)的字體。
以上兩者還可以和具體字體名寫(xiě)在一塊,但是必須寫(xiě)在最后,因?yàn)榇蠖鄶?shù)瀏覽器下,寫(xiě)在這兩種屬性后面的字體會(huì)被忽略。
body { font-family: "Microsoft Yahei", sans-serif;}
③monospace 等寬字體,這種一般針對(duì)英文字體而言,即每個(gè)字符在同等f(wàn)ont-size下寬度相同。這種特性的其中一種應(yīng)用就是在模擬選擇欄中的solid、dashed這些效果時(shí),使它們長(zhǎng)度相當(dāng),見(jiàn)穿送門(mén)。ch單位結(jié)合等寬字體特性進(jìn)行手機(jī)長(zhǎng)度校驗(yàn)這類的寬度控制。ch本身是一個(gè)相對(duì)單位,它對(duì)應(yīng)著阿拉伯?dāng)?shù)字0的寬度,CSS3才開(kāi)始支持該單位。
④cursive 手寫(xiě)字體
⑤fantasy 奇幻字體
⑥system-ui 系統(tǒng)UI字體89、font-weight同樣支持關(guān)鍵詞屬性和具體的數(shù)值,如normal,bold,lighter,bolder,數(shù)值從100到900(間隔100為一個(gè)關(guān)鍵詞),其中400對(duì)應(yīng)normal,700對(duì)應(yīng)bold。關(guān)于lighter和bolder是對(duì)繼承的font-weight進(jìn)行解析的,解析規(guī)則如下,這里需要注意的是,系統(tǒng)里面需要安裝了該字體家族的全部字重字體才能將所有解析情景呈現(xiàn),否則缺失的字重字體是無(wú)法解析的,即沒(méi)有表現(xiàn)形式。
90、font-style屬性值有normal,italic,oblique,其中要提的一點(diǎn)差異是italic與oblique,這兩者都是指斜體控制,那么有什么區(qū)別呢,答案就是如果當(dāng)前字體有設(shè)定專門(mén)的斜體字體,那么italic會(huì)取那個(gè)專門(mén)的“樣式”,如果沒(méi)有就會(huì)適應(yīng)成oblique,oblique僅單純地讓文字傾斜。91、縮寫(xiě)的font屬性:它的基本語(yǔ)法組成有[ [ font-style || font-variant || font-weight ] ? font-size [ / line-height ] ? font-family ],其中font-size和font-family是必選的。值得注意的是這種縮寫(xiě)的font屬性將會(huì)破壞部分屬性的繼承性。原文對(duì)這塊的例子解釋,我覺(jué)得有點(diǎn)繞人的意思,概括下來(lái)就是當(dāng)你想用font內(nèi)的font-weight屬性時(shí),line-height將會(huì)被覆蓋成這個(gè)值,并且不同瀏覽器的這個(gè)值是不一樣的,存在兼容性問(wèn)題。另外,由于font-family是必選項(xiàng),當(dāng)這個(gè)屬性很長(zhǎng)的時(shí)候,后面繼承的時(shí)候就會(huì)掛很長(zhǎng)的列表。文中提供了如下兩種解決方式:①設(shè)置一個(gè)不存在的字體名占位,然后再設(shè)置font-family: inherit來(lái)重置這個(gè)占位字體。
②利用@font face將我們的字體列表重定義為一個(gè)字體。92、關(guān)于@font face,我們常在字體圖標(biāo)技術(shù)中應(yīng)用它:本質(zhì)是一個(gè)定義字體或字體集的變量,它不僅可以簡(jiǎn)單定義字體,還包括字體重命名,默認(rèn)字體樣式設(shè)置等。需要我們關(guān)注的屬性包括font-family,src,font-style,font-weight和unicode-range。這里主要記錄一下src和unicode-range,其余的前文我們有過(guò)描述。src表示引入的字體資源,如果使用系統(tǒng)安裝字體可以使用locale()功能符,該功能符IE9及以上版本才支持。而unicode-range則是可以替換特定字符或者特定范圍內(nèi)的字符為我們指定的字體(IE8不支持),如下面這個(gè)替換前后雙引號(hào)的demo。@font-face { font-family: quote; src: local('SimSun'); unicode-range: U+201c, U+201d;}.font { font-family: quote, 'Microsoft Yahei';}
93、text-indent用于對(duì)文本進(jìn)行縮進(jìn)控制,我們可以使用text-indent負(fù)值隱藏文本內(nèi)容,這種操作可以應(yīng)用在將網(wǎng)站的標(biāo)記放在<h1>這種標(biāo)題標(biāo)簽中然后隱藏,利于SEO。關(guān)于text-indent為負(fù)值的情景,要注意百分比和數(shù)值的區(qū)別:百分比是根據(jù)當(dāng)前元素的包含塊來(lái)運(yùn)算的,而數(shù)值則是當(dāng)前內(nèi)聯(lián)盒子,見(jiàn)實(shí)例。有一點(diǎn)需要注意,一些設(shè)備在text-indent負(fù)值特別大的時(shí)候可能會(huì)存在卡頓和性能風(fēng)險(xiǎn),以及對(duì)于一些屏幕閱讀軟件不會(huì)讀取越界的內(nèi)容,將給無(wú)障礙閱讀用戶帶來(lái)困擾。
94、text-indent僅對(duì)第一行內(nèi)聯(lián)盒子內(nèi)容有效。95、非替換元素意外的display計(jì)算值為inline的內(nèi)聯(lián)元素設(shè)置text-indent無(wú)效。在生效時(shí),注意是否存在嵌套的子元素,由于繼承性,如果你還想對(duì)其進(jìn)行別的控制,需要在子元素上覆蓋這個(gè)值。96、<input>的text-indent值無(wú)效,<button>的text-indent有效但是存在兼容性問(wèn)題,IE下百分比根據(jù)容器計(jì)算,Chrome和FF以及其他Shadow DOM元素瀏覽器百分比按照自身尺寸計(jì)算。97、letter-spacing用來(lái)控制字符之間的間距,具有繼承性。默認(rèn)值是normal而非0,支持負(fù)值,當(dāng)值足夠大的時(shí)候,會(huì)讓字符重疊甚至反向排列。98、word-spacing與letter-spacing特性類似,但前者僅作用在空格字符上。啥意思呢?它生效的條件是你首先得有空格存在。99、word-break屬性有normal:默認(rèn)的換行規(guī)則;break-all:允許任意非CJK(中日韓)文本單詞斷行;keep-all:不允許CJK單詞換行,只能在半角空格或連字符處換行。非CJK的文本行為實(shí)際上和normal一致。目前移動(dòng)端不支持keep-all屬性。100、word-wrap在CSS3中有了另外的命名overflow-wrap,但是考慮到兼容性問(wèn)題我們還是用以前的寫(xiě)法,屬性有normal,正常換行規(guī)則;break-world,一行單詞中是在沒(méi)有其他靠譜的換行點(diǎn)再換行,這個(gè)換行點(diǎn)比較關(guān)鍵,具體見(jiàn)傳送門(mén)。101、white-space用于處理元素內(nèi)的空白字符(包含了Space、Enter、Tab產(chǎn)生的空白)。屬性有normal:合并空白字符和換行符;pre:空白字符不合并,并且內(nèi)容只在有換行符的地方換行;nowrap:合并空白字符,但不允許文本環(huán)繞;pre-wrap:pre的作用上同時(shí)允許文本環(huán)繞;pre-line:合并空白字符,但只在換行符的地方換行,允許文本環(huán)繞。102、white-space設(shè)置nowrap時(shí),元素寬度表現(xiàn)為”最大可用寬度”,換行符和一些空格合并,文本一行顯示。以下是常見(jiàn)的應(yīng)用場(chǎng)景:①包含塊尺寸過(guò)小處理。
②單行文字溢出點(diǎn)點(diǎn)點(diǎn)效果(配合text-overflow: ellipsis)。
③水平列表切換效果,DEMO。103、text-decoration下劃線和文本重疊問(wèn)題如何解決?結(jié)合text-decoration: none以及設(shè)置border-bottom和padding-bottom。104、text-transform這個(gè)屬性就比較有趣了,它是為英文字符定制的,可以將這些字符進(jìn)行大小寫(xiě)轉(zhuǎn)化。屬性也比較簡(jiǎn)單uppercase和lowercase。應(yīng)用價(jià)值也極高,比如我們?cè)谳斎腧?yàn)證碼、身份證這些信息時(shí),如果有強(qiáng)校驗(yàn)大寫(xiě),這種轉(zhuǎn)化無(wú)異于幫我們省了一個(gè)重大工序。105、:first-letter是用來(lái)選擇首字符進(jìn)行操作的,不過(guò)這里的首字符比較特殊,里面有個(gè)比較神奇的設(shè)定:就是一些常見(jiàn)的標(biāo)點(diǎn)符號(hào)在:first-letter眼中是”附贈(zèng)品”,什么意思呢?當(dāng)這些附贈(zèng)品出現(xiàn)在頭部時(shí),它們就像贈(zèng)品一樣默認(rèn)受我們的選擇器影響,然后直到我們真正意義上的首字符(商品)變化為止。其次:first-letter生效的前提是display值為block、inline-block、list-item、table-cell或table-caption,其他如table、flex都無(wú)效。另外:before偽元素的content內(nèi)容會(huì)影響:first-letter,即里面的內(nèi)容將會(huì)被優(yōu)先作用。下面看看它支持的CSS屬性:
①所有字體相關(guān)屬性。
②所有背景相關(guān)屬性。
③所有margin相關(guān)屬性。
④所有padding相關(guān)屬性。
⑤所有border相關(guān)屬性。
⑥color屬性。
⑦text-decoration等修飾用屬性。
不能使用visibility、display這些去控制顯隱性。
:first-letter具有嵌套選擇的能力,比如<p>下嵌套了一個(gè)<span>,<span>外沒(méi)內(nèi)容,能夠直接選擇到span內(nèi)的首字符。
:first-letter其實(shí)是作為子元素存在的,所以在衡量特指度權(quán)重的時(shí)候,相同屬性聲明,它的級(jí)別一定會(huì)比父級(jí)高,因?yàn)橄壤^承再覆蓋。
實(shí)際應(yīng)用:如在字段、金額前加符號(hào)標(biāo)記。106、:first-line沒(méi)有筆記105中”附贈(zèng)品的”操作,兩者支持的CSS屬性相近。這一類的偽元素選擇器視作子元素,跟前文中一樣,存在總是高一級(jí)樣式權(quán)重的特征。在標(biāo)簽嵌套的時(shí)候有所不一樣,它不支持table相關(guān)屬性(inline-block/inline-table),DEMO。文中對(duì)該選擇器的應(yīng)用舉了個(gè)覆蓋父級(jí)的例子:按鈕具有一個(gè)全局的顏色控制,但是按鈕的字體不就被遮了么,用:first-line指定顏色,就可以規(guī)避這個(gè)問(wèn)題。107、關(guān)于顏色的關(guān)鍵字:如果瀏覽器能夠識(shí)別關(guān)鍵字,不會(huì)有什么問(wèn)題,但如果瀏覽器無(wú)法識(shí)別的話,在HTML和CSS中定義的這個(gè)關(guān)鍵字將會(huì)產(chǎn)生不同的解析結(jié)果。前者,會(huì)有特殊的算法替換這個(gè)顏色,后者則會(huì)直接使用默認(rèn)顏色。108、background-color: transparentIE6就開(kāi)始支持,border-color: transparentIE7開(kāi)始支持,但color: transparent從IE9才開(kāi)始支持(高版本的IE8兼容可以透明化,但是用戶實(shí)際上使用的都是原生IE8)。109、currentColor使用當(dāng)前color計(jì)算值,但這是個(gè)CSS3變量,IE9+才支持。110、rgba、hsl,CSS3屬性,IE9+才支持。rgba在低版本中可以使用透明度PNG圖片以及filter漸變?yōu)V鏡來(lái)兼容。111、background-color背景色永遠(yuǎn)是最低的。112、一些沒(méi)見(jiàn)過(guò)的隱藏操作:
①不占據(jù)空間、輔助設(shè)備無(wú)法訪問(wèn)、同時(shí)不渲染,可以使用<script>標(biāo)簽。
<script> <img src="1.jpg"></script>
②不占據(jù)空間,輔助設(shè)備無(wú)法訪問(wèn),顯隱的時(shí)候可以有transition淡入淡出效果(其實(shí)這種應(yīng)用場(chǎng)景我沒(méi)有接觸過(guò),先記錄下)。
.hidden { position: absolute; visibility: hidden;}
③不能點(diǎn)擊,不占據(jù)空間,鍵盤(pán)可訪問(wèn),可使用clip裁剪。
.clip { position: absolute; clip: rect(0, 0, 0, 0);}.out { position: relative; left: -999em;}
④可以點(diǎn)擊,不占據(jù)空間,可以使用透明度。
.opacity { position: absolute; opacity: 0; filter: Alpha(opacity=0); }
113、display: none和background-image的問(wèn)題:FF中,display: none元素的background-image是不加載的;但在Chrome和Safari中,若父元素是display: none,圖片才會(huì)不加載,僅是本身元素的背景圖display: none,圖片依舊會(huì)去加載。而IE老哥表示,任何情況他都會(huì)去加載圖片。<img>標(biāo)簽則不受display: none影響,所有瀏覽器都會(huì)去請(qǐng)求圖片資源。有了這種特性,我們就可以利用這種方式去優(yōu)化我們輪播的加載體驗(yàn)。114、visibility具有繼承性,父元素設(shè)置hidden后子元素也會(huì)被隱藏。另外visibility: hidden并不會(huì)影響CSS計(jì)數(shù)器的計(jì)算,但是display: none時(shí),就完全不會(huì)參與計(jì)算。115、visibility可以配合transition實(shí)現(xiàn)顯隱的過(guò)度效果,如transition: opacity 延遲時(shí)間。CSS3中的transition支持CSS屬性visibility。這種延遲顯示的場(chǎng)景有個(gè)比較經(jīng)典的例子:光標(biāo)移動(dòng)的過(guò)程中,如果不設(shè)置延遲效果將會(huì)瞬間觸發(fā)一些hover動(dòng)作,可能會(huì)造成一些不必要的遮擋,見(jiàn)傳送門(mén)。116、關(guān)于視覺(jué)障礙用戶的體驗(yàn):其實(shí)這個(gè)問(wèn)題目前我做的需求都是沒(méi)有涉及的,作者對(duì)display: none和visibility: hidden兩種情景的屏幕閱讀進(jìn)行了對(duì)比,即visibility的顯隱性在視覺(jué)障礙用戶進(jìn)行操作時(shí),體驗(yàn)更佳,它能夠精準(zhǔn)地讀取當(dāng)前操作狀態(tài)的title信息。而display顯隱無(wú)法通知。另外,普通元素的title屬性不會(huì)被朗讀,需要輔助按鈕等控件元素,如role="button"。注意:visibility: hidden的元素是不會(huì)被朗讀的。見(jiàn)文中DEMO,似乎是個(gè)反例,但是其實(shí)在從顯示到隱藏的這個(gè)過(guò)程中,區(qū)域還沒(méi)有消失,所以會(huì)被朗讀出來(lái)。117、outline表示元素的輪廓,語(yǔ)法和border屬性非常類似;outline與focus狀態(tài)以及鍵盤(pán)訪問(wèn)關(guān)系密切。Tab鍵可以依次不斷切換focus元素,包括鏈接、按鈕、輸入框等表單,甚至設(shè)置了tabindex的普通根元素。Shift+Tab可以反向focus。默認(rèn)狀態(tài)下,focus元素會(huì)通過(guò)虛框或者外發(fā)光的形式進(jìn)行區(qū)分和提示,當(dāng)元素被focus后,敲擊回車鍵相當(dāng)于觸發(fā)了該元素的click事件。現(xiàn)代瀏覽器,點(diǎn)擊鏈接按鈕后已經(jīng)不會(huì)觸發(fā)outline效果了,但通過(guò)Tab或element.focus()才會(huì)觸發(fā)發(fā)光效果。118、outline的應(yīng)用:outline是真正意義上的不占據(jù)任何空間的屬性。輪廓寬度設(shè)置再厚也不會(huì)影響任何其他元素的布局。并且outline輪廓是可穿透的。書(shū)中例子有二,①頭像裁剪的矩形鏤空效果。②自動(dòng)填滿屏幕剩余空間。119、cursor光標(biāo)屬性:auto,cursor的默認(rèn)值,會(huì)跟著內(nèi)容而變化成不同的光標(biāo)形態(tài);default系統(tǒng)默認(rèn)光標(biāo)形態(tài),不會(huì)變化,指那種未選定的情形。none,隱藏光標(biāo),比如觀看視頻全屏?xí)r,靜止幾秒我們就將鼠標(biāo)圖標(biāo)隱藏掉,有mouseover再重新顯示,注意這里cursor: none的兼容性是IE9+,即IE8下要做兼容處理,可以通過(guò)自定義透明光標(biāo)(Chrome弄一張透明PNG)實(shí)現(xiàn),傳送門(mén)。代碼中出現(xiàn)了:root選擇器,首先這是一個(gè)根元素選擇器,html就是我們的根,其次這是一個(gè)CSS3屬性,兼容性IE9+。還有一些常用的如pointer、text就不全部贅述了。120、direction主要關(guān)注2個(gè)屬性ltr默認(rèn)值以及rtl,分別代表從左到右left to right以及右到左。它負(fù)責(zé)的東西很關(guān)鍵,就是改變水平流向,比如交換按鈕位置,圖片左右互換等等。121、unicode-bidi,這個(gè)屬性是配合direction一起使用的,因?yàn)閐irection其實(shí)只能改變圖片或按鈕的呈現(xiàn)順序,而對(duì)純字符內(nèi)容無(wú)能為力(尤其是中文字符),這個(gè)時(shí)候就需要兄弟unicode-bidi幫忙了。bidi的全寫(xiě)英文是bidirectionality,它意味著雙向性(阿拉伯文是從右往左讀的),它幫助規(guī)范字符出現(xiàn)雙向性時(shí)該有的表現(xiàn),默認(rèn)值為normal,表示正常排列,而embed只能作用于內(nèi)聯(lián)元素上,并且embed屬性不會(huì)受外部嵌套的元素屬性設(shè)置影響(相當(dāng)于自身開(kāi)了個(gè)內(nèi)嵌區(qū)域,自己操作),傳送門(mén)。bidi-override,會(huì)強(qiáng)制所有字符按照direction設(shè)置的方向反向排列。embed和bidi-override可以使用特殊字符替代。122、writing-mode就比較牛逼了,它可以將頁(yè)面默認(rèn)的水平流改成垂直流。默認(rèn)值為horizontal-tb很好理解,horizontal水平,tb,topbottom,即水平方向從上到下排列。由于不同瀏覽器和版本支持的屬性都有所不同,作者整理出了幾個(gè)需要關(guān)注的屬性:
.example { writing-mode: lr-tb | tb-rl | tb-lr; writing-mode: horizontal-tb | vertical-rl | vertical-lr;}
123、關(guān)于float,浮動(dòng)的本質(zhì)就是為了實(shí)現(xiàn)文字環(huán)繞的效果,文章原話。124、float特性:
①包裹性,由兩部分組成,包裹和自適應(yīng)性。包裹可以理解為,具有float設(shè)定的容器的寬高將會(huì)以嵌套的內(nèi)容寬高為表現(xiàn)。自適應(yīng)則是浮動(dòng)元素嵌套的元素如果是多個(gè),將會(huì)自適應(yīng)分配剩余空間。
②塊狀化格式上下文(BFC)
③破壞文檔流
④無(wú)任何margin合并125、筆記124中的第二條中,強(qiáng)調(diào)了塊狀化的說(shuō)法,那么什么是塊狀化?即一旦float屬性不為none,則display計(jì)算值將是block或者table。像以下的寫(xiě)法都是冗余的:
span { display: block; float: left;}span { float: left; vertical-align: middle; text-align: center; }
126、行框盒子如果和浮動(dòng)元素的垂直高度有重疊,則行框盒子在正常定位狀態(tài)下只會(huì)跟隨浮動(dòng)元素,而不會(huì)發(fā)生重疊。行框盒子怎么理解呢,其實(shí)就是我們內(nèi)聯(lián)元素所在的那一層,當(dāng)浮動(dòng)元素導(dǎo)致高度塌陷時(shí),其實(shí)塊盒的確發(fā)生重疊了,但是內(nèi)聯(lián)元素所在的層則由于有這種特性不會(huì)發(fā)生重疊。127、文字環(huán)繞其實(shí)是由”父級(jí)高度塌陷”和”行框盒子區(qū)域限制”(筆記126中描述)兩方面作用的結(jié)果。”父級(jí)高度塌陷”可以通過(guò)設(shè)定高度來(lái)cover但是”行框盒子區(qū)域限制”就沒(méi)辦法了,所以當(dāng)你出現(xiàn)設(shè)定容器高度與內(nèi)嵌圖片高度一樣時(shí),由于內(nèi)聯(lián)下圖片底部的間隙導(dǎo)致實(shí)際高度大于這個(gè)高,后面的文本就會(huì)產(chǎn)生環(huán)繞。128、IE8以下的瀏覽器產(chǎn)生浮動(dòng),文字會(huì)浮動(dòng)到下一行內(nèi)容顯示。這與我現(xiàn)在的認(rèn)知IE8+的同行浮動(dòng)顯示不同。129、浮動(dòng)元素的作用機(jī)制:
①浮動(dòng)錨點(diǎn):float所在流中的一個(gè)點(diǎn),這個(gè)點(diǎn)本身并不浮動(dòng),表現(xiàn)得像一個(gè)沒(méi)有margin、border和padding的空內(nèi)聯(lián)元素。作用就是產(chǎn)生”行框盒子”:在沒(méi)有”行框盒子”進(jìn)行浮動(dòng)參考時(shí)(比如浮動(dòng)元素前后都是塊級(jí)時(shí)),提供參考。①浮動(dòng)參考:浮動(dòng)元素對(duì)齊參考的實(shí)體。浮動(dòng)元素進(jìn)行對(duì)齊的實(shí)體就是當(dāng)前float元素的”行框盒子”,而非外部包含塊盒。130、官方文檔對(duì)clear屬性的解釋是:元素盒子的邊不能和前面的浮動(dòng)元素相鄰。所以其實(shí)這個(gè)值真正意義上定義的是設(shè)置了clear屬性元素本身的行為,而不是float元素的行為。默認(rèn)是none,即左右浮動(dòng)正常作用于本身,left左側(cè)抗拒浮動(dòng),right右側(cè)抗拒浮動(dòng),both兩側(cè)抗拒浮動(dòng)。在我們實(shí)際應(yīng)用場(chǎng)景中使用clear來(lái)清除浮動(dòng)其實(shí)使用clear: both即可,因?yàn)閏lear: left\right都可以用前者替代。文中有一個(gè)DEMO比較好地闡釋了什么clear針對(duì)的前面的浮動(dòng)元素:
li { width: 20px; height: 20px; margin: 5px; float: left;}li: nth-of-type(3) { clear: both;}
以上樣式為第三個(gè)li設(shè)置clear: both,假設(shè)我們有10個(gè)<li>元素,最終只會(huì)形成2行排列而不是三行。首先最基本的一點(diǎn),li是塊級(jí)元素,在float: left;的作用下,才會(huì)出現(xiàn)單行的情景,然而clear: both事實(shí)上只針對(duì)前面的浮動(dòng),所以第三個(gè)li本身恢復(fù)塊級(jí)排列到了第二行,其后的浮動(dòng)不受影響跟著第三個(gè)li到第二行。綜上所述,當(dāng)我們遇到需要屏蔽浮動(dòng)的場(chǎng)景統(tǒng)一使用clear: both。131、clear屬性只有塊級(jí)元素才生效,而::after等偽元素默認(rèn)都是內(nèi)聯(lián)水平,這就是為什么我們?cè)谇宄?dòng)的時(shí)候往往還需要同時(shí)設(shè)置一個(gè)display屬性的原因,比如下面這種:
.clear:after { content: ''; display: table/block/list-item; clear: both;}
132、clear只能在一定程度上消除浮動(dòng)的影響,因?yàn)閏lear: both這種本質(zhì)上是使自身不和float元素在一行顯示,所以float一些特性還是會(huì)被保留。比如:
①clear: both元素前也是浮動(dòng)元素,即使margin-top負(fù)值設(shè)為-9999px也無(wú)效。
②clear: both后面元素依舊可能發(fā)生文字環(huán)繞現(xiàn)象。133、再看看overflow,它才是最適合進(jìn)行清除浮動(dòng)的控制屬性。為什么呢?因?yàn)樗粫?huì)影響原本的流體特性或?qū)挾缺憩F(xiàn)。而其他的CSS聲明基本都會(huì)讓元素產(chǎn)生”包裹性”。134、overflow屬性本身是為了對(duì)溢出元素的內(nèi)容進(jìn)行裁剪而設(shè)計(jì)的,并且裁剪邊界的判定是以border box為基準(zhǔn)而非padding box。,實(shí)例。135、overflow屬性有一個(gè)典型的兼容問(wèn)題,即在Chrome瀏覽器下如果容器支持滾動(dòng),則padding-box也會(huì)被計(jì)入滾動(dòng)尺寸內(nèi),表現(xiàn)形式就是拖到容器最下方,若有設(shè)定padding,Chrome下將會(huì)有留白,而IE和FF不會(huì)計(jì)算這個(gè)padding,即不會(huì)有留白問(wèn)題。136、IE8以上開(kāi)始支持overflow-x和overflow-y屬性,它們提供的屬性跟overflow一致:
①visible: 默認(rèn)值。
②hidden: 剪裁。
③scroll: 滾動(dòng)條區(qū)域一直在。
④auto: 不足以滾動(dòng)時(shí)沒(méi)有滾動(dòng)條,可以滾動(dòng)時(shí)滾動(dòng)條出現(xiàn)。
但是,overflow-x和overflow-y有相互約束:除非overflow-x和overflow-y屬性值都是visible,否則visible會(huì)被當(dāng)作auto解析。看看下面這個(gè)例子:
html { overflow-x: hidden; overflow-y: auto; }
137、textarea和html元素是默認(rèn)可以產(chǎn)生滾動(dòng)條的。因?yàn)樗鼈兡J(rèn)的overflow不是visible,IE8開(kāi)始都是使用auto作為默認(rèn)屬性,即默認(rèn)狀態(tài)下是沒(méi)有滾動(dòng)欄的,只有當(dāng)內(nèi)容溢出時(shí)才出現(xiàn)。而IE7的表現(xiàn)就是如同設(shè)置了overflow-y: scroll一樣(為什么說(shuō)如同,見(jiàn)筆記136),一直保有垂直滾動(dòng)欄。138、PC端,無(wú)論什么瀏覽器,默認(rèn)滾動(dòng)條都是來(lái)自html,如果想去除默認(rèn)滾動(dòng)條可以直接通過(guò)如下樣式設(shè)置剔除:
html { overflow: hidden;}
139、移動(dòng)端使用筆記138中的方式就不一定能夠隱藏默認(rèn)滾動(dòng)條了,PC端的滾動(dòng)高度可以使用document.documentElement.scrollTop獲取,而移動(dòng)端需要使用document.body.scrollTop獲取。那結(jié)果已經(jīng)很明顯了,使用body元素選擇器即可:
body { width: 400px; height: 100px; overflow: auto;}
這里的寬度雖然是400px,但要注意到其實(shí)滾動(dòng)條本身會(huì)占據(jù)空間,在WIN7系統(tǒng)下的IE7+、Chrome、FF瀏覽器滾動(dòng)欄所占據(jù)的寬度均為17px。關(guān)于滾動(dòng)條占據(jù)空間帶來(lái)最大的影響是水平居中布局可能會(huì)產(chǎn)生晃動(dòng),因?yàn)榇绑w默認(rèn)沒(méi)有滾動(dòng)條,而HTML內(nèi)容是自上而下加載的,就會(huì)發(fā)生一開(kāi)始沒(méi)有滾動(dòng)條,然后突然出現(xiàn)滾動(dòng)條的情況,此時(shí)頁(yè)面的可用寬度發(fā)生變化,水平居中重新計(jì)算,就會(huì)發(fā)生頁(yè)面晃動(dòng)。比較簡(jiǎn)單的做法是:
html { overflow-y: scroll;}
但這樣雖然橫向的overflow最終計(jì)算就是auto了,并且在頁(yè)面比較高的時(shí)候還湊合,但是如果頁(yè)面就只用一屏,右側(cè)還是始終有滾動(dòng)欄就不合適了。下面是作者提供的讓頁(yè)面滾動(dòng)條不發(fā)生晃動(dòng)的技巧:
html { overflow-y: scroll; }:root { overflow-y: auto; overflow-x: hidden;}:root body { position: absolute;}body { width: 100vh; overflow: hidden;}
140、自定義瀏覽器滾動(dòng)條:IE的自定義效果要比原生的還差;支持-webkit-前綴的瀏覽器可以使用以下屬性:
::-webkit-scrollbar整體部分。
::-webkit-scrollbar-button兩端按鈕。
::-webkit-scrollbar-track外層軌道。
::-webkit-scrollbar-track-piece內(nèi)層軌道。
::-webkit-scrollbar-thumb滾動(dòng)滑塊。
::-webkit-scrollbar-corner邊角。
實(shí)際開(kāi)發(fā)中使用其中3個(gè)就夠了:
::-webkit-scrollbar { width: 8px; height: 8px;}::-webkit-scrollbar-thumb { background-color: rgba(0,0,0,.3); border-radius: 6px;}::-webkit-scrollbar-track { background-color: #ddd; border-radius: 6px;}
141、錨點(diǎn)是如何跳轉(zhuǎn)的就不贅述了,主要記錄一下錨點(diǎn)行為的本質(zhì):通過(guò)改變?nèi)萜鳚L動(dòng)高度或者寬度亦可以說(shuō)是修改scrollTop和scrollLeft來(lái)實(shí)現(xiàn)(注意不是瀏覽器的滾動(dòng)高度或?qū)挾?。錨點(diǎn)的定位可以發(fā)生在普通容器元素上,并且由內(nèi)而外,這個(gè)由內(nèi)而外的意思是當(dāng)普通元素和窗體同時(shí)可滾動(dòng)的時(shí)候,會(huì)由內(nèi)而外觸發(fā)所有可滾動(dòng)窗體的錨點(diǎn)定位,假設(shè)目前一個(gè)是容器盒子的錨點(diǎn)定位,另一個(gè)則是頁(yè)面的視窗錨點(diǎn)定位,即先定位到內(nèi)部錨點(diǎn)再在整個(gè)頁(yè)面視窗定位,見(jiàn)DEMO。142、設(shè)置了overflow: hidden的元素僅是隱藏了滾動(dòng)條,當(dāng)內(nèi)容溢出時(shí),依然可以進(jìn)行滾動(dòng)。當(dāng)然此時(shí)滾動(dòng)條已經(jīng)消失,無(wú)法通過(guò)鼠標(biāo)滾輪進(jìn)行操作,但是錨點(diǎn)定位還是可以使得頁(yè)面滾動(dòng)。143、結(jié)合筆記141和筆記142,可以通過(guò)錨點(diǎn)切換來(lái)做一些簡(jiǎn)單的選項(xiàng)卡切換動(dòng)作。但是在筆記141中的錨點(diǎn)交互中存在由內(nèi)而外觸發(fā)錨點(diǎn)定位的頁(yè)面跳動(dòng)問(wèn)題,所以我們可以使用另外一種錨點(diǎn)定位方式:focus錨點(diǎn)定位,即類似鏈接或按鈕、輸入框那種在被focus時(shí)發(fā)生的重定位現(xiàn)象。這種方式只要定位的元素在窗體當(dāng)中,就不會(huì)觸發(fā)窗體的滾動(dòng)。見(jiàn)DEMO。操作的原理就是往列表里加入一個(gè)隱藏的input框并設(shè)置id,然后關(guān)聯(lián)一個(gè)label,這一步其實(shí)跟那篇<<input與label標(biāo)簽的關(guān)聯(lián)>>文章原理一致,只不過(guò)當(dāng)我們點(diǎn)擊關(guān)聯(lián)label的同時(shí)也focus了我們的輸入框,這才真正實(shí)現(xiàn)了滾動(dòng)切換,并且這種focus實(shí)現(xiàn)還能通過(guò)TAB來(lái)控制。144、position: absolute和float都兼具”塊狀化”、”包裹性”、”破壞性”等特性。但是當(dāng)absolute和float同時(shí)存在時(shí),float屬性是無(wú)效的,所以這兩者沒(méi)有理由同時(shí)出現(xiàn)。145、absolute元素的寬高百分比取決于它的包含塊,而這包含塊指的是該元素第一個(gè)position不為static的祖先元素。一些基本的計(jì)算規(guī)則:①position: statc\relative以最近的塊級(jí)元素祖先的content-box計(jì)算。
②positoin: fixed以根元素,即瀏覽器可視窗口大小計(jì)算。
③position: absolute前文提及。
對(duì)于absolute元素,內(nèi)聯(lián)元素也能成為它的包含塊;包含塊不是它的父級(jí)元素,而是最近的非static祖先或根元素;邊界取padding-box。146、在移動(dòng)端,列表和模塊域往往會(huì)有一定的留白來(lái)反饋手指按壓的感覺(jué),比如加深顏色背景,這種留白往往都是通過(guò)padding來(lái)實(shí)現(xiàn)的,那為什么不用margin呢?因?yàn)閙argin box永遠(yuǎn)是透明的。147、在頁(yè)頭放置一個(gè)標(biāo)簽,使用透明border設(shè)置,可以規(guī)避padding和top/right這種方向?qū)傩缘鸟詈?兩者的數(shù)值都要同時(shí)修改)。148、absolute是非常獨(dú)立的CSS屬性值,起樣式和行為表現(xiàn)不依賴其他任何CSS屬性就可以完成。我們很多時(shí)候使用絕對(duì)定位的時(shí)候,都習(xí)慣在外層嵌套一層relative控制,但其實(shí)它自己就能完成這件事,見(jiàn)DEMO。作者將那些沒(méi)有設(shè)置方向?qū)傩詌eft/top/right/bottom的絕對(duì)定位稱為”無(wú)依賴絕對(duì)定位”,它可以理解為不占據(jù)空間的相對(duì)定位。見(jiàn)DEMO。后面作者舉的輸入框校驗(yàn)提示語(yǔ)的DEMO也很亮,就是利用absolute的不占據(jù)空間的優(yōu)勢(shì)而不會(huì)破壞最初定好的容器總寬度。傳送門(mén)。雖然以上足以說(shuō)明”無(wú)依賴絕對(duì)定位”好處多多,但是最好只在靜態(tài)交互效果上使用,如導(dǎo)航二級(jí)菜單的顯示與定位。149、IE9及其以下版本的瀏覽器不支持placeholder占位符效果。那怎么模擬呢?可以使用前文提到過(guò)的label與input關(guān)聯(lián),然后focus轉(zhuǎn)變樣式,定位使用前面的”無(wú)依賴絕對(duì)定位”就很合適,不會(huì)占據(jù)空間。150、absolute在遇到left/top/right/bottom后才真正具有絕對(duì)定位的特性,如果僅有一個(gè)方向設(shè)定了值,那么沒(méi)有設(shè)定值的方向依然保有相對(duì)特性。151、前文中,我們?cè)岬竭^(guò)當(dāng)對(duì)立方向同時(shí)發(fā)生定位的時(shí)候會(huì)產(chǎn)生”格式化寬度”,對(duì)于absolute元素而言,當(dāng)它具備”格式化寬度”時(shí),也同時(shí)具備了流體特性,如果包含塊的padding box發(fā)生變化,這個(gè)塊的寬度也會(huì)跟著一起變。152、如果想讓絕對(duì)定位元素寬高自適應(yīng)于包含塊,沒(méi)有理由不使用流體特性寫(xiě)法。因?yàn)槠洳粌H跟普通元素持有一樣的水平流動(dòng)性,在垂直方向上它也可以保持流動(dòng)性。153、當(dāng)絕對(duì)定位元素處于流體狀態(tài)的時(shí)候,它的盒模型相關(guān)解析和普通流體元素都是一模一樣的:②:一側(cè)margin定值,一側(cè)auto,auto為剩余空間大小。③:如果兩側(cè)均為auto,則平分剩余空間。④:絕對(duì)定位元素的margin: auto從IE8開(kāi)始才支持,而普通元素的很早就支持了。⑤:百分比transform在部分場(chǎng)景可能會(huì)造成IOS微信閃退。154、relative定位具有”無(wú)侵入性”,即relative元素自身進(jìn)行偏移時(shí),不會(huì)影響周圍元素的布局。見(jiàn)DEMO。155、關(guān)于relative的定位問(wèn)題:①:letf/top/right/bottom的百分比值是相對(duì)于包含塊計(jì)算的,垂直方向上的屬性百分比值計(jì)算跟height的百分比值一樣,都是相對(duì)高度計(jì)算。所以當(dāng)包含塊高度是auto時(shí),計(jì)算值為0,會(huì)導(dǎo)致偏移無(wú)效。即我們要注意到父元素沒(méi)有設(shè)定高度或者不是”格式化高度”的情況。②:當(dāng)relative的對(duì)向?qū)傩酝瑫r(shí)出現(xiàn)的時(shí)候,和absolute表現(xiàn)非常不一樣;當(dāng)水平方向?qū)傩酝瑫r(shí)出現(xiàn),只保留left;當(dāng)垂直方向?qū)傩酝瑫r(shí)出現(xiàn),只保留top。因?yàn)槟J(rèn)文檔流是從左到右,自上而下的。①盡量不要使用relative,如果想定位某些元素,可以考慮是否能用”無(wú)依賴絕對(duì)定位”,優(yōu)勢(shì)在筆記148中有記錄。②如果場(chǎng)景受限,必須使用relative時(shí),務(wù)必使其最小化,這個(gè)最小化可以理解為便于之后的維護(hù)以及規(guī)避場(chǎng)景復(fù)雜后的樣式問(wèn)題。前文中,我們?cè)岬竭^(guò)relative有無(wú)侵入性,即它能夠保證不影響之后的元素布局。按書(shū)中的一個(gè)例子,場(chǎng)景是在某個(gè)模塊右上角定位一個(gè)圖標(biāo):<img src="xx.jpg" style="position: absolute; top: 0; right:0;">
<div style="position: relative"> <img src="xx.jpg" style="position: absolute; top:0; right:0;"></div>
其實(shí)這種relative限制還有一個(gè)好處,那就是層疊級(jí)別提升,relative比普通元素的層級(jí)要高,那么后面的元素就不會(huì)出現(xiàn)可能覆蓋前者的情況。157、position: fixed正常來(lái)講,不管在啥地方,都是根據(jù)根元素即html來(lái)定位的;但我們可以操作一波把它也按照我們的想法根據(jù)包裹的父容器定位,因?yàn)閒ixed和absolute一樣,在沒(méi)有方向?qū)傩缘臅r(shí)候具有相對(duì)定位特性。158、position: fixed的absolute模擬:說(shuō)實(shí)話一開(kāi)始我看這個(gè)解釋挺懵逼的,什么既不跟隨滾動(dòng),又被定位元素限制。后面看了下DEMO代碼大概能理解其行為了:<html> <body> <div class="page"> <div class="fixed"> </body></html>
html, body { height: 100%; overflow: hidden;}.page { height: 100%; overflow: auto;}.fixed { position: absolute;}
首先同時(shí)適配移動(dòng)端隱藏根的滾動(dòng)條,然后自行生成一個(gè)page容器來(lái)配置滾動(dòng)條,最后將絕對(duì)定位元素脫離文檔流塞進(jìn)去。
由于這個(gè)絕對(duì)定位元素不在這個(gè)滾動(dòng)容器內(nèi),所以它不會(huì)滾動(dòng),ok符合第一種情況,然后自身絕對(duì)定位,可以使用relative或者overflow等定位剪裁,滿足第二個(gè)情況。那么這種模擬可以應(yīng)用在哪種場(chǎng)景呢?比如說(shuō)我們有一個(gè)Modal框點(diǎn)擊然后會(huì)彈出一個(gè)蒙層,如果通過(guò)fixed定位,蒙層會(huì)無(wú)法覆蓋瀏覽器右側(cè)的滾動(dòng)欄,即當(dāng)有滾動(dòng)條時(shí),背景內(nèi)容在蒙層下依舊可以滾動(dòng),無(wú)法被鎖定,但是如果用absolute模擬這種問(wèn)題就被修復(fù)了。不過(guò),如果我們的頁(yè)面結(jié)構(gòu)已經(jīng)固定了,不太適合全局調(diào)整的時(shí)候,可以結(jié)合JS,移動(dòng)端,我們阻止touchmove事件就能防止?jié)L動(dòng),PC端可以通過(guò)overflow: hidden來(lái)隱藏,但這么玩前文中有記錄,會(huì)導(dǎo)致頁(yè)面晃動(dòng),因?yàn)闈L動(dòng)框也占據(jù)了可視寬度,我們可以通過(guò)透明border修復(fù)這個(gè)問(wèn)題:var widthBar = 17; var root = document.documentElement;if (typeof window.innerWidth == 'number') { widthBar = window.innerWidth - root.clientWidth;}root.style.overflow = 'hidden';root.style.borderRight = widthBar + 'px solid transparent';
var root = document.documentElement;root.style.overflow = '';root.style.borderRight = '';
159、CSS層疊上下文和層疊水平:其實(shí)關(guān)于層疊的問(wèn)題,我在<<CSS特指度與布局層疊順序>>一文中曾經(jīng)結(jié)合水印需求討論過(guò)一次,不過(guò)那個(gè)時(shí)候其實(shí)只是取了作者博客中的一張圖示,在這本書(shū)中其實(shí)有更為細(xì)致的講解:①誰(shuí)大誰(shuí)上:當(dāng)具有明顯的層疊水平標(biāo)識(shí)時(shí),如z-index,在同一層疊上下文領(lǐng)域,層疊水平值大的那一個(gè)覆蓋小的那一個(gè)。②后來(lái)居上:當(dāng)元素層疊水平一致、順序相同時(shí),DOM流處于后面的元素會(huì)覆蓋前面的元素。③獨(dú)立性:每個(gè)層疊上下文和兄弟元素獨(dú)立,進(jìn)行層疊變化或渲染的時(shí)候,只需要考慮自身的后代元素;且元素發(fā)生層疊的時(shí)候,整個(gè)元素被認(rèn)為在其父元素的層疊上下文當(dāng)中。⑤對(duì)于position為relative/absolute以及FF/IE下含有position: fixed的元素(注意不包括Chrome),當(dāng)它們的z-index不是auto時(shí),會(huì)創(chuàng)建層疊上下文。這里可以參見(jiàn)一個(gè)提供的DEMO。從DEMO中看到,當(dāng)元素默認(rèn)z-index是auto的時(shí)候就是一個(gè)普通定位元素,容器內(nèi)的元素進(jìn)行層疊比較將不會(huì)受到父級(jí)的影響,可以通過(guò)①和②的規(guī)律來(lái)判斷。就算z-index的值為0,它也會(huì)創(chuàng)建層疊上下文。所以DEMO中,相當(dāng)于后面的覆蓋了之前的,內(nèi)部由于兩塊都是獨(dú)立的層疊上下文,都作用在自己的父容器當(dāng)中,故不會(huì)作用于外面對(duì)比,真正進(jìn)行比較的是兩個(gè)父容器。另外,作者提及在IE6/IE7下,z-index: auto同樣會(huì)創(chuàng)建層疊上下文;以前的position: fixed跟absolute/relative一樣都需要z-index有值才會(huì)產(chǎn)生層疊,但是后面,在-webkit-內(nèi)核的瀏覽器中fixed定位不需要z-index就可以產(chǎn)生層疊,而IE和FF還是和以前保持一致。160、clip從英文看就可以知道是個(gè)剪裁屬性,并且它僅在position為fixed或absolute時(shí)生效,它的基本語(yǔ)法為clip: rect(top right bottom left),clip: rect(top, right, bottom, left)這種有逗號(hào)的寫(xiě)法其實(shí)才是標(biāo)準(zhǔn)的,不過(guò)前者兼容性更好,IE6、IE7也支持,并且字符更少。那么它的應(yīng)用場(chǎng)景在那里呢?①首先是對(duì)fixed定位進(jìn)行裁剪,因?yàn)閒ixed本身的包含塊是html,overflow雖然也能進(jìn)行剪裁作用,但是它主要還是應(yīng)用于普通元素或絕對(duì)定位元素,對(duì)fixed元素除了滾動(dòng)條區(qū)域,其他區(qū)域也沒(méi)辦法操作。②隱藏主頁(yè)上SEO的文本,僅展示圖片,比如:
<a href="/" class="logo"> <h1>CSS世界</h1></a>
.logo h1 { position: absolute; clip: rect(0 0 0 0); }
這種做法與其他的一些隱藏做法相比優(yōu)勢(shì)在于具有更強(qiáng)的普適性,任何元素和場(chǎng)景都可以無(wú)障礙使用(我們前文有記錄過(guò)一些隱藏元素的方案,但是像vibility: hidden;,display: none,text-indent: 足夠到屏幕外的負(fù)值這些最終都會(huì)導(dǎo)致屏幕閱讀設(shè)備無(wú)法讀取)。同時(shí)元素原本的行為特征也被保留,比如原本能夠被focus的元素,即使剪裁了依舊能夠繼續(xù)focus,再利用”無(wú)依賴絕對(duì)定位”的特性可以實(shí)現(xiàn)一種替換默認(rèn)按鈕樣式的hack操作。文中提供了一個(gè)使用關(guān)聯(lián)label替代input的提交按鈕做法:
.clip { position: absolute; clip: rect(0 0 0 0);}
<form> <input type="submit" id="someID" class="clip"> <label for="someID">提交</label></form>
以上,書(shū)中有一種”可訪問(wèn)隱藏”的叫法我覺(jué)得挺不錯(cuò)的,并且在如何進(jìn)行隱藏的方案中,color: transparent是移動(dòng)端推薦的做法,但是在PC端IE8瀏覽器并不支持。作者對(duì)clip的總結(jié):
①clip隱藏僅僅是決定哪部分可見(jiàn),非可見(jiàn)部分無(wú)法響應(yīng)點(diǎn)擊事件;
②視覺(jué)上隱藏,但是元素尺寸依然是原本尺寸;IE/FF瀏覽器下抹去了不可見(jiàn)區(qū)域尺寸對(duì)布局的影響比如生成的滾動(dòng)條,Chrome則保留了影響。學(xué)習(xí)更多技能
請(qǐng)點(diǎn)擊下方公眾號(hào)

