選擇器 | 格式 | 優(yōu)先級權(quán)重 |
---|---|---|
id選擇器 | #id | 100 |
類選擇器 | .classname | 10 |
屬性選擇器 | a[ref=“eee”] | 10 |
偽類選擇器 | li:last-child | 10 |
標簽選擇器 | div | 1 |
偽元素選擇器 | li:after | 1 |
相鄰兄弟選擇器 | h1+p | 0 |
子選擇器 | ul>li | 0 |
后代選擇器 | li a | 0 |
通配符選擇器 | * | 0 |
對于選擇器的優(yōu)先級:
注意事項:
屬性值 | 作用 |
---|---|
none | 元素不顯示,并且會從文檔流中移除。 |
block | 塊類型。默認寬度為父元素寬度,可設(shè)置寬高,換行顯示。 |
inline | 行內(nèi)元素類型。默認寬度為內(nèi)容寬度,不可設(shè)置寬高,同行顯示。 |
inline-block | 默認寬度為內(nèi)容寬度,可以設(shè)置寬高,同行顯示。 |
list-item | 像塊類型元素一樣顯示,并添加樣式列表標記。 |
table | 此元素會作為塊級表格來顯示。 |
inherit | 規(guī)定應(yīng)該從父元素繼承display屬性的值。 |
(1)block:會獨占一行,多個元素會另起一行,可以設(shè)置width、height、margin和padding屬性;
(2)inline:元素不會獨占一行,設(shè)置width、height屬性無效。但可以設(shè)置水平方向的margin和padding屬性,不能設(shè)置垂直方向的padding和margin;
(3)inline-block:將對象設(shè)置為inline對象,但對象的內(nèi)容作為block對象呈現(xiàn),之后的內(nèi)聯(lián)對象會被排列在同一行內(nèi)。
對于行內(nèi)元素和塊級元素,其特點如下:
(1)行內(nèi)元素
(2)塊級元素
兩者都是外部引用CSS的方式,它們的區(qū)別如下:
這兩個屬性都是讓元素隱藏,不可見。兩者區(qū)別如下:
(1)在渲染樹中
display:none
?會讓元素完全從渲染樹中消失,渲染時不會占據(jù)任何空間;visibility:hidden
?不會讓元素從渲染樹中消失,渲染的元素還會占據(jù)相應(yīng)的空間,只是內(nèi)容不可見。(2)是否是繼承屬性
display:none
?是非繼承屬性,子孫節(jié)點會隨著父節(jié)點從渲染樹消失,通過修改子孫節(jié)點的屬性也無法顯示;visibility:hidden
? 是繼承屬性,子孫節(jié)點消失是由于繼承了 ?hidden
?,通過設(shè)置 ?visibility:visible
? 可以讓子孫節(jié)點顯示;(3)修改常規(guī)文檔流中元素的 ?display
?通常會造成文檔的重排,但是修改 ?visibility
? 屬性只會造成本元素的重繪;
(4)如果使用讀屏器,設(shè)置為 ?display:none
? 的內(nèi)容不會被讀取,設(shè)置為 ?visibility:hidden
? 的內(nèi)容會被讀取。
p::before {content:"第一章:";}
p::after {content:"Hot!";}
p::first-line {background:red;}
p::first-letter {font-size:30px;}
a:hover {color: #FF00FF}
p:first-child {color: red}
總結(jié):偽類是通過在元素選擇器上加?偽類改變元素狀態(tài),?偽元素通過對元素的操作進?對元素的改變。
實現(xiàn)動畫效果的方法比較多,Javascript 中可以通過定時器 setTimeout 來實現(xiàn),CSS3 中可以使用 transition 和 animation 來實現(xiàn),HTML5 中的 canvas 也可以實現(xiàn)。除此之外,HTML5 提供一個專門用于請求動畫的API,那就是 requestAnimationFrame,顧名思義就是請求動畫幀。
MDN對該方法的描述:
window.requestAnimationFrame() 告訴瀏覽器——你希望執(zhí)行一個動畫,并且要求瀏覽器在下次重繪之前調(diào)用指定的回調(diào)函數(shù)更新動畫。該方法需要傳入一個回調(diào)函數(shù)作為參數(shù),該回調(diào)函數(shù)會在瀏覽器下一次重繪之前執(zhí)行。
語法: window.requestAnimationFrame(callback);
其中,callback是下一次重繪之前更新動畫幀所調(diào)用的函數(shù)(即上面所說的回調(diào)函數(shù))。該回調(diào)函數(shù)會被傳入DOMHighResTimeStamp參數(shù),它表示requestAnimationFrame() 開始去執(zhí)行回調(diào)函數(shù)的時刻。該方法屬于宏任務(wù),所以會在執(zhí)行完微任務(wù)之后再去執(zhí)行。
取消動畫:使用cancelAnimationFrame()來取消執(zhí)行動畫,該方法接收一個參數(shù)——requestAnimationFrame默認返回的id,只需要傳入這個id就可以取消動畫了。
優(yōu)勢:
setTimeout執(zhí)行動畫的缺點:它通過設(shè)定間隔時間來不斷改變圖像位置,達到動畫效果。但是容易出現(xiàn)卡頓、抖動的現(xiàn)象;原因是:
CSS3中的盒模型有以下兩種:標準盒子模型、IE盒子模型
盒模型都是由四個部分組成的,分別是margin、border、padding和content。
標準盒模型和IE盒模型的區(qū)別在于設(shè)置width和height時,所對應(yīng)的范圍不同:
可以通過修改元素的box-sizing屬性來改變元素的盒模型:
box-sizeing: content-box
?表示標準盒模型(默認值)box-sizeing: border-box
?表示IE盒模型(怪異盒模型)translate 是 transform 屬性的?個值。改變transform或opacity不會觸發(fā)瀏覽器重新布局(reflow)或重繪(repaint),只會觸發(fā)復(fù)合(compositions)。?改變絕對定位會觸發(fā)重新布局,進?觸發(fā)重繪和復(fù)合。transform使瀏覽器為元素創(chuàng)建?個 GPU 圖層,但改變絕對定位會使?到 CPU。 因此translate()更?效,可以縮短平滑動畫的繪制時間。 ?translate改變位置時,元素依然會占據(jù)其原始空間,絕對定位就不會發(fā)?這種情況。
瀏覽器會把inline內(nèi)聯(lián)元素間的空白字符(空格、換行、Tab等)渲染成一個空格。為了美觀,通常是一個 <li>
放在一行,這導(dǎo)致 <li>
換行后產(chǎn)生換行字符,它變成一個空格,占用了一個字符的寬度。
解決辦法:
(1)為 ?<li>
?設(shè)置float:left。不足:有些容器是不能設(shè)置浮動,如左右切換的焦點圖等。
(2)將所有 ?<li>
?寫在同一行。不足:代碼不美觀。
(3)將 ?<ul>
?內(nèi)的字符尺寸直接設(shè)為0,即font-size:0。不足:?<ul>
?中的其他字符尺寸也被設(shè)為0,需要額外重新設(shè)定其他字符尺寸,且在Safari瀏覽器依然會出現(xiàn)空白間隔。
(4)消除 ?<ul>
?的字符間隔letter-spacing:-8px,不足:這也設(shè)置了 ?<li>
?內(nèi)的字符間隔,因此需要將 ?<li>
?內(nèi)的字符間隔設(shè)為默認letter-spacing:normal。
img、input、textarea、select
通過修改某個屬性值呈現(xiàn)的內(nèi)容就可以被替換的元素就稱為“替換元素”。
替換元素除了內(nèi)容可替換這一特性以外,還有以下特性:
替換元素的尺寸從內(nèi)而外分為三類:
這三層結(jié)構(gòu)的計算規(guī)則具體如下:
(1)如果沒有CSS尺寸和HTML尺寸,則使用固有尺寸作為最終的寬高。
(2)如果沒有CSS尺寸,則使用HTML尺寸作為最終的寬高。
(3)如果有CSS尺寸,則最終尺寸由CSS屬性決定。
(4)如果“固有尺寸”含有固有的寬高比例,同時僅設(shè)置了寬度或僅設(shè)置了高度,則元素依然按照固有的寬高比例顯示。
(5)如果上面的條件都不符合,則最終寬度表現(xiàn)為300像素,高度為150像素。
(6)內(nèi)聯(lián)替換元素和塊級替換元素使用上面同一套尺寸計算規(guī)則。
(1)BMP,是無損的、既支持索引色也支持直接色的點陣圖。這種圖片格式幾乎沒有對數(shù)據(jù)進行壓縮,所以BMP格式的圖片通常是較大的文件。
(2)GIF是無損的、采用索引色的點陣圖。采用LZW壓縮算法進行編碼。文件小,是GIF格式的優(yōu)點,同時,GIF格式還具有支持動畫以及透明的優(yōu)點。但是GIF格式僅支持8bit的索引色,所以GIF格式適用于對色彩要求不高同時需要文件體積較小的場景。
(3)JPEG是有損的、采用直接色的點陣圖。JPEG的圖片的優(yōu)點是采用了直接色,得益于更豐富的色彩,JPEG非常適合用來存儲照片,與GIF相比,JPEG不適合用來存儲企業(yè)Logo、線框類的圖。因為有損壓縮會導(dǎo)致圖片模糊,而直接色的選用,又會導(dǎo)致圖片文件較GIF更大。
(4)PNG-8是無損的、使用索引色的點陣圖。PNG是一種比較新的圖片格式,PNG-8是非常好的GIF格式替代者,在可能的情況下,應(yīng)該盡可能的使用PNG-8而不是GIF,因為在相同的圖片效果下,PNG-8具有更小的文件體積。除此之外,PNG-8還支持透明度的調(diào)節(jié),而GIF并不支持。除非需要動畫的支持,否則沒有理由使用GIF而不是PNG-8。
(5)PNG-24是無損的、使用直接色的點陣圖。PNG-24的優(yōu)點在于它壓縮了圖片的數(shù)據(jù),使得同樣效果的圖片,PNG-24格式的文件大小要比BMP小得多。當然,PNG24的圖片還是要比JPEG、GIF、PNG-8大得多。
(6)SVG是無損的矢量圖。SVG是矢量圖意味著SVG圖片由直線和曲線以及繪制它們的方法組成。當放大SVG圖片時,看到的還是線和曲線,而不會出現(xiàn)像素點。SVG圖片在放大時,不會失真,所以它適合用來繪制Logo、Icon等。
(7)WebP是谷歌開發(fā)的一種新圖片格式,WebP是同時支持有損和無損壓縮的、使用直接色的點陣圖。從名字就可以看出來它是為Web而生的,什么叫為Web而生呢?就是說相同質(zhì)量的圖片,WebP具有更小的文件體積?,F(xiàn)在網(wǎng)站上充滿了大量的圖片,如果能夠降低每一個圖片的文件大小,那么將大大減少瀏覽器和服務(wù)器之間的數(shù)據(jù)傳輸量,進而降低訪問延遲,提升訪問體驗。目前只有Chrome瀏覽器和Opera瀏覽器支持WebP格式,兼容性不太好。
CSSSprites(精靈圖),將一個頁面涉及到的所有圖片都包含到一張大圖中去,然后利用CSS的 background-image,background-repeat,background-position屬性的組合進行背景定位。
優(yōu)點:
CSS Sprites
?能很好地減少網(wǎng)頁的http請求,從而大大提高了頁面的性能,這是 ?CSS Sprites
?最大的優(yōu)點;CSS Sprites
?能減少圖片的字節(jié),把3張圖片合并成1張圖片的字節(jié)總是小于這3張圖片的字節(jié)總和。缺點:
CSSSprites
?在開發(fā)的時候相對來說有點麻煩,需要借助 ?photoshop
?或其他工具來對每個背景單元測量其準確的位置。CSS Sprites
?在維護的時候比較麻煩,頁面背景有少許改動時,就要改這張合并的圖片,無需改的地方盡量不要動,這樣避免改動更多的 ?CSS
?,如果在原來的地方放不下,又只能(最好)往下加圖片,這樣圖片的字節(jié)就增加了,還要改動 ?CSS
?。以 iPhone XS 為例,當寫 CSS 代碼時,針對于單位 px,其寬度為 414px & 896px,也就是說當賦予一個 DIV元素寬度為 414px,這個 DIV 就會填滿手機的寬度;
而如果有一把尺子來實際測量這部手機的物理像素,實際為 1242*2688 物理像素;經(jīng)過計算可知,1242/414=3,也就是說,在單邊上,一個邏輯像素=3個物理像素,就說這個屏幕的像素密度為 3,也就是常說的 3 倍屏。
對于圖片來說,為了保證其不失真,1 個圖片像素至少要對應(yīng)一個物理像素,假如原始圖片是 500300 像素,那么在 3 倍屏上就要放一個 1500900 像素的圖片才能保證 1 個物理像素至少對應(yīng)一個圖片像素,才能不失真。
當然,也可以針對所有屏幕,都只提供最高清圖片。雖然低密度屏幕用不到那么多圖片像素,而且會因為下載多余的像素造成帶寬浪費和下載延遲,但從結(jié)果上說能保證圖片在所有屏幕上都不會失真。
還可以使用 CSS 媒體查詢來判斷不同的像素密度,從而選擇不同的圖片:
my-image { background: (low.png); }
@media only screen and (min-device-pixel-ratio: 1.5) {
#my-image { background: (high.png); }
}
(1)line-height的概念:
(2)line-height 的賦值方式:
加載性能:
(1)css壓縮:將寫好的css進行打包壓縮,可以減小文件體積。
(2)css單一樣式:當需要下邊距和左邊距的時候,很多時候會選擇使用 margin:top 0 bottom 0;但margin-bottom:bottom;margin-left:left;執(zhí)行效率會更高。
(3)減少使用@import,建議使用link,因為后者在頁面加載時一起加載,前者是等待頁面加載完成之后再進行加載。
選擇器性能:
(1)關(guān)鍵選擇器(key selector)。選擇器的最后面的部分為關(guān)鍵選擇器(即用來匹配目標元素的部分)。CSS選擇符是從右到左進行匹配的。當使用后代選擇器的時候,瀏覽器會遍歷所有子元素來確定是否是指定的元素等等;
(2)如果規(guī)則擁有ID選擇器作為其關(guān)鍵選擇器,則不要為規(guī)則增加標簽。過濾掉無關(guān)的規(guī)則(這樣樣式系統(tǒng)就不會浪費時間去匹配它們了)。
(3)避免使用通配規(guī)則,如*{}計算次數(shù)驚人,只對需要用到的元素進行選擇。
(4)盡量少的去對標簽進行選擇,而是用class。
(5)盡量少的去使用后代選擇器,降低選擇器的權(quán)重值。后代選擇器的開銷是最高的,盡量將選擇器的深度降到最低,最高不要超過三層,更多的使用類來關(guān)聯(lián)每一個標簽元素。
(6)了解哪些屬性是可以通過繼承而來的,然后避免對這些屬性重復(fù)指定規(guī)則。
渲染性能:
(1)慎重使用高性能屬性:浮動、定位。
(2)盡量減少頁面重排、重繪。
(3)去除空規(guī)則:{}??找?guī)則的產(chǎn)生原因一般來說是為了預(yù)留樣式。去除這些空規(guī)則無疑能減少css文檔體積。
(4)屬性值為0時,不加單位。
(5)屬性值為浮動小數(shù)0.**,可以省略小數(shù)點之前的0。
(6)標準化各種瀏覽器前綴:帶瀏覽器前綴的在前。標準屬性在后。
(7)不使用@import前綴,它會影響css的加載速度。
(8)選擇器優(yōu)化嵌套,盡量避免層級過深。
(9)css雪碧圖,同一頁面相近部分的小圖標,方便使用,減少頁面的請求次數(shù),但是同時圖片本身會變大,使用時,優(yōu)劣考慮清楚,再使用。
(10)正確使用display的屬性,由于display的作用,某些樣式組合會無效,徒增樣式體積的同時也影響解析性能。
(11)不濫用web字體。對于中文網(wǎng)站來說WebFonts可能很陌生,國外卻很流行。web fonts通常體積龐大,而且一些瀏覽器在下載web fonts時會阻塞頁面渲染損傷性能。
可維護性、健壯性:
(1)將具有相同屬性的樣式抽離出來,整合并通過class在頁面中進行使用,提高css的可維護性。
(2)樣式與內(nèi)容分離:將css代碼定義到外部css中。
預(yù)處理器,如:less
,sass
,stylus
,用來預(yù)編譯 sass
或者 less
,增加了 css
代碼的復(fù)用性。層級,mixin
, 變量,循環(huán), 函數(shù)等對編寫以及開發(fā)UI組件都極為方便。
后處理器, 如: postCss
,通常是在完成的樣式表中根據(jù) css
規(guī)范處理 css
,讓其更加有效。目前最常做的是給 css
屬性添加瀏覽器私有前綴,實現(xiàn)跨瀏覽器兼容性的問題。
css
預(yù)處理器為 css
增加一些編程特性,無需考慮瀏覽器的兼容問題,可以在 CSS
中使用變量,簡單的邏輯程序,函數(shù)等在編程語言中的一些基本的性能,可以讓 css
更加的簡潔,增加適應(yīng)性以及可讀性,可維護性等。
其它 css
預(yù)處理器語言:Sass(Scss)
, Less
, Stylus
, Turbine
, Swithch css
, CSS Cacheer
, DT Css
。
使用原因:
CSS
?代碼,可以應(yīng)用到老項目中(1)冒號(:
)用于 CSS3
偽類,雙冒號(::
)用于 CSS3
偽元素。
(2)::before
就是以一個子元素的存在,定義在元素主體內(nèi)容之前的一個偽元素。并不存在于 dom
之中,只存在在頁面之中。
注意: :before
和 :after
這兩個偽元素,是在 CSS2.1
里新出現(xiàn)的。起初,偽元素的前綴使用的是單冒號語法,但隨著 Web
的進化,在 CSS3
的規(guī)范里,偽元素的語法被修改成使用雙冒號,成為 ::before
、::after
。
margin
?正值時,可以讓 ?margin
?使用負值解決;font-size
?時,可通過設(shè)置 ?font-size:0
?、?letter-spacing
?、?word-spacing
?解決;overflow: hidden; // 溢出隱藏
text-overflow: ellipsis; // 溢出用省略號顯示
white-space: nowrap; // 規(guī)定段落中的文本不進行換行
overflow: hidden; // 溢出隱藏
text-overflow: ellipsis; // 溢出用省略號顯示
display:-webkit-box; // 作為彈性伸縮盒子模型顯示。
-webkit-box-orient:vertical; // 設(shè)置伸縮盒子的子元素排列方式:從上到下垂直排列
-webkit-line-clamp:3; // 顯示的行數(shù)
注意:由于上面的三個屬性都是 CSS3 的屬性,沒有瀏覽器可以兼容,所以要在前面加一個 -webkit-
來兼容一部分瀏覽器。
他們都是 CSS 預(yù)處理器,是 CSS 上的一種抽象層。他們是一種特殊的語法/語言編譯成 CSS。 例如 Less 是一種動態(tài)樣式語言,將 CSS 賦予了動態(tài)語言的特性,如變量,繼承,運算, 函數(shù),LESS 既可以在客戶端上運行 (支持 IE 6+, Webkit, Firefox),也可以在服務(wù)端運行 (借助 Node.js)。
為什么要使用它們?
媒體查詢由?個可選的媒體類型和零個或多個使?媒體功能的限制了樣式表范圍的表達式組成,例如寬度、?度和顏?。媒體查詢,添加?CSS3,允許內(nèi)容的呈現(xiàn)針對?個特定范圍的輸出設(shè)備?進?裁剪,?不必改變內(nèi)容本身,適合web??應(yīng)對不同型號的設(shè)備?做出對應(yīng)的響應(yīng)適配。
媒體查詢包含?個可選的媒體類型和滿?CSS3規(guī)范的條件下,包含零個或多個表達式,這些表達式描述了媒體特征,最終會被解析為true或false。如果媒體查詢中指定的媒體類型匹配展示?檔所使?的設(shè)備類型,并且所有的表達式的值都是true,那么該媒體查詢的結(jié)果為true。那么媒體查詢內(nèi)的樣式將會?效。
<!-- link元素中的CSS媒體查詢 -->
<link rel="stylesheet" media="(max-width: 800px)" href="example.css" />
<!-- 樣式表中的CSS媒體查詢 -->
<style>
@media (max-width: 600px) {
.facet_sidebar {
display: none;
}
}
</style>
簡單來說,使用 @media 查詢,可以針對不同的媒體類型定義不同的樣式。@media 可以針對不同的屏幕尺寸設(shè)置不同的樣式,特別是需要設(shè)置設(shè)計響應(yīng)式的頁面,@media 是非常有用的。當重置瀏覽器大小的過程中,頁面也會根據(jù)瀏覽器的寬度和高度重新渲染頁面。
CSS 工程化是為了解決以下問題:
以下三個方向都是時下比較流行的、普適性非常好的 CSS 工程化實踐:
基于這三個方向,可以衍生出一些具有典型意義的子問題,這里我們逐個來看:
(1)預(yù)處理器:為什么要用預(yù)處理器?它的出現(xiàn)是為了解決什么問題?
預(yù)處理器,其實就是 CSS 世界的“輪子”。預(yù)處理器支持我們寫一種類似 CSS、但實際并不是 CSS 的語言,然后把它編譯成 CSS 代碼:
那為什么寫 CSS 代碼寫得好好的,偏偏要轉(zhuǎn)去寫“類 CSS”呢?這就和本來用 JS 也可以實現(xiàn)所有功能,但最后卻寫 React 的 jsx 或者 Vue 的模板語法一樣——為了爽!要想知道有了預(yù)處理器有多爽,首先要知道的是傳統(tǒng) CSS 有多不爽。隨著前端業(yè)務(wù)復(fù)雜度的提高,前端工程中對 CSS 提出了以下的訴求:
這三點是傳統(tǒng) CSS 所做不到的,也正是預(yù)處理器所解決掉的問題。預(yù)處理器普遍會具備這樣的特性:
(2)PostCss:PostCss 是如何工作的?我們在什么場景下會使用 PostCss?
PostCss 仍然是一個對 CSS 進行解析和處理的工具,它會對 CSS 做這樣的事情:
它和預(yù)處理器的不同就在于,預(yù)處理器處理的是 類CSS,而 PostCss 處理的就是 CSS 本身。Babel 可以將高版本的 JS 代碼轉(zhuǎn)換為低版本的 JS 代碼。PostCss 做的是類似的事情:它可以編譯尚未被瀏覽器廣泛支持的先進的 CSS 語法,還可以自動為一些需要額外兼容的語法增加前綴。更強的是,由于 PostCss 有著強大的插件機制,支持各種各樣的擴展,極大地強化了 CSS 的能力。
PostCss 在業(yè)務(wù)中的使用場景非常多:
(3)Webpack 能處理 CSS 嗎?如何實現(xiàn)?
Webpack 能處理 CSS 嗎:
如何用 Webpack 實現(xiàn)對 CSS 的處理:
在實際使用中,css-loader 的執(zhí)行順序一定要安排在 style-loader 的前面。因為只有完成了編譯過程,才可以對 css 代碼進行插入;若提前插入了未編譯的代碼,那么 webpack 是無法理解這坨東西的,它會無情報錯。
以圖片顯示為例:
window.innerHeight
? 是瀏覽器可視區(qū)的高度;document.body.scrollTop || document.documentElement.scrollTop
? 是瀏覽器滾動的過的距離;imgs.offsetTop
? 是元素頂部距離文檔頂部的高度(包括滾動條的距離);img.offsetTop < window.innerHeight + document.body.scrollTop;
?
通常 z-index 的使用是在有兩個重疊的標簽,在一定的情況下控制其中一個在另一個的上方或者下方出現(xiàn)。z-index值越大就越是在上層。z-index元素的position屬性需要是relative,absolute或是fixed。
z-index屬性在下列情況下會失效:
首先將獲得1px 與 vw之前的比例關(guān)系 再將html標簽中的font-size定義為多少vw 然后就使用rem來作為單位 常用的布局單位包括像素(px
),百分比(%
),em
,rem
,vw/vh
。
(1)像素(px
)是頁面布局的基礎(chǔ),一個像素表示終端(電腦、手機、平板等)屏幕所能顯示的最小的區(qū)域,像素分為兩種類型:CSS像素和物理像素:
(2)百分比(%
),當瀏覽器的寬度或者高度發(fā)生變化時,通過百分比單位可以使得瀏覽器中的組件的寬和高隨著瀏覽器的變化而變化,從而實現(xiàn)響應(yīng)式的效果。一般認為子元素的百分比相對于直接父元素。
(3)em和rem相對于px更具靈活性,它們都是相對長度單位,它們之間的區(qū)別:em相對于父元素,rem相對于根元素。
(4)vw/vh是與視圖窗口有關(guān)的單位,vw表示相對于視圖窗口的寬度,vh表示相對于視圖窗口高度,除了vw和vh外,還有vmin和vmax兩個相關(guān)的單位。
vw/vh 和百分比很類似,兩者的區(qū)別:
%
?):大部分相對于祖先元素,也有相對于自身的情況比如(border-radius、translate等)三者的區(qū)別:
使用場景:
一般兩欄布局指的是左邊一欄寬度固定,右邊一欄寬度自適應(yīng),兩欄布局的具體實現(xiàn):
.outer {
height: 100px;
}
.left {
float: left;
width: 200px;
background: tomato;
}
.right {
margin-left: 200px;
width: auto;
background: gold;
}
.left{
width: 100px;
height: 200px;
background: red;
float: left;
}
.right{
height: 300px;
background: blue;
overflow: hidden;
}
.outer {
display: flex;
height: 100px;
}
.left {
width: 200px;
background: tomato;
}
.right {
flex: 1;
background: gold;
}
.outer {
position: relative;
height: 100px;
}
.left {
position: absolute;
width: 200px;
height: 100px;
background: tomato;
}
.right {
margin-left: 200px;
background: gold;
}
.outer {
position: relative;
height: 100px;
}
.left {
width: 200px;
background: tomato;
}
.right {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 200px;
background: gold;
}
三欄布局一般指的是頁面中一共有三欄,左右兩欄寬度固定,中間自適應(yīng)的布局,三欄布局的具體實現(xiàn):
.outer {
position: relative;
height: 100px;
}
.left {
position: absolute;
width: 100px;
height: 100px;
background: tomato;
}
.right {
position: absolute;
top: 0;
right: 0;
width: 200px;
height: 100px;
background: gold;
}
.center {
margin-left: 100px;
margin-right: 200px;
height: 100px;
background: lightgreen;
}
.outer {
display: flex;
height: 100px;
}
.left {
width: 100px;
background: tomato;
}
.right {
width: 100px;
background: gold;
}
.center {
flex: 1;
background: lightgreen;
}
.outer {
height: 100px;
}
.left {
float: left;
width: 100px;
height: 100px;
background: tomato;
}
.right {
float: right;
width: 200px;
height: 100px;
background: gold;
}
.center {
height: 100px;
margin-left: 100px;
margin-right: 200px;
background: lightgreen;
}
.outer {
height: 100px;
padding-left: 100px;
padding-right: 200px;
}
.left {
position: relative;
left: -100px;
float: left;
margin-left: -100%;
width: 100px;
height: 100px;
background: tomato;
}
.right {
position: relative;
left: 200px;
float: right;
margin-left: -200px;
width: 200px;
height: 100px;
background: gold;
}
.center {
float: left;
width: 100%;
height: 100px;
background: lightgreen;
}
.outer {
height: 100px;
}
.left {
float: left;
margin-left: -100%;
width: 100px;
height: 100px;
background: tomato;
}
.right {
float: left;
margin-left: -200px;
width: 200px;
height: 100px;
background: gold;
}
.wrapper {
float: left;
width: 100%;
height: 100px;
background: lightgreen;
}
.center {
margin-left: 100px;
margin-right: 200px;
height: 100px;
}
.parent {
position: relative;
}
.child {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
.parent {
position: relative;
}
.child {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
margin-top: -50px; /* 自身 height 的一半 */
margin-left: -50px; /* 自身 width 的一半 */
}
.parent {
display: flex;
justify-content:center;
align-items:center;
}
移動端適配主要有兩個維度:
為了能讓頁面的尺寸自適應(yīng),可以使用 rem,em,vw,vh 等相對單位。
Flex是FlexibleBox的縮寫,意為"彈性布局",用來為盒狀模型提供最大的靈活性。任何一個容器都可以指定為Flex布局。行內(nèi)元素也可以使用Flex布局。注意,設(shè)為Flex布局以后,子元素的float、clear和vertical-align屬性將失效。采用Flex布局的元素,稱為Flex容器(flex container),簡稱"容器"。它的所有子元素自動成為容器成員,稱為Flex項目(flex item),簡稱"項目"。容器默認存在兩根軸:水平的主軸(main
axis)和垂直的交叉軸(cross axis),項目默認沿水平主軸排列。
以下6個屬性設(shè)置在容器上:
以下6個屬性設(shè)置在項目上:
簡單來說:
flex布局是CSS3新增的一種布局方式,可以通過將一個元素的display屬性值設(shè)置為flex從而使它成為一個flex容器,它的所有子元素都會成為它的項目。一個容器默認有兩條軸:一個是水平的主軸,一個是與主軸垂直的交叉軸。可以使用flex-direction來指定主軸的方向??梢允褂胘ustify-content來指定元素在主軸上的排列方式,使用align-items來指定元素在交叉軸上的排列方式。還可以使用flex-wrap來規(guī)定當一行排列不下時的換行方式。對于容器中的項目,可以使用order屬性來指定項目的排列順序,還可以使用flex-grow來指定當排列空間有剩余的時候,項目的放大比例,還可以使用flex-shrink來指定當排列空間不足時,項目的縮小比例。
響應(yīng)式網(wǎng)站設(shè)計 (Responsive Web design
)是一個網(wǎng)站能夠兼容多個終端,而不是為每一個終端做一個特定的版本。
關(guān)于原理: 基本原理是通過媒體查詢 (@media)
查詢檢測不同的設(shè)備屏幕尺寸做處理。
關(guān)于兼容: 頁面頭部必須有mate聲明的 viewport
。
<meta name="’viewport’" content="”width=device-width," initial-scale="1." maximum-scale="1,user-scalable=no”"/>
浮動的定義: 非IE瀏覽器下,容器不設(shè)高度且子元素浮動時,容器高度不能被內(nèi)容撐開。 此時,內(nèi)容會溢出到容器外面而影響布局。這種現(xiàn)象被稱為浮動(溢出)。
浮動的工作原理:
浮動元素可以左右移動,直到遇到另一個浮動元素或者遇到它外邊緣的包含框。浮動框不屬于文檔流中的普通流,當元素浮動之后,不會影響塊級元素的布局,只會影響內(nèi)聯(lián)元素布局。此時文檔流中的普通流就會表現(xiàn)得該浮動框不存在一樣的布局模式。當包含框的高度小于浮動框的時候,此時就會出現(xiàn)“高度塌陷”。
浮動元素引起的問題?
清除浮動的方式如下:
height
?屬性clear:both
?樣式overflow:hidden
?或者 ?overflow:auto
?.clearfix:after{
content: "\200B";
display: table;
height: 0;
clear: both;
}
.clearfix{
*zoom: 1;
}
使用clear屬性清除浮動,其語法如下:
clear:none|left|right|both
如果單看字面意思,clear:left 是“清除左浮動”,clear:right 是“清除右浮動”,實際上,這種解釋是有問題的,因為浮動一直還在,并沒有清除。
官方對clear屬性解釋:“元素盒子的邊不能和前面的浮動元素相鄰”,對元素設(shè)置clear屬性是為了避免浮動元素對該元素的影響,而不是清除掉浮動。
還需要注意 clear 屬性指的是元素盒子的邊不能和前面的浮動元素相鄰,注意這里“前面的”3個字,也就是clear屬性對“后面的”浮動元素是不聞不問的??紤]到float屬性要么是left,要么是right,不可能同時存在,同時由于clear屬性對“后面的”浮動元素不聞不問,因此,當clear:left有效的時候,clear:right必定無效,也就是此時clear:left等同于設(shè)置clear:both;同樣地,clear:right如果有效也是等同于設(shè)置clear:both。由此可見,clear:left和clear:right這兩個聲明就沒有任何使用的價值,至少在CSS世界中是如此,直接使用clear:both吧。
一般使用偽元素的方式清除浮動:
.clear::after{
content:'';
display: block;
clear:both;
}
clear屬性只有塊級元素才有效的,而::after等偽元素默認都是內(nèi)聯(lián)水平,這就是借助偽元素清除浮動影響時需要設(shè)置display屬性值的原因。
先來看兩個相關(guān)的概念:
塊格式化上下文(Block Formatting Context,BFC)是Web頁面的可視化CSS渲染的一部分,是布局過程中生成塊級盒子的區(qū)域,也是浮動元素與其他元素的交互限定區(qū)域。
通俗來講:BFC是一個獨立的布局環(huán)境,可以理解為一個容器,在這個容器中按照一定規(guī)則進行物品擺放,并且不會影響其它環(huán)境中的物品。如果一個元素符合觸發(fā)BFC的條件,則BFC中的元素布局不受外部影響。
創(chuàng)建BFC的條件:
BFC的特點:
BFC的作用:
overflow:hidden
?。.left{
width: 100px;
height: 200px;
background: red;
float: left;
}
.right{
height: 300px;
background: blue;
overflow: hidden;
}
<div class="left"></div>
<div class="right"></div>
左側(cè)設(shè)置 float:left
,右側(cè)設(shè)置 overflow: hidden
。這樣右邊就觸發(fā)了BFC,BFC的區(qū)域不會與浮動元素發(fā)生重疊,所以兩側(cè)就不會發(fā)生重疊,實現(xiàn)了自適應(yīng)兩欄布局。
問題描述:
兩個塊級元素的上外邊距和下外邊距可能會合并(折疊)為一個外邊距,其大小會取其中外邊距值大的那個,這種行為就是外邊距折疊。需要注意的是,浮動的元素和絕對定位這種脫離文檔流的元素的外邊距不會折疊。重疊只會出現(xiàn)在垂直方向。
計算原則:
折疊合并后外邊距的計算原則如下:
解決辦法:
對于折疊的情況,主要有兩種:兄弟之間重疊和父子之間重疊
(1)兄弟之間重疊
display: inline-block
?float
?absolute/fixed
?(2)父子之間重疊
overflow: hidden
?border:1px solid transparent
?display: inline-block
?層疊順序,英文稱作 stacking order,表示元素發(fā)生層疊時有著特定的垂直顯示順序。下面是盒模型的層疊規(guī)則:
對于上圖,由上到下分別是:
(1)背景和邊框:建立當前層疊上下文元素的背景和邊框。
(2)負的z-index:當前層疊上下文中,z-index屬性值為負的元素。
(3)塊級盒:文檔流內(nèi)非行內(nèi)級非定位后代元素。
(4)浮動盒:非定位浮動元素。
(5)行內(nèi)盒:文檔流內(nèi)行內(nèi)級非定位后代元素。
(6)z-index:0:層疊級數(shù)為0的定位元素。
(7)正z-index:z-index屬性值為正的定位元素。
注意: 當定位元素z-index:auto,生成盒在當前層疊上下文中的層級為 0,不會建立新的層疊上下文,除非是根元素。
position有以下屬性值:
屬性值 | 概述 |
---|---|
absolute | 生成絕對定位的元素,相對于static定位以外的一個父元素進行定位。元素的位置通過left、top、right、bottom屬性進行規(guī)定。 |
relative | 生成相對定位的元素,相對于其原來的位置進行定位。元素的位置通過left、top、right、bottom屬性進行規(guī)定。 |
fixed | 生成絕對定位的元素,指定元素相對于屏幕視?(viewport)的位置來指定元素位置。元素的位置在屏幕滾動時不會改變,?如回到頂部的按鈕?般都是?此定位?式。 |
static | 默認值,沒有定位,元素出現(xiàn)在正常的文檔流中,會忽略 top, bottom, left, right 或者 z-index 聲明,塊級元素從上往下縱向排布,?級元素從左向右排列。 |
inherit | 規(guī)定從父元素繼承position屬性的值 |
前面三者的定位方式如下:
relative:元素的定位永遠是相對于元素自身位置的,和其他元素沒關(guān)系,也不會影響其他元素。
fixed:元素的定位是相對于 window (或者 iframe)邊界的,和其他元素沒有關(guān)系。但是它具有破壞性,會導(dǎo)致其他元素位置的變化。
absolute:元素的定位相對于前兩者要復(fù)雜許多。如果為 absolute 設(shè)置了 top、left,瀏覽器會根據(jù)什么去確定它的縱向和橫向的偏移量呢?答案是瀏覽器會遞歸查找該元素的所有父元素,如果找到一個設(shè)置了 position:relative/absolute/fixed
的元素,就以該元素為基準定位,如果沒找到,就以瀏覽器邊界定位。如下兩個圖所示:
(1)首先判斷display屬性是否為none,如果為none,則position和float屬性的值不影響元素最后的表現(xiàn)。
(2)然后判斷position的值是否為absolute或者fixed,如果是,則float屬性失效,并且display的值應(yīng)該被設(shè)置為table或者block,具體轉(zhuǎn)換需要看初始轉(zhuǎn)換值。
(3)如果position的值不為absolute或者fixed,則判斷float屬性的值是否為none,如果不是,則display的值則按上面的規(guī)則轉(zhuǎn)換。注意,如果position的值為relative并且float屬性的值存在,則relative相對于浮動后的最終位置定位。
(4)如果float的值為none,則判斷元素是否為根元素,如果是根元素則display屬性按照上面的規(guī)則轉(zhuǎn)換,如果不是,則保持指定的display屬性值不變。
總的來說,可以把它看作是一個類似優(yōu)先級的機制,"position:absolute"和"position:fixed"優(yōu)先級最高,有它存在的時候,浮動不起作用,'display'的值也需要調(diào)整;其次,元素的'float'特性的值不是"none"的時候或者它是根元素的時候,調(diào)整'display'的值;最后,非根元素,并且非浮動元素,并且非絕對定位的元素,'display'特性值同設(shè)置值。
共同點:
不同點:
sticky 英文字面意思是粘貼,所以可以把它稱之為粘性定位。語法:position: sticky; 基于用戶的滾動位置來定位。
粘性定位的元素是依賴于用戶的滾動,在 position:relative 與 position:fixed 定位之間切換。它的行為就像 position:relative; 而當頁面滾動超出目標區(qū)域時,它的表現(xiàn)就像 position:fixed;,它會固定在目標位置。元素定位表現(xiàn)為在跨越特定閾值前為相對定位,之后為固定定位。這個特定閾值指的是
top, right, bottom 或 left 之一,換言之,指定 top, right, bottom 或 left 四個閾值其中之一,才可使粘性定位生效。否則其行為與相對定位相同。
CSS繪制三角形主要用到的是border屬性,也就是邊框。
平時在給盒子設(shè)置邊框時,往往都設(shè)置很窄,就可能誤以為邊框是由矩形組成的。實際上,border屬性是右三角形組成的,下面看一個例子:
div {
width: 0;
height: 0;
border: 100px solid;
border-color: orange blue red green;
}
將元素的長寬都設(shè)置為0,顯示出來的效果是這樣的:
所以可以根據(jù)border這個特性來繪制三角形:
(1)三角1
div {
width: 0;
height: 0;
border-top: 50px solid red;
border-right: 50px solid transparent;
border-left: 50px solid transparent;
}
(2)三角2
div {
width: 0;
height: 0;
border-bottom: 50px solid red;
border-right: 50px solid transparent;
border-left: 50px solid transparent;
}
(3)三角3
div {
width: 0;
height: 0;
border-left: 50px solid red;
border-top: 50px solid transparent;
border-bottom: 50px solid transparent;
}
(4)三角4
div {
width: 0;
height: 0;
border-right: 50px solid red;
border-top: 50px solid transparent;
border-bottom: 50px solid transparent;
}
(5)三角5
div {
width: 0;
height: 0;
border-top: 100px solid red;
border-right: 100px solid transparent;
}
還有很多,就不一一實現(xiàn)了,總體的原則就是通過上下左右邊框來控制三角形的方向,用邊框的寬度比來控制三角形的角度。
用CSS實現(xiàn)扇形的思路和三角形基本一致,就是多了一個圓角的樣式,實現(xiàn)一個90°的扇形:
div{
border: 100px solid transparent;
width: 0;
heigt: 0;
border-radius: 100px;
border-top-color: red;
}
.square {
width: 10%;
height: 10vw;
background: tomato;
}
.square {
width: 20%;
height: 0;
padding-top: 20%;
background: orange;
}
.square {
width: 30%;
overflow: hidden;
background: yellow;
}
.square::after {
content: '';
display: block;
margin-top: 100%;
}
transform: scale(0.5,0.5);
<meta name="viewport" content="width=device-width, initial-scale=0.5, minimum-scale=0.5, maximum-scale=0.5"/>
這樣就能縮放到原來的0.5倍,如果是1px那么就會變成0.5px。viewport只針對于移動端,只在移動端上才能看到效果
在谷歌下css設(shè)置字體大小為12px及以下時,顯示都是一樣大小,都是默認12px。
解決方法:
1px 問題指的是:在一些 Retina屏幕
的機型上,移動端頁面的 1px 會變得很粗,呈現(xiàn)出不止 1px 的效果。原因很簡單——CSS 中的 1px 并不能和移動設(shè)備上的 1px 劃等號。它們之間的比例關(guān)系有一個專門的屬性來描述:
window.devicePixelRatio = 設(shè)備的物理像素 / CSS像素。
打開 Chrome 瀏覽器,啟動移動端調(diào)試模式,在控制臺去輸出這個 devicePixelRatio
的值。這里選中 iPhone6/7/8 這系列的機型,輸出的結(jié)果就是2:
這就意味著設(shè)置的 1px CSS 像素,在這個設(shè)備上實際會用 2 個物理像素單元來進行渲染,所以實際看到的一定會比 1px 粗一些。
解決1px 問題的三種思路:
思路一:直接寫 0.5px
如果之前 1px 的樣式這樣寫:
border:1px solid #333
可以先在 JS 中拿到 window.devicePixelRatio 的值,然后把這個值通過 JSX 或者模板語法給到 CSS 的 data 里,達到這樣的效果(這里用 JSX 語法做示范):
<div id="container" data-device={{window.devicePixelRatio}}></div>
然后就可以在 CSS 中用屬性選擇器來命中 devicePixelRatio 為某一值的情況,比如說這里嘗試命中 devicePixelRatio 為2的情況:
#container[data-device="2"] {
border:0.5px solid #333
}
直接把 1px 改成 1/devicePixelRatio 后的值,這是目前為止最簡單的一種方法。這種方法的缺陷在于兼容性不行,IOS 系統(tǒng)需要8及以上的版本,安卓系統(tǒng)則直接不兼容。
思路二:偽元素先放大后縮小
這個方法的可行性會更高,兼容性也更好。唯一的缺點是代碼會變多。
思路是先放大、后縮小:在目標元素的后面追加一個 ::after 偽元素,讓這個元素布局為 absolute 之后、整個伸展開鋪在目標元素上,然后把它的寬和高都設(shè)置為目標元素的兩倍,border值設(shè)為 1px。接著借助 CSS 動畫特效中的放縮能力,把整個偽元素縮小為原來的 50%。此時,偽元素的寬高剛好可以和原有的目標元素對齊,而 border 也縮小為了 1px 的二分之一,間接地實現(xiàn)了
0.5px 的效果。
代碼如下:
#container[data-device="2"] {
position: relative;
}
#container[data-device="2"]::after{
position:absolute;
top: 0;
left: 0;
width: 200%;
height: 200%;
content:"";
transform: scale(0.5);
transform-origin: left top;
box-sizing: border-box;
border: 1px solid #333;
}
}
思路三:viewport 縮放來解決
這個思路就是對 meta 標簽里幾個關(guān)鍵屬性下手:
<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
這里針對像素比為2的頁面,把整個頁面縮放為了原來的1/2大小。這樣,本來占用2個物理像素的 1px 樣式,現(xiàn)在占用的就是標準的一個物理像素。根據(jù)像素比的不同,這個縮放比例可以被計算為不同的值,用 js 代碼實現(xiàn)如下:
const scale = 1 / window.devicePixelRatio;
// 這里 metaEl 指的是 meta 標簽對應(yīng)的 Dom
metaEl.setAttribute('content', `width=device-width,user-scalable=no,initial-scale=${scale},maximum-scale=${scale},minimum-scale=${scale}`);
這樣解決了,但這樣做的副作用也很大,整個頁面被縮放了。這時 1px 已經(jīng)被處理成物理像素大小,這樣的大小在手機上顯示邊框很合適。但是,一些原本不需要被縮小的內(nèi)容,比如文字、圖片等,也被無差別縮小掉了。
更多建議: