最近和設計同學調ui,遇到的是一位對1px有極致追求的同學,像素眼一眼看出我寫的是不是1px,所以讓我好好地研究了一番1px到底怎么寫最方便。
一、為什么出不來1px?
簡而言之:css的1px只是一個抽象的單位,並非實際設備中的1px。
關於retina屏:
我們知道現在iphone大多數型號都用上了retina屏,而retina屏的分辨率相較於普通屏幕增加了一倍,也就是說原來1個像素寬度的區域內可以塞進2個像素了。我們css寫的1px是一個概念像素,在retina屏的實際設備上占了2px的位置。
而對於手機屏幕整體來說,一個標注了750寬的手機(iPhone6)在css中只需要375px就能表示。
二、如何在手機上寫出1px?
網上其實有人列了非常多的方案,有用transform的、有用圖片的、有用canvas的、還有用0.5px的……從操作簡易性來看,用transform的方案是比較簡單的,而且適配也比較容易(0.5px的方案安卓不支持)。
原理:寫一條1px的線,然后transform:scaleY(0.5)或scaleX(0.5),就能夠將retina上顯示的2px縮小為實際屏幕中的1px。
三、幾種1px的樣式實踐方案
1、單線
思路:寫一個height為1px的元素,然后通過transform:scaleY(0.5)來縮放實現
示例:https://jsfiddle.net/xhabhyf9/2/
.single-line{ margin:0 auto; height: 1px; width:200px; background: #000; overflow: hidden; transform: scaleY(0.5); -webkit-transform: scaleY(0.5); }
(此處加的一句overflow: hidden有奇效,能使得1px真正實現,如果不加這句會有部分顏色溢出,手機上看起來會比1px粗。但是我查了半天沒查到是什么原因,還望有高人指點指點,感激不盡。)
2、四邊形&圓角四邊形
思路:假定需求是給width為200px、height為100px的矩形畫1px的描邊。則寫css時,元素寬高增加1倍,然后給元素寫1px的border,再通過transform:scale(0.5)來整體縮放實現。(如果有圓角,圓角的弧度也要放大2倍,即需求是4px,css則寫成8px)
示例:https://jsfiddle.net/xhabhyf9/3/
.rectangle{ height: 200px; width:400px; background: #f0f0f0; border:1px solid #000; border-radius:8px; transform: scale(0.5); -webkit-transform: scale(0.5); }
3、文字容器的描邊
大多數情況下,我們希望文字框的描邊隨着文字的字數而變化,倘若我們直接在2的例子中的子元素(class="rectangle")里添加文字,則無法實現文字按照父級元素的寬度來排列文字。比如這樣:https://jsfiddle.net/xhabhyf9/5/,文字框縮小成了父級元素的50%,無法實現充滿父級元素的效果。
思路:給文字框加一層標簽,給這層標簽元素描邊1px,然后給它的外層元素設置為width:200%並transform:scale(0.5),並且用translate讓外層元素由於縮放scale帶來的位移“歸位”
示例:https://jsfiddle.net/xhabhyf9/7/
.rectangle{ background: #f0f0f0; width:200%; transform: scale(0.5) translate(-50%,-50%); -webkit-transform: scale(0.5) translate(-50%,-50%); } span{ display:inline-block; font-size:24px; border:1px solid #000; border-radius:8px; }