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