CSS設置1px變粗的原因:
為什么移動端css里面寫了1px, 實際看起來比1px粗. 其實原因很好理解:這兩個“px”的含義是不一樣的. 移動端html的header總會加上一句:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
這句話定義了本頁面的viewport的寬度為設備寬度,初始縮放值和最大縮放值都為1,並禁止了用戶縮放. viewport通俗的講是瀏覽器上可用來顯示頁面的區域, 這個區域是可能比屏幕大的。css中的像素只是一個抽象的單位,在不同的設備或不同的環境中,css中的1px所代表的設備物理像素是不同的。
viewport詳細解釋推薦:移動前端開發之viewport的深入理解
實現0.5px的邊框或線的方法:
方法一: 定位+縮放
利用的是 transform 縮放功能,將 1px 縮放一半,同時利用定位,將偽元素覆蓋整個 div 元素,從而達到偽元素與本身元素的合並效果。
.button {
position: relative;
}
.button::before { content: ""; position: absolute; top: 0; left: 0; min-width: 200%; height: 200%; border: 1px solid $color-black54; transform-origin: 0 0; transform: scale(.5, .5); }
支持的瀏覽器:Firefox: ✅ Safari: ✅ Chrome: ✅
需要注意<input type="button">是沒有:before, :after偽元素的
方法二: box-shadow
利用的是 box-shadow
的擴散半徑可以設置為 0.5px 原理
box-shadow: 0px 0px 0px 0.5px #f00;
支持的瀏覽器: Firefox: ✅ Safari: ❌ Chrome: ✅ Firefox: ✅ Safari: ✅
方法三: 線性漸變 linear-gradient
.box { height: 1px; background: linear-gradient(#f00 50%, transparent 50%);
}
方法四: SVG
.HalfPixelLine{ background: repeat-x top left url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='1' height='1'><rect fill='red' x='0' y='0' width='1' height='0.5'/></svg>"); height: 1px; width: 100%; }
方法五: 直接使用border屬性
border: 0.5px solid #f00;
支持的瀏覽器: Firefox: ✅ Safari: ✅ Chrome: ❌
方法六: flexible.js
這是淘寶移動端采取的方案, github的地址:https://github.com/amfe/lib-flexible. 前面已經說過1px變粗的原因就在於一刀切的設置viewport寬度, 如果能把viewport寬度設置為實際的設備物理寬度, css里的1px不就等於實際1px長了么. flexible.js就是這樣干的.
metaEl = doc.createElement('meta');
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
devicePixelRatio=2時輸出meta如下, 這樣viewport與ideal viewport的比是0.5, 也就與設備物理像素一致
<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
缺點:不適用安卓, flexible內部做了檢測 非iOS機型還是采用傳統的scale=1.0, 原因在於安卓手機不一定有devicePixelRatio屬性, 就算有也不一定能響應scale小於1的viewport縮放設置, 例如我的手機設置了scale=0.33333333, 顯示的結果也與scale=1無異。