🧑💻 寫在開頭
點贊 + 收藏 === 學會🤣🤣🤣
7 種方案解決移動端1px邊框的問題
造成邊框變粗的原因
css中的1px並不等於移動裝置的1px,這是由不同手機由不同畫素密度,在window物件中有一個devicePixelRatio屬性,他可以反應css中畫素與裝置的畫素比
devicePixelRatio 的官方給的定義為: 裝置物理畫素和裝置獨立畫素的比例,也就是devicePixelRatio = 物理畫素 / 獨立畫素。
解決邊框變粗的6種辦法
總結:
- 根據判斷畫素比大於等於2時,
1、0.5px邊框
if(window.devicePixelRatio && devicePixelRatio>=2){ var testElem = document.createElement('div') testElem.style.border = '.5px solid transparent' document.body.appendChild(testElem) if(testElem.offsetHeight ==1){ document.querySelector('html').classList.add('hairlines') } document.body.removeChild(testElem); } // 指令碼放在內聯,如果裡面執行 需要包裝$(document).ready(function(){})
div{ border: 1px solid #bbb } .hairlines div { border-width: 0.5px; }
2、使用border-image實現
準備一張符合要求的border-image
底部邊框
.border-bottom-1px{ border-width: 0 0 1px 0 ; border-image: url(linenew.png) 0 0 2 0 stretch; -webkit-border-image: url(linenew.png) 0 0 2 0 stretch; }
把border設定在底部,圖片2px高,上面1px顏色透明,下面1px使用規定的border顏色
3、使用background-image實現
和border-image實現類似,需要事先準備好圖片
.backround-image-1px{ background: url(../img/line.png) repeat-x left bottom; -wibkit-background-size:100% 1px; background-size:100% 1px; }
缺點:
- 修改顏色麻煩,需要替換圖片
- 圓角需要特別處理,邊緣會模糊
4、利用多背景漸變實現
與background-image類似,把圖片改成漸變的背景,一半設定顏色,一半設定透明
.background-gradient-1px{ background: line-gradient(180deg, black,black 50%, transparent 50%) top left / 100% 1px no-repeat; line-gradient(90deg, black,black 50%, transparent 50%) top right / 1px 100% no-repeat; line-gradient(0, black,black 50%, transparent 50%) bottom right / 100% 1px no-repeat; line-gradient(-90deg, black,black 50%, transparent 50%) bottom left / 1px 100% no-repeat; } /*或者*/ .background-gradient-1px{ background: -webkit-gradient(linear,left top, left bottom, color-step(.5,transparent), color-step(.5,#c8c7cc), to(#c8c7cc)) left bottom repeat-x; background-size: 100% 1px; }
5、利用box-shadow模擬邊框
css陰影的方式處理
.box-shadow-1px{ box-shadow: inset 0px -1px 1px -1px #c8c7cc }
6、viewport + rem 實現
同時透過設定對應的viewport的rem基準值, 解決了1畫素bug
這種方式比較完美,對老版本的修改不友好
優點:所有場景都能滿足,一套程式碼,可以相容所有佈局
缺點:老專案修改代價過大
// 在devicePixlRatio = 1 時, 輸出viewport <mate name="viewport" content="initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"> // 在devicePixlRatio = 2 時, 輸出viewport <mate name="viewport" content="initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5,user-scalable=no"> // 在devicePixlRatio = 3 時, 輸出viewport <mate name="viewport" content="initial-scale=0.333333,maximum-scale=0.333333,minimum-scale=0.333333,user-scalable=no"> <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no" /> <title>rem+viewport適配</title> <style type="text/css"> * { margin: 0; padding: 0; } #box { width: 8rem; height: 8rem; border: 1px solid #000; } </style> </head> <body> <div id="box"></div> </body> <script type="text/javascript"> //獲取dpr var dpr = window.devicePixelRatio; // 2 console.log(dpr, 'dpr+++'); //比例 // 0.5 var scale = 1 / dpr; var width = document.documentElement.clientWidth; //375 //3.透過dpr讓元素進行縮放,initial-scale=0.5 var metaNode = document.querySelector('meta[name="viewport"]'); metaNode.setAttribute( 'content', 'width=device-width,initial-scale=' + scale + ',user-scalable=no' ); var width = document.documentElement.clientWidth; //750 //4.佈局元素 單位 rem ,反向把縮放比例乘回來 2 var styleN = document.createElement('style'); styleN.innerHTML = 'html{font-size: ' + width / 16 + 'px !important;}'; document.head.appendChild(styleN); </script> </html>
7、使用偽類+transform實現
對於老專案,這種方案比較完美, 原理是把原來的所有邊框去掉,透過偽類崇左border,並且transform的scale縮小一半,原先的單挑border樣式設定
.scale-1px{ position:relative; border:none; } .scale-1px:after{ content: ''; position:absolute; bottom:0; background: #000; width:100%; height:1px; transform:scale(0.5); transform-origin: 0 0; } .scale-1px-top { /* border-bottom: 1px solid rgb(229, 229, 229); */ /* box-shadow: inset 0px -1px 1px -1px #c8c7cc; */ border:none; position:relative; } .scale-1px-top:before{ content: ''; position: absolute; display:block; top: 0; left: 0; width: 200%; height: 1px; border-top: 1px solid #E7E7E7; -webkit-transform: scale(0.5,0.5); transform: scale(0.5,0.5); -webkit-transform-origin: 0 0; transform-origin: 0 0; } .scale-1px-bottom { /* border-bottom: 1px solid rgb(229, 229, 229); */ /* box-shadow: inset 0px -1px 1px -1px #c8c7cc; */ border:none; position:relative; } .scale-1px-bottom:before{ content: ''; position: absolute; display:block; bottom: -1px; left: 0; width: 200%; height: 1px; border-bottom: 1px solid #ccc; -webkit-transform: scale(0.5,0.5); transform: scale(0.5,0.5); -webkit-transform-origin: 0 0; transform-origin: 0 0; } .borderRadius-1px { /* border-bottom: 1px solid rgb(229, 229, 229); */ /* 圓角(偽類和本體類都需要加border-radius) */ border-radius:.16rem; border:none; position:relative; } .borderRadius-1px:after{ /* 圓角(偽類和本體類都需要加border-radius) */ content: ''; position: absolute; top: 0; left: 0; border: 1px solid #d1d1d1; -webkit-box-sizing: border-box; box-sizing: border-box; width: 200%; height: 200%; -webkit-transform: scale(0.5); transform: scale(0.5); -webkit-transform-origin: left top; transform-origin: left top; border-radius:.16rem; }
8 、svg
<svg width=100% height=1 style="position: absolute;bottom: 0;left: 0;"> <line x1="0" y1="0" x2="1000" y2="0" style="stroke:#E5E5E5;stroke-width:1" /> </svg>
如果對您有所幫助,歡迎您點個關注,我會定時更新技術文件,大家一起討論學習,一起進步。