摘要:在和一些安卓手機(jī)等的設(shè)備上,需要設(shè)置為,這個(gè)時(shí)候就是倍地畫(huà)了。
編者按:本文由人人網(wǎng)FED發(fā)表于掘金,并已授權(quán)奇舞周刊轉(zhuǎn)載
什么是像素?
像素是屏幕顯示最小的單位,在一個(gè)1080p的屏幕上,它的像素?cái)?shù)量是1920 1080,即橫邊有1920個(gè)像素,而豎邊為1080個(gè)。一個(gè)像素就是一個(gè)單位色塊,是由rgba四個(gè)通道混合而成。對(duì)于一個(gè)1200萬(wàn)像素的相機(jī)鏡頭來(lái)說(shuō),它有1200萬(wàn)個(gè)感光單元,它能輸出的最大圖片分辨率大約為3000 ?4000。
那么像素本身有大小嗎,一個(gè)像素有多大?
有的,如果一個(gè)像素越小,那么在同樣大小的屏幕上,需要的像素點(diǎn)就越多,像素就越密集,如果一英寸有435個(gè)像素,那么它的dpi/ppi就達(dá)到了435。Macbook Pro 15寸的分辨率為2880 x 1800,15寸是指屏幕的對(duì)角線為15寸(具體為15.4),根據(jù)長(zhǎng)寬比換算一下得到橫邊為13寸,所以ppi為2880 / 13 = 220 ppi. 像素越密集即ppi(pixel per inch)越高,那么屏幕看起來(lái)就越細(xì)膩越高清。
在Mac/Windows上可以設(shè)置屏幕顯示的分辨率,Mac默認(rèn)為設(shè)備分辨率的一半,它的dpr = 2,即長(zhǎng)和寬用2個(gè)像素表示1個(gè)像素,所以2880個(gè)物理像素點(diǎn)實(shí)際上只表示1440個(gè)邏輯像素:
那么我們的問(wèn)題來(lái)了,怎么在高清屏上畫(huà)一條0.5px的邊呢?0.5px相當(dāng)于高清屏物理像素的1px。這樣的目的是在高清屏上看起來(lái)會(huì)更細(xì)一點(diǎn),效果會(huì)更好一點(diǎn),例如更細(xì)的分隔線。
大漠在《再談Retina下1px的解決方案》已經(jīng)討論過(guò)這個(gè)問(wèn)題,這里我們?cè)倮硪焕硭悸贰?/p>
理論上px的最小單位是1,但是會(huì)有幾個(gè)特例,高清屏的顯示就是一個(gè)特例。高清屏確實(shí)可以畫(huà)0.5px,對(duì)比效果如下:
如果我們直接設(shè)置0.5px,在不同的瀏覽器會(huì)有不同的表現(xiàn),使用如下代碼:
??? ??? ????0.5px
???? ????1px
????
在PC上的不同瀏覽器上測(cè)試測(cè)試結(jié)果如下所示:
其中Chrome把0.5px四舍五入變成了1px,而firefox/safari能夠畫(huà)出半個(gè)像素的邊,并且Chrome會(huì)把小于0.5px的當(dāng)成0,而Firefox會(huì)把不小于0.55px當(dāng)成1px,Safari是把不小于0.75px當(dāng)成1px,進(jìn)一步在手機(jī)上觀察iOS的Chrome會(huì)畫(huà)出0.5px的邊,而安卓(5.0)原生瀏覽器是不行的。所以直接設(shè)置0.5px不同瀏覽器的差異比較大,并且我們看到不同系統(tǒng)的不同瀏覽器對(duì)小數(shù)點(diǎn)的px有不同的處理。所以如果我們把單位設(shè)置成小數(shù)的px包括寬高等,其實(shí)不太可靠,因?yàn)椴煌瑸g覽器表現(xiàn)不一樣。
第二種能想到的方法是縮放,能否設(shè)置1px,然后scale 0.5呢,我們可以嘗試一下,如下代碼所示:
1px + scaleY(0.5)
效果如下圖所示:
我們發(fā)現(xiàn)Chrome/Safari都變虛了,只有Firefox比較完美看起來(lái)是實(shí)的而且還很細(xì),效果和直接設(shè)置0.5px一樣。所以通過(guò)transform: scale會(huì)導(dǎo)致Chrome變虛了,而粗細(xì)幾乎沒(méi)有變化,所以這個(gè)效果不好。
我們還想到做移動(dòng)端的時(shí)候還使用了rem做縮放,但實(shí)際上rem的縮放最后還是會(huì)轉(zhuǎn)化成px,所以和直接使用0.5px的方案是一樣的。
還有什么辦法呢?還可以用線性漸變linear-gradient,如下代碼所示:
linear-gradient(0deg, #fff, #000)
linear-gradient(0deg, #fff, #000)的意思是:漸變的角度從下往上,從白色#fff漸變到黑色#000,而且是線性的,在高清屏上,1px的邏輯像素代表的物理(設(shè)備)像素有2px,由于是線性漸變,所以第1個(gè)px只能是#fff,而剩下的那個(gè)像素只能是#000,這樣就達(dá)到了畫(huà)一半的目的。邏輯分析很完美,實(shí)際的效果又怎么樣呢,如下圖所示:
我們發(fā)現(xiàn)這種方法在各個(gè)流覽器上面都不完美,效果都是虛的,和完美的0.5px還是有差距。這個(gè)效果和scale 0.5的差不多,都是通過(guò)虛化線,讓人覺(jué)得變細(xì)了。
還有另外一種方法,使用box-shadow,如下代碼所示:
box-shadow: 0 0.5px 0 #000
設(shè)置box-shadow的第二個(gè)參數(shù)為0.5px,表示陰影垂直方向的偏移為0.5px,效果如下:
這個(gè)方法在Chrome和Firefox都非常完美,但是Safari不支持小于1px的boxshadow,所以完全沒(méi)顯示出來(lái)了。不過(guò)至少找到了一種方法能夠讓PC的Chrome顯示0.5px。
還可以使用SVG,利用SVG的1px還是物理像素的1px,不是高清屏的1px。如下代碼所示:
svg
設(shè)置background為一個(gè)svg文件,這個(gè)svg多帶帶拷出來(lái)是這樣的:
使用svg的line元素畫(huà)線,stroke表示描邊顏色,默認(rèn)的寬度stroke-width="1",由于svg的1px是物理像素的px,相當(dāng)于高清屏的0.5px,另外還可以使用svg的rect等元素進(jìn)行繪制。在Chrome和Safari的效果如下:
這個(gè)方案也是很完美,但是在firefox掛了,究其原因是因?yàn)閒irefox的background-image如果是svg的話只支持命名的顏色,如"black"、"red"等,如果把上面代碼的svg里面的#000改成black的話就可以顯示出來(lái),但是這樣就很不靈活了。否則只能把svg轉(zhuǎn)成base64的形式,我們把svg的內(nèi)容轉(zhuǎn)成base64(可以找一些在線的工具),對(duì)比如下:
.hr.svg?{ ????background:?url("data:image/svg+xml;utf-8,"); ????background:?url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMDAlJyBoZWlnaHQ9JzFweCc+PGxpbmUgeDE9JzAnIHkxPScwJyB4Mj0nMTAwJScgeTI9JzAnIHN0cm9rZT0nIzAwMCc+PC9saW5lPjwvc3ZnPg=="); }
這樣在firefox也能完美展示了。
其實(shí)0.5px的需求在移動(dòng)端應(yīng)該會(huì)更常見(jiàn),比較一下以上五種方法在IOS和安卓的表現(xiàn),如下圖所示:
IOS下的Safari和Chrome表現(xiàn)一致,都是以直接設(shè)置0.5px的效果最好,而安卓瀏覽器則是以box-shadow的效果最好(試了5和7),而svg的方案在IOS和安卓的設(shè)備上都能完美支持。讀者可以打開(kāi)這個(gè)網(wǎng)頁(yè),看一下在你的設(shè)備是哪種效果最好。
結(jié)合以上,我們初步得到以下結(jié)論:
使用SVG相對(duì)于box-shadow等方法,還有一個(gè)好處是可以借助svg的元素畫(huà)出任意圖形,如四邊形,圓角等。
最后還有一個(gè)萬(wàn)能的方法,那就是通過(guò)控制viewport,在移端開(kāi)發(fā)里面一般會(huì)把viewport的scale設(shè)置成1:
其中width=device-width表示將viewport視窗的寬度調(diào)整為設(shè)備的寬度,這個(gè)寬度通常是指物理上寬度。默認(rèn)的縮放比例為1,如iphone 6豎屏的寬度為750px,它的dpr=2,用2px表示1px,這樣設(shè)置之后viewport的寬度就變成375px。這時(shí)候0.5px的邊就使用我們上面討論的方法。
但是你可以把scale改成0.5:
這樣的話,viewport的寬度就是原本的750px,所以1個(gè)px還是1px,正常畫(huà)就行,但這樣也意味著UI需要按2倍圖的出,整體面面的單位都會(huì)放大一倍。
在iPhone X和一些安卓手機(jī)等dpr = 3的設(shè)備上,需要設(shè)置scale為0.333333,這個(gè)時(shí)候就是3倍地畫(huà)了。
綜上討論了像素和viewport的一些概念,并介紹和比較了在高清屏上畫(huà)0.5px的幾種方法——可以通過(guò)直接設(shè)置寬高border為0.5px、設(shè)置box-shadow的垂直方向的偏移量為0.5px、借助線性漸變linear-gradient、使用transform: scaleY(0.5)的方法,使用SVG的方法。最后發(fā)現(xiàn)SVG的方法兼容性和效果都是最好的,所以在viewport是1的情況下,可以使用SVG畫(huà)0.5px,而如果viewport的縮放比例不是1的話,那么直接畫(huà)1px即可。
關(guān)于奇舞周刊
《奇舞周刊》是360公司專(zhuān)業(yè)前端團(tuán)隊(duì)「奇舞團(tuán)」運(yùn)營(yíng)的前端技術(shù)社區(qū)。關(guān)注公眾號(hào)后,直接發(fā)送鏈接到后臺(tái)即可給我們投稿。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/115902.html
摘要:在和一些安卓手機(jī)等的設(shè)備上,需要設(shè)置為,這個(gè)時(shí)候就是倍地畫(huà)了。 編者按:本文由人人網(wǎng)FED發(fā)表于掘金,并已授權(quán)奇舞周刊轉(zhuǎn)載 什么是像素? 像素是屏幕顯示最小的單位,在一個(gè)1080p的屏幕上,它的像素?cái)?shù)量是1920 1080,即橫邊有1920個(gè)像素,而豎邊為1080個(gè)。一個(gè)像素就是一個(gè)單位色塊,是由rgba四個(gè)通道混合而成。對(duì)于一個(gè)1200萬(wàn)像素的相機(jī)鏡頭來(lái)說(shuō),它有1200萬(wàn)個(gè)感光單元...
摘要:今天想寫(xiě)的問(wèn)題來(lái)自于網(wǎng)易一面的時(shí)候,面試官問(wèn)我如何在移動(dòng)端的頁(yè)面上畫(huà)一條的線。上面的結(jié)論我在端谷歌瀏覽器的設(shè)備模擬器里證實(shí)了有效,但是安卓和真機(jī)并沒(méi)有試過(guò)。 起因 最近一個(gè)月都在準(zhǔn)備校招,所以沒(méi)什么時(shí)間寫(xiě)博客。今天想寫(xiě)的問(wèn)題來(lái)自于網(wǎng)易一面的時(shí)候,面試官問(wèn)我如何在移動(dòng)端的頁(yè)面上畫(huà)一條1px的線。這個(gè)問(wèn)題我模糊地記得之前看過(guò)相關(guān)文章,但是我清楚地記得當(dāng)時(shí)自己腦子一片空白。是的,一面掛了,但...
摘要:常見(jiàn)優(yōu)化方案模糊問(wèn)題旋轉(zhuǎn)效果離屏自定義圖片尺寸實(shí)踐離屏旋轉(zhuǎn)效果實(shí)踐旋轉(zhuǎn)的雪花更新關(guān)于模糊問(wèn)題前幾天研究的時(shí)候剛好趕上作者發(fā)布新版本,發(fā)現(xiàn)新版本截屏出來(lái)的效果比我對(duì)舊版本處理后畫(huà)布尺寸都設(shè)為倍的效果更好。 canvas常見(jiàn)優(yōu)化方案——模糊問(wèn)題、旋轉(zhuǎn)效果、離屏、自定義圖片尺寸 實(shí)踐demo——canvas離屏、旋轉(zhuǎn)效果實(shí)踐——旋轉(zhuǎn)的雪花 2017-12-18 16:27:35更新關(guān)于模糊問(wèn)...
閱讀 1887·2021-09-27 13:35
閱讀 3434·2019-08-30 14:16
閱讀 2489·2019-08-30 10:52
閱讀 869·2019-08-29 16:35
閱讀 1422·2019-08-29 15:22
閱讀 3648·2019-08-23 18:21
閱讀 3139·2019-08-23 18:00
閱讀 3127·2019-08-23 16:50